Basic Information

This page allows you to fork a new project from an existing project (写真を撮って自動翻訳するマシーン). The newly forked project will be listed in the IoT Projects page as a new entry. If you want to overwrite the existing project, please edit 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

Unchecking this will make the project public and be listed in the IoT Projects page. The checkbox is unchecked by default since we want you to share the projects! Additionally, you cannot check this unless you are logged in. Once you make the project public, it cannot be undone. (Any edits to the project except for forking will also be public.)

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; }; // 腕に付けるlcd用ケース (http://f3js.org/projects/200 からコピー) var band_width = 25 , band_thickness = 2 , margin = 2; //**************** main box ******************************** 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})
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.