Basic Information

This page allows you to edit the existing project (写真を撮って自動翻訳するマシーン). The edited project will replace the existing entry in the IoT Projects page. If you want to add a new entry based on the project, please fork from it instead.

* Photo URLs that end with any one of .jpg, .jpeg, .png or that are uploaded to the Gyazo web service in the PNG format (e.g.https://gyazo.com/hogehoge) are supported.

* Node.js entry point main: index.js and dependencies to the npm module dependencies: { f3js: (略) } will be automatically added and thus do not need to be in this form.

Private Project

This project is already public and cannot be made private.

Source Code

Provide the source code of a microcontroller or tiny computer in JavaScript. Node.js-based computers are supported. Require f3js package and use its API to design the device enclosure.

'use strict'; var keyFilename = YOUR_KEY_FILE_NAME; var projectId = YOUR_PROJECT_ID; var translateKey = YOUR_TRANSLATE_KEY; var mraa = require("mraa"); var touch_sensor_value = 0, last_t_sensor_value; var jsUpmI2cLcd = require('jsupm_i2clcd'); var lcd = new jsUpmI2cLcd.Jhd1313m1(6, 0x3E, 0x62); var touchSensor = require('jsupm_ttp223'); var touch = new touchSensor.TTP223(0); var working = false; lcd.setColor(0, 0, 255); lcd.setCursor(0, 0); lcd.write('Initializing Goo'); lcd.setCursor(1, 0); lcd.write('gle API... '); var vision = require('gcloud')({ keyFilename: keyFilename, projectId: projectId }).vision(); var googleTranslate = require('google-translate')(translateKey); lcd.setColor(0, 255, 0); lcd.setCursor(0, 0); lcd.write('Ready! '); lcd.setCursor(1, 0); lcd.write(' '); var detect = function () { vision.detectText('result.png', function (err, text) { if (text && text[0]) { var string = text[0].replace(/(?:\r\n|\r|\n)/g, ' ').replace(/[^0-9a-z ]/gi, ''); console.log(string); googleTranslate.translate(string, 'en', function (err, translation) { console.log(translation.translatedText); lcd.setColor(255, 255, 255); lcd.setCursor(0, 0); lcd.write(' '); lcd.setCursor(0, 0); lcd.write(translation.translatedText.slice(0, 16)); lcd.setCursor(1, 0); lcd.write(' '); lcd.setCursor(1, 0); lcd.write(translation.translatedText.slice(16, 31)); working = false; }); } else { lcd.setColor(255, 0, 0); lcd.setCursor(0, 0); lcd.write('Error... '); lcd.setCursor(1, 0); lcd.write(' '); working = false; } }); }; setInterval(function () { // https://github.com/intel-iot-devkit/upm/blob/master/examples/javascript/ttp223.js touch_sensor_value = touch.isPressed(); if (touch_sensor_value === 1 && last_t_sensor_value === 0 && !working) { lcd.setColor(0, 0, 255); lcd.setCursor(0, 0); lcd.write('Taking Picture..'); lcd.setCursor(1, 0); lcd.write('. '); working = true; main(); } last_t_sensor_value = touch_sensor_value; }, 500); var main = function () { takePicture(); }; var takePicture = function () { var v4l2camera = require("v4l2camera"); var cam = new v4l2camera.Camera("/dev/video0"); if (cam.configGet().formatName !== "YUYV") { console.log("YUYV camera required"); process.exit(1); } cam.configSet({width: 352, height: 288}); cam.start(); times(6, cam.capture.bind(cam), function () { var rgb = yuyv2rgb(cam.toYUYV(), cam.width, cam.height); saveAsPng(rgb, cam.width, cam.height, "result.png"); cam.stop(); }); }; var ocr = function () { lcd.setColor(0, 0, 255); lcd.setCursor(0, 0); lcd.write('Executing pictur'); lcd.setCursor(1, 0); lcd.write('e... '); setTimeout(detect, 3000); }; var times = function (n, async, cont) { return async(function rec(r) {return --n === 0 ? cont(r) : async(rec);}); }; var saveAsPng = function (rgb, width, height, filename) { var fs = require("fs"); var pngjs = require("pngjs"); var png = new pngjs.PNG({ width: width, height: height, deflateLevel: 1, deflateStrategy: 1, }); var size = width * height; for (var i = 0; i < size; i++) { png.data[i * 4 + 0] = rgb[i * 3 + 0]; png.data[i * 4 + 1] = rgb[i * 3 + 1]; png.data[i * 4 + 2] = rgb[i * 3 + 2]; png.data[i * 4 + 3] = 255; } png.pack().pipe(fs.createWriteStream(filename)); lcd.setColor(0, 255, 0); lcd.setCursor(0, 0); lcd.write('Picture successf'); lcd.setCursor(1, 0); lcd.write('ully taken! '); ocr(); }; var minmax = function (min, v, max) { return (v < min) ? min : (max < v) ? max : v; }; var yuv2r = function (y, u, v) { return minmax(0, (y + 359 * v) >> 8, 255); }; var yuv2g = function (y, u, v) { return minmax(0, (y + 88 * v - 183 * u) >> 8, 255); }; var yuv2b = function (y, u, v) { return minmax(0, (y + 454 * u) >> 8, 255); }; var yuyv2rgb = function (yuyv, width, height) { var rgb = new Array(width * height * 3); for (var i = 0; i < height; i++) { for (var j = 0; j < width; j += 2) { var index = i * width + j; var y0 = yuyv[index * 2 + 0] << 8; var u = yuyv[index * 2 + 1] - 128; var y1 = yuyv[index * 2 + 2] << 8; var v = yuyv[index * 2 + 3] - 128; rgb[index * 3 + 0] = yuv2r(y0, u, v); rgb[index * 3 + 1] = yuv2g(y0, u, v); rgb[index * 3 + 2] = yuv2b(y0, u, v); rgb[index * 3 + 3] = yuv2r(y1, u, v); rgb[index * 3 + 4] = yuv2g(y1, u, v); rgb[index * 3 + 5] = yuv2b(y1, u, v); } } return rgb; }; // ---------------------------------------------------------------- // グローバルな設定 var band_width = 25 , band_thickness = 2 , margin = 2; // ---------------------------------------------------------------- // 腕に付けるlcd用ケース (http://f3js.org/projects/200 からコピー) var iw = 90 , ih = 52 , id = 10 + band_thickness , dw = 7 //ギザギザの幅 , dh = 2 // ギザギザの深さ , w = iw + dh*2 + margin*2 // + dh*2 で板厚を考慮 , h = ih + dh*2 + margin*2 , d = id + dh*2 + margin*2 , f3js = require('f3js') , c = f3js.createContainer() , p = c.drawJointRectangle(0, 0, w, h, dw, dh); // 板の左上から1cm余白あける c.x = 10; c.y = 10; // 基板の脇に立つ4枚 var planes = p.extrude(d); planes[0].x = w; planes[0].y = 0; planes[1].x = w; planes[1].y = d * 2; planes[2].x = w; planes[2].y = d; planes[3].x = w; planes[3].y = d * 3; for (var i = 0; i < planes.length - 1; i ++) c.add(planes[i]); //信号ケーブルの穴(前) var c2 = c.cc(); c2.x = planes[1].x ; c2.y = planes[1].y; c2.rc( dh + margin + 3, dh+margin, 10, 8); //バンド用の穴 var c_band0 = c.cc(); c_band0.x = planes[0].x ; c_band0.y = planes[0].y; c_band0.rc(w / 10 + dh , dh + margin, band_width, band_thickness); c_band0.rc( w * 9 / 10 - dh -band_width , dh + margin, band_width, band_thickness); var c_band2 = c.cc(); c_band2.x = planes[2].x ; c_band2.y = planes[2].y; c_band2.rc(w / 10 + dh , dh + margin, band_width, band_thickness); c_band2.rc( w * 9 / 10 - dh - band_width , dh + margin, band_width, band_thickness); c.rc(dh +37 , 1.5*h -7.5/2 -dh, 17.5, 3); c.rc(dh +37 ,1.5*h +7.5/2-dh, 17.5, 3); // 基板の上にかぶさる1枚 var c3 = c.cc(); c3.y = h; c3.add(planes[4]); //touch c2.rc( 25 + dh ,8 +dh + margin, 15, 2); c2.drawCircle(20 + dh + margin,dh + margin+1.5, 1.6); c2.drawCircle(40 + dh + margin,dh + margin+1.5, 1.6); //部品 c.add(lcd, { x: 50, y: 30 }); //c.add(touch, { x: c.x + w + dh + margin, y: 30}) // ---------------------------------------------------------------- // main box (http://f3js.org/projects/199 からコピー) f3js.addPage(); var iw = 122 // 幅[mm][122,200] , ih = 72 // 高さ[mm][72, 200] , id = 40 + band_thickness// 奥行[mm][50, 200] , margin = 2 , dw = 7 //ギザギザの幅 , dh = 2 // ギザギザの深さ , w = iw + dh*2 + margin*2 // + dh*2 で板厚を考慮 , h = ih + dh*2 + margin*2 , d = id + dh*2 , f3js = require('f3js') , c = f3js.createContainer() , p = c.drawJointRectangle(0, 0, w, h, dw, dh); // 板の左上から1cm余白あける c.x = 10; c.y = 10; // 基板を固定する穴6つ c.drawCircle(105 + dh + margin, 12 + dh, 1.6); c.drawCircle(105 + dh + margin, h - dh - 12, 1.6); c.drawCircle(55 + dh + margin, dh + 17, 1.6); c.drawCircle(55 + dh + margin, h - dh - 28, 1.6); c.drawCircle(6 + dh + margin, dh + 6, 1.6); c.drawCircle(6 + dh + margin, h - dh - 13, 1.6); //circle.x = iw - 65.995 + dh; //circle.y = 45.683 + dh; //circle.r = 1.6; // 基板の脇に立つ4枚 var planes = p.extrude(d); planes[0].x = w; planes[0].y = 0; planes[1].x = w; planes[1].y = d * 2; planes[2].x = w; planes[2].y = d; planes[3].x = w; planes[3].y = d * 3; for (var i = 0; i < planes.length - 1; i ++) c.add(planes[i]); // USBケーブルと電源ケーブルを通す穴 var c2 = c.cc(); //createContainer c2.x = planes[1].x; c2.y = planes[1].y; c2.rc(3 + dh + margin, dh + margin + band_thickness, 65, 17); //信号ケーブルの穴(前後) var c2 = c.cc(); c2.x = planes[1].x ; c2.y = planes[1].y; c2.rc( h / 2.0 - 5.0 / 2, 25 + dh + margin + band_thickness, 10, 5); var c3 = c.cc(); //createContainer c3.x = planes[3].x ; c3.y = planes[3].y; c3.rc( h / 2.0 - 5.0 / 2, 25 + dh + margin + band_thickness, 10, 5); //バンド用の穴 var c_band0 = c.cc(); c_band0.x = planes[0].x ; c_band0.y = planes[0].y; c_band0.rc(w / 10 + dh , dh + margin, band_width, band_thickness); c_band0.rc( w * 9 / 10 - dh -band_width , dh + margin, band_width, band_thickness); var c_band2 = c.cc(); c_band2.x = planes[2].x ; c_band2.y = planes[2].y; c_band2.rc(w / 10 + dh , dh + margin, band_width, band_thickness); c_band2.rc( w * 9 / 10 - dh -band_width , dh + margin, band_width, band_thickness); // 基板の上にかぶさる1枚 var c3 = c.cc(); c3.y = h; c3.add(planes[4]);
Customization

This content does not allow any customization.

Layout view options
Adding comments to variable declarations in the source code populate various GUI widgets in the "Customization" section depending on their types.

Design Alternatives

Modules

No modules are required for this project.

Layout
Program

Login first to use this feature.