I am trying to use node.js on a Raspberry Pi to interface a serial device. I want to send data from the device to a webpage, send control data from the webpage to the device and log and store data on the Pi. When I run this:
var fs = require('fs');
var http = require('http');
var server = http.createServer(function(req, res){
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/engComp.html'));
}).listen(8080, function(){console.log('Listening at: http://localhost:8080');});
var io = require('socket.io').listen(server);
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyAMA0", {
baudrate: 9600,parser: serialport.parsers.readline('\r')});
sp.open(function (){console.log('serial port open');
io.on('connection', function (socket){
console.log('socket open');
socket.on('data',function(recData){ //data recieved from socket
console.log('http rec data = '+recData);
sp.write(recData, function(err, results){
console.log('serial port send data = '+recData);
});
});
sp.on('data', function(sdata){ //data recieved from serial port
console.log('serial port rec sdata = ' + sdata);
});
socket.on('disconnect', function (){
console.log('socket disconnect');
// sp.close(function(){
// console.log('serial port closed');
// });
});
});
});
and reload the page say 3 times I get 3 outputs for each serial data read.
If I put back (un-rem) the sp.close() it works until I reload as expected (the port is closed but never reopened).
If I put the sp.open() in the io.on(connection) callback and serial data comes in while the page is reloading (after sp.close() but before sp.open() it crashes with:
events.js:72
throw er; // Unhandled 'error' event
^
Error: EBADF, read
I would prefer not to close the port durring a reload as this would interfere with loging to the Pi.
I am using node v0.10.26 but same thing happens with v0.8.17
Operating on the assumption that you intend for there to only be one serial connection open and one website connection open, try something like this.
var fs = require('fs');
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/engComp.html'));
});
var io = require('socket.io').listen(server);
var SerialPort = require('serialport').SerialPort;
var sp = new SerialPort('/dev/ttyAMA0', {
baudrate: 9600,
parser: serialport.parsers.readline('\r')
});
io.on('connection', function (socket) {
console.log('socket open');
socket.on('data', function(recData) {
console.log('http rec data =', recData);
sp.write(recData, function(err, results){
console.log('serial port send data =', recData);
});
});
});
sp.open(function () {
console.log('serial port open');
server.listen(8080, function(){
console.log('Listening at: http://localhost:8080');
})
sp.on('data', function(sdata) {
io.emit('sdata', sdata);
console.log('serial port rec sdata = ', sdata);
});
});
Now there is only one serial port connection opened and it doesn't open / close between requests. Furthermore, the website only starts listening for connections after the serial port has been opened and is ready for data.