diff --git a/app/cfg.json b/app/cfg.json new file mode 100644 index 0000000..e784606 --- /dev/null +++ b/app/cfg.json @@ -0,0 +1,35 @@ +{ + "version" : "0.0.7", + "ext_port" : 1111, + "arduino" : { + "baud" : 57600, + "board" : "uno", + "serialDelay" : 20, + "sequenceDelay" : 100, + "cam" : { + "time" : 750, + "delay" : 50, + "momentary" : 300 + }, + "proj" : { + "time" : 1300, + "delay" : 50, + "momentary" : 300 + }, + "black" : { + "before" : 250, + "after" : 250 + }, + "cmd" : { + "debug" : "d", + "connect": "i", + "camera" : "c", + "projector" : "p", + "black" : "b", + "cam_forward" : "e", + "cam_backward" : "f", + "proj_forward" : "g", + "proj_backward" : "h" + } + } +} \ No newline at end of file diff --git a/app/index.html b/app/index.html index 2906663..7d17278 100644 --- a/app/index.html +++ b/app/index.html @@ -9,5 +9,7 @@ We are using node , Chromium , and Electron . + + \ No newline at end of file diff --git a/app/js/index.js b/app/js/index.js new file mode 100644 index 0000000..026fdf6 --- /dev/null +++ b/app/js/index.js @@ -0,0 +1,10 @@ +var ipcRenderer = require('electron').ipcRenderer, + light = {}; +//console.log(ipcRenderer.sendSync('light', { 'fuck' : true }) ); + + +light.set = function (color) { + 'use strict'; + console.log('color: ' + color.join(',')); + ipcRenderer.sendSync('light', color); +}; diff --git a/app/main.js b/app/main.js index 0f14007..c0893b1 100644 --- a/app/main.js +++ b/app/main.js @@ -1,51 +1,152 @@ 'use strict'; +const electron = require('electron'), + fs = require('fs'), + Menu = require('menu'), + ipcMain = require('electron').ipcMain, + app = electron.app, + BrowserWindow = electron.BrowserWindow, + uuid = require('node-uuid'), + serialport = require('serialport'), + SerialPort = serialport.SerialPort, + mcopy = {}; -const electron = require('electron'); -// Module to control application life. -const app = electron.app; -// Module to create native browser window. -const BrowserWindow = electron.BrowserWindow; - -// Keep a global reference of the window object, if you don't, the window will -// be closed automatically when the JavaScript object is garbage collected. let mainWindow; -function createWindow () { - // Create the browser window. - mainWindow = new BrowserWindow({width: 800, height: 600}); +var init = function () { + mcopy.cfg = JSON.parse(fs.readFileSync('./cfg.json', 'utf8')); + createWindow(); +}; - // and load the index.html of the app. - mainWindow.loadURL('file://' + __dirname + '/index.html'); +var createMenu = function () { - // Open the DevTools. - mainWindow.webContents.openDevTools(); +}; - // Emitted when the window is closed. - mainWindow.on('closed', function() { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - mainWindow = null; - }); +var createWindow = function () { + mainWindow = new BrowserWindow({width: 800, height: 600}); + mainWindow.loadURL('file://' + __dirname + '/index.html'); + mainWindow.webContents.openDevTools(); + mainWindow.on('closed', function() { + mainWindow = null; + }); } -// This method will be called when Electron has finished -// initialization and is ready to create browser windows. -app.on('ready', createWindow); +app.on('ready', init); -// Quit when all windows are closed. app.on('window-all-closed', function () { - // On OS X it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== 'darwin') { - app.quit(); - } + if (process.platform !== 'darwin') { + app.quit(); + } }); app.on('activate', function () { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (mainWindow === null) { - createWindow(); - } -}); \ No newline at end of file + if (mainWindow === null) { + createWindow(); + } +}); + +ipcMain.on('light', function(event, arg) { + // + event.returnValue = true; +}); + +/****** + Arduino handlers +*******/ +mcopy.arduino = { + path : '', + known: [ + '/dev/tty.usbmodem1a161', + '/dev/tty.usbserial-A800f8dk', + '/dev/tty.usbserial-A900cebm', + '/dev/tty.usbmodem1a131', + '/dev/tty.usbserial-a900f6de', + '/dev/tty.usbmodem1a141' + ], + serial : {}, + baud : 57600, + queue : {}, + timer : 0, + lock : false +}; +mcopy.arduino.init = function (callback) { + mcopy.log('Searching for devices...'); + var cmd = 'ls /dev/tty.*'; + exec(cmd, function (e, std) { + var devices = std.split('\n'), + matches = []; + devices.pop(); + for (var i = 0; i < devices.length; i++) { + if (devices[i].indexOf('usbserial') !== -1 + ||devices[i].indexOf('usbmodem') !== -1){ + matches.push(devices[i]); + } + } + if (matches.length === 0) { + mcopy.log('No devices found.'); + mcopy.gui.spinner(false); + mcopy.gui.overlay(true); + if (callback) { callback(false); } + } else if (matches.length > 0) { + mcopy.log('Found ' + matches[0]); + mcopy.arduino.path = matches[0]; + //once connected to the arduino + //start user interface + if (callback) { callback(true); } + } + }); +}; +//commands which respond to a sent char +mcopy.arduino.send = function (cmd, res) { + if (!mcopy.arduino.lock) { + mcopy.arduino.lock = true; + mcopy.arduino.queue[cmd] = res; + setTimeout(function () { + mcopy.arduino.serial.write(cmd, function (err, results) { + if (err) { mcopy.log(err, 0); } + mcopy.arduino.lock = false; + mcopy.arduino.timer = new Date().getTime(); + }); + }, mcopy.cfg.arduino.serialDelay); + } +}; +//with same over serial when done +mcopy.arduino.end = function (data) { + var end = new Date().getTime(), + ms = end - mcopy.arduino.timer; + if (mcopy.arduino.queue[data] !== undefined) { + mcopy.arduino.lock = false; + mcopy.log('Command ' + data + ' took ' + ms + 'ms'); + mcopy.arduino.queue[data](ms); + + mcopy.arduino.queue = {}; + } else { + //console.log('Received stray "' + data + '" from ' + mcopy.arduino.path); //silent to user + } +}; +mcopy.arduino.connect = function (callback) { + mcopy.log('Connecting to ' + mcopy.arduino.path + '...'); + mcopy.state.arduino = mcopy.arduino.path; + mcopy.arduino.serial = new SerialPort(mcopy.arduino.path, { + baudrate: mcopy.cfg.arduino.baud, + parser: sp.parsers.readline("\n") + }); + mcopy.arduino.serial.open(function (error) { + if ( error ) { + return mcopy.log('failed to open: '+ error, 0); + } else { + mcopy.log('Opened connection with ' + mcopy.arduino.path); + mcopy.arduino.serial.on('data', function (data) { + data = data.replace('\r', ''); + mcopy.arduino.end(data); + }); + setTimeout(function () { + mcopy.log('Verifying firmware...'); + mcopy.arduino.send(mcopy.cfg.arduino.cmd.connect, function () { + mcopy.log('Firmware verified'); + mcopy.log('Optical printer ready!'); + if (callback) { callback(); } + }); + }, 2000); + } + }); +}; diff --git a/app/package.json b/app/package.json index 70a0049..a3539aa 100644 --- a/app/package.json +++ b/app/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "node-notifier": "^4.5.0", - "node-uuid": "^1.4.7" + "node-uuid": "^1.4.7", + "serialport": "^2.1.0" } }