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.