Beaglebone how-to: pagina web gestito con un pulsante e Node.js
Questo articolo a cura di Giulio Roggero descrive come intercettare l’interrupt GPIO di una scheda Beaglebone e aggiornare, via Web Sockets, una pagina web usando Node.js.
Breadboard
Usando una Breadboard è possibile creare un piccolo circuito con un bottone che collegato alla Beaglebone provoca un interrupt.
Di seguito trovate le immagini della Breadboard e e della sua mappa.
Beaglebone
Per quanto riguarda Beaglebone, ecco le immagini della scheda e della lista di pin.
Beaglebone nell’esperimento
Nel suo esperimento Giulio ha:
- configurato il PIN P8_3 – GPIO1_6 come INPUT;
- configurato il PIN P8_15 – GPIO1_15 come OUTPUT;
- connesso il bottone S1 che, quando premuto, interrompe la corrente tra P8_3 e P8_15.
Di seguito la foto del circuito (incompleto, manca una resistenza da 1K al led).
Codice Node.js per la gestione del pulsante
Ogni volta che il bottone S1 è premuto la corrente scende, il led si spegne e il pin P8_15 riceve un segnale.
Per mandare l’informazione alla pagina web è necessario scrivere qualche riga di codice in Node.js.
Aprire Cloud9 all’indirizzo http://beaglebone.local:3000
e aggiungere il file button.js con il seguente codice:
var app = require('http').createServer(handler); var io = require('socket.io').listen(app); var fs = require('fs'); var url = require('url'); var path = require('path'); io.set('log level', 1); // runs only on beaglebone! var bb = require('bonescript'); var inputPin = bone.P8_15; var ledPin = bone.P8_3; app.listen(2509); io.sockets.on('connection', function(socket) { attachInterrupt(inputPin, CHANGE, function(pin, value) { socket.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); socket.broadcast.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); }); }); setup = function() { pinMode(inputPin, INPUT); // turn on the led pinMode(ledPin, OUTPUT); digitalWrite(ledPin, HIGH); attachInterrupt(inputPin, CHANGE, function(pin, value) { console.log(pin.key + ' changed to ' + ((value == HIGH) ? 'HIGH' : 'LOW')); }); }; function handler(req, res) { var uri = url.parse(req.url).pathname; var subdir = path.join(process.cwd(), 'button'); if (uri == '/') { loadFile('index.html', subdir, res, "text/html"); } else { if (uri.match(/\.js$/i)) { loadFile(uri, subdir, res, "application/javascript"); } else if (uri.match(/\.css$/i)) { loadFile(uri, subdir, res, "text/css"); } else if (uri.match(/\.htm(.)$/i)) { loadFile(uri, subdir, res, "text/html"); } else if (uri.match(/\.(jpg|png|ico|gif)$/i)) { loadFile(uri, subdir, res, "binary"); } else { loadFile(uri, subdir, res, "text/plain"); } } }; function loadFile(uri, subdir, res, type) { var filename = path.join(subdir, uri); path.exists(filename, function(exists) { if (!exists) { res.writeHead(404, { "Content-Type": "text/plain" }); res.write("Error 404: '" + uri + "' Not Found\n"); res.end(); }else if (type == "binary") { fs.readFile( filename, "binary", function(err, file) { if (err) { res.writeHead(500, { "Content-Type": "text/plain" }); res.write(err + "\n"); res.end(); return; } res.writeHead(200); res.write(file, "binary"); res.end(); }); } else { fs.readFile( filename, encoding = 'utf8', function(err, file) { if (err) { res.writeHead(500, { "Content-Type": "text/plain" }); res.write(err + "\n"); res.end(); return; } res.writeHead(200, { "Content-Type": type }); res.write("" + file); res.end(); }); } }); }; bb.run(); console.log('Server running at http://beaglebone.local:2509/');
Integrazione del pulsante in una pagina HTML
Creare una directory che si chiama button e aggiungere il seguente codice per il file index.html:
<script src = "/socket.io/socket.io.js"> </script> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"> </script> <script var socket = io.connect(); socket.on('button_event', function (data) { console.log(data); $("body").css("background-color", data); });> </script> <h1>Press the button, the page will become red!></h1>
Press the button, the page will become red!
La “magia” avviene grazie al seguente pezzo di codice:
attachInterrupt(inputPin, CHANGE, function(pin, value) { socket.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); socket.broadcast.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); });
Se siete curiosi, date un’occhiata al video dimostrativo di questo esperimento.