This article describes how to get the interrupt of a beaglebone GPIO and update via web socket a web page using Node.js.
You can build your button or use the BreadBoard – http://beagleboardtoys.com/wiki/index.php?title=BeagleBone_Breadboard buttons.
Follow the photos of Breadboard
… and Beaglebone.
(from http://elinux.org/BeagleBone)
In this experiment I:
- setup a pin in INPUT mode (in my example P8_3 – GPIO1_6)
- setup a pin in OUTPUT mode (P8_15 – GPIO1_15)
- connect the button S1 in order to interrupt the current between P8_3 and P8_15 when the button is pressed
Here a photo of the cabled board (in the next days I’ll update the post with better images and a video). A 1k resistor is missing in led connection….
Each time you click button S1 the current go down, the led is turned off and pin P8_15 receive a signal.
To send this information to a web page let’s write some line of code in Node.js 🙂
Open Cloud9 on http://beaglebone.local:3000 and add button.js file
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/');
than create a directory named button and add here the index.html
<html> <head> <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> </head> <body> <h1>Press the button, the page will become red!</h1> </body> </html>
The “magic” is done by
attachInterrupt(inputPin, CHANGE, function(pin, value) { socket.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); socket.broadcast.emit('button_event', ((value == HIGH) ? 'white' : 'red') ); });
This function, exposed by bone library, will alert you each time an I/O changes. The implementation behind is done with a poller, I’m looking for an implementation based on kernel interrupts.
Is it possible for you to post this setup with the wires connected into the GPIO pins on the BBB instead of into cape? I am having trouble replicating this with a BeagleBone Black, breadboard, and button. Thanks!