Now we’re cookin’ …
I’ve implemented the following with a new “compile” module in HouseMon – based on Arduino.mk, which is also available for the Raspberry Pi via Debian apt:
In other words, this allows uploading the source code of an Arduino sketch through a web browser, manage these uploaded files from the browser, and compile + upload the sketch to a server-side JeeNode / Arduino. All interaction is browser based…
Only proof of concept, but it opens up some fascinating options. Here’s an example of use:
(note that both avr-gcc + avrdude output and the exit status show up in the browser!)
The processing flow is fairly complex, given the number of different tasks involved, yet the way Node’s asynchronous system calls, SocketStream’s client-server connectivity, and Angular’s two-way webpage bindings work together is absolutely mind-blowing, IMO.
Here’s the main code, running on the server as briqs/jcw-compile.coffee:
exports.info = name: 'jcw-compile' description: 'Compile for embedded systems' menus: [ title: 'Compile' controller: 'CompileCtrl' ] state = require '../server/state' fs = require 'fs' child_process = require 'child_process' ss = require 'socketstream' # TODO hardcoded paths for now SKETCHDIR = switch process.platform when 'darwin' then '/Users/jcw/Tools/sketch' when 'linux' then '/home/pi/sketchbook/sketch' # callable from client as: rpc.exec 'host.api', 'compile', path ss.api.add 'compile', (path, cb) -> # TODO totally unsafe, will accept any path as input file wr = fs.createWriteStream "#{SKETCHDIR}/sketch.ino" fs.createReadStream(path).pipe wr wr.on 'close', -> make = child_process.spawn 'make', ['upload'], cwd: SKETCHDIR make.stdout.on 'data', (data) -> ss.api.publish.all 'ss-output', 'stdout', "#{data}" make.stderr.on 'data', (data) -> ss.api.publish.all 'ss-output', 'stderr', "#{data}" make.on 'exit', (code) -> cb? null, code # triggered when bodyParser middleware finishes processing a file upload state.on 'upload', (url, files) -> for file, info of files state.store 'uploads', key: info.path file: file name: info.name size: info.size date: Date.parse(info.lastModifiedDate) # triggered when the uploads collection changes, used to clean up files state.on 'store.uploads', (obj, oldObj) -> unless obj.key # only act on deletions fs.unlink oldObj.key
The client-side code needed to implement all this is even shorter: see the controller code and the page definition on GitHub.
There’s no error handling in here yet, so evidently this code is not ready for prime time.
PS – Verified to also work on the Raspberry Pi – yippie!
I just stumbled on something similar: http://codebender.cc/
Thx, but note that this is in the cloud, whereas the post is about running on a local machine / RPi.
Perhaps you have seen http://ace.ajax.org ? Its great for editing those simple sketches. Easy to embed into your node app frontend.
Hey, didn’t know about that one. There’s also CodeMirror – and yes, that’s definitely one of the paths we could take it.
Totally unrelated question: I like your hand drawn diagrams, the pen strokes seems soft and a joy to write with. Which pens do you use?
Heh – an iPad with the Bamboo Paper app and this (mostly because it has a fine tip). The fact that I can zoom in and undo has won me over…
Your enormous productivity and enthusiasm is unbelievable! Helps to keep me connected to this stuff, although I’m not actively participating (for now).
Thx, Alwik. You know me: always excited by new adventures! :)
Having a full-featured linux box attached to the AVR opens up all sorts of options. I like doing all my development in Visual Studio because sometimes my projects can be quite large. I’ve used a a web browser to upload code and flash an attached AVR over SPI, but even easier is using SSH to just execute avrdude remotely: plink bmayland@rpi avrdude -p m328p -c arduino -P /dev/ttyUSB1 -V -D -Uflash:w:-:i < “%1”
I never thought to have it compile on the Pi, that’s sweet for small sketches!