First off, I'm new to both node.js and the concept of async functions and would greatly appreciate any help I can get here.
I've been trying to write a script using the node.js serialport module to scan the ports on my Windows machine and do simple stuff once an Arduino Micro is connected to a port. The below works fine if the Arduino is already connected, but I can't work out how to extend it so that it will wait, indefinitely, until the Micro is plugged in. It just terminates if nothing is found.
const serialPort = require('serialport');
var portName;
serialPort.list().then(function(ports){
ports.forEach(function(portInfo){
if (portInfo.vendorId == 2341 && portInfo.productId == 8037) {
portName = portInfo.path;
var myPort = new serialPort(portName);
myPort.on('open' , function() {
showPortOpen();
myPort.write('RL'); // command to initiate functions in Arduino code
});
myPort.on('data' , readSerialData); // echo data from Arduino
myPort.on('close', showPortClose);
}
})
});
function readSerialData(data) {
console.log(data);
}
function showPortOpen() {
console.log(portName,'opened');
}
function showPortClose() {
console.log(portName,'closed');
}
Problem solved in double-quick time. Thank you :-)
Not sure if it's the cleanest approach but by re-calling the setInterval function when the port closes, I have a script that waits and finds the Arduino once it's plugged into the USB and, if subsequently unplugged, will find it again once it's plugged in again. Just what I want!
const serialPort = require('serialport');
var portName;
loop(); // start searching for Arduino on a port
function loop() {
loopId = setInterval(function() {
serialPort.list().then(function(ports){
ports.forEach(function(portInfo){
if (portInfo.vendorId == 2341 && portInfo.productId == 8037) {
portName = portInfo.path;
var myPort = new serialPort(portName);
myPort.on('open' , function() {
showPortOpen();
myPort.write('RL'); // command to initiate Arduino functions
});
myPort.on('data' , readSerialData); // echo data from Arduino
myPort.on('close', showPortClose);
}
})
})
}, 1000)
};
function readSerialData(data) {
console.log(data);
}
function showPortOpen() {
console.log(portName,'opened');
clearInterval(loopId); // stop looping once Arduino found on port
}
function showPortClose() {
console.log(portName,'closed');
loop(); // start over when Arduino port is closed
}
Related
This is the code I have in node js to read from the serial data port of the arduino.
var SerialPort = require('serialport');
var io = require('socket.io').listen(3000);
var serialPort = new SerialPort("COM4", {
baudRate: 9600,
parser: new SerialPort.parsers.Readline("\n")
});
io.sockets.on('connection', function(socket){
socket.on('message', function(msg){
console.log(msg);
});
socket.on('disconnected', function(){
console.log('disconnected');
});
});
var clearData = "";
var readData = "";
serialPort.on('open',function(){
console.log('open');
serialPort.on('data', function(data){
console.log(data);
readData += data.toString();
io.sockets.emit('message',data);
});
});
This is the code that I have in Arduino, it's just a short example.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Hello");
delay(2000);
}
However, in the console of node js the following is shown when printing the data:
How can I get the data correctly in one line?
To have something like this:
Hello
Hello
Hello
I cannot test this end to end (no arduino anywhere near), but since serialport seems to implement a Readable stream, I'd try using scramjet like this:
const {StringStream} = require('scramjet');
serialport.on('open', () => console.log('open');
serialport.pipe(new StringStream) // pipe the stream to scramjet StringStream
.lines('\n') // split per line
.each( // send message per every line
data => io.sockets.emit('message',data)
);
Scramjet would sort the readline issue for you.
I tested this code with the serial port device that uses RS-232 protocol. Its advantage is that you don't need install the third package from npm.
var recVal = '';
mySerial.on('data', function(data) {
if(data.indexOf('\n') != -1) {
io.emit('serial:data', {
value: recVal
});
console.log("Data: ", recVal.toString());
recVal = '';
} else {
recVal = recVal.concat(data);
}
});
I'm totally new to the whole nodeJS asynchronous-y callback-y programming so I need more like a guidance to understanding what I'm even doing. With that said, I have two files main.js and server.js
My main file looks like this:
var server=require('./server.js');
server();
function WhenUserClicksButton(){
server();
}
and my server file looks like this:
var net = require('net');
function server(){
net.createServer(function (socket) {
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
//handle data from client
});
}).listen(33333);
}
First call of server(); starts the TCP server. Then function WhenUserClicksButton is called when user clicks button (duhh) in a GUI. But it attempts to start the server again so I get
Error: listen EADDRINUSE :::33333
I got why this is happening but I can't think of a solution for it. What I really need is:
Start the server and listen on 33333
When nothing is happening server and client just exchanges SYN and ACK characters every few seconds (I already have this part done, I just removed it from this example for clarity because it's not really topic of this question)
When user click button change socket.write('\x16'); to socket.write('something');
Then wait for server and client to exchange data and after everything is done return results back to main.js
As I said, I'm new to this and I believe my problem lies in not understanding fully of what I'm doing. Any help and explanations are welcome!
I think you're very near where you need to be. I would do something like this:
server.js
var net = require('net');
var netServer = null;
var netSocket = null;
function sendData(data) {
if (netServer && netSocket) {
console.log('Send data: sending: ', data);
netSocket.write(data);
}
}
function startServer(){
netServer = net.createServer(function (socket) {
netSocket = socket;
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
console.log('Server: data from client: ', data);
if (data.length === 1 && data[0] === 0x16) {
// log and ignore SYN chars..
console.log('SYN received from client');
} else if (newDataCallback) {
newDataCallback(data);
};
});
});
console.log('Server listening on 33333..');
netServer.listen(33333);
}
var newDataCallback = null;
function setNewDataCallback(callback) {
newDataCallback = callback;
}
module.exports = {
sendData: sendData,
startServer: startServer,
setNewDataCallback: setNewDataCallback
};
main.js
var server = require('./server');
function newDataCallback(data) {
console.log('newDataCallback: New data from server: ', data);
}
server.setNewDataCallback(newDataCallback);
server.startServer();
function wheneverUserClicksButton() {
server.sendData('something');
}
testClient.js
var clientSocket = net.createConnection(33333, "127.0.0.1");
clientSocket.on('data', (someData) => {
console.log('Data received', someData);
});
clientSocket.on('connect', () => {
console.log('Client Socket connected ');
clientSocket.write('Hello from client');
});
I know it may sounds weird and Im really dont know whats going on here.
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM1", {
baudrate: 9600,
parser: serialport.parsers.readline("\n")
});
sp.on('open', function ()
{
console.log("writing...");
sp.write('b');
console.log("done");
});
this is my nodejs script when i run with my serial monitor open makes my led in my arduino blinks
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop()
{
if(Serial.available() > 0)
{
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
}
now, my problem here is when I closed my serial monitor and run my nodejs script it doesnt blink my led. tho, i can see "writing..." and "done" in console.
any ideas why is this happening? or suggestion what to do? thanks in advance.
node version: 6.9.2
npm version: 3.10.9
OS: Ubuntu 14.04 LTS
I've read that the arduino cannot immediately receive a data after opening of port. Or something like that. So, ive tried this syntax and it perfectly works.
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", {
baudrate: 9600,
parser: serialport.parsers.readline("\n")
});
sp.on('open', function() {
sp.on('data', function (data) {
sp.write("b");
});
});
I'm using nodejs "v0.10.28" and npm "1.4.9", downloaded from http://nodejs.org.
I've installed serialport through npm
npm install serialport
My program is running on a Raspberry-pi and needs to keep sending updated values quickly through serialport, so I've created this test program.
var serialPort = require("serialport");
var SerialPort = require("serialport").SerialPort;
var sp = new SerialPort("/dev/ttyAMA0", {
baudrate: 9600
}, false);
console.log("Starting up serial host...");
var message = "Num: ";
var counter = 1000000;
function write()
{
message= counter.toString();
counter+=1;
sp.open(function(err)
{
console.log("Writing serial data: " + message);
sp.write(message, function(err, res)
{
if (err)
{
console.log(err);
}
sp.close();
});
});
}
setTimeout(write, 10); //wait 10 ms for everything to initialize correctly
setInterval(write, 50); //write data every 50 ms
The program runs ok for exactly 1012 writes, then crashes.
Program output towards the end:
...
Writing serial data: 1001011
Writing serial data: 1001012
Writing serial data: 1001013
[Error: Serialport not open.]
events.js:72
throw er; // Unhandled 'error' event
^
Error: Serialport not open.
at SerialPortFactory.SerialPort.close (/home/pi/node_modules/serialport/serialport.js:476:17)
at /home/pi/serialTest.js:25:7
at SerialPortFactory.SerialPort.write (/home/pi/node_modules/serialport/serialport.js:290:9)
at /home/pi/serialTest.js:19:13
at /home/pi/node_modules/serialport/serialport.js:224:11
Why is it crashing?
Is there any buffer overflow in memory somewhere?
And why exactly 1012 writes? Very close to 1024, is it a coincidence?
A friend just helped with answering this privately so I'll share findings here.
Code:
var SerialPort = require("serialport").SerialPort;
var sp = new SerialPort("/dev/ttyAMA0", {
baudrate: 9600
}, false);
console.log("Starting up serial host...");
var message = "Num: ";
var counter = 1000000;
sp.open(function(err) {
if (err) {
console.log("Port open error: ", err);
}
else {
console.log("Port opened!");
}
});
function write()
{
if (sp.isOpen()) {
message= counter.toString();
counter+=1;
console.log("Writing serial data: " + message);
sp.write(message, function(err, res)
{
if (err)
{
console.log(err);
}
setTimeout(write, 50);
});
}
else {
setTimeout(write, 50);
}
}
setTimeout(write, 10); //wait 10 ms for everything to initialize correctly
If you look closely you'll notice that now sp.open() is used once and in the beginning of write function sp.isOpen() is used to check if port is open.
Also setInterval(write, 50); is gone and now only use setTimeout(write, 10);
Code now works, but that still doesn't answer the question why did it use to crash when opening and closing the port in the previous code.
I'm writing an npm module to interface with a piLite with node.js. I'd like to write it properly using TDD principles.
The code I need to test:
var SerialPort = require("serialport").SerialPort;
exports.PiLite = {
device: "/dev/ttyAMA0",
baudrate: 9600,
client: null,
init: function() {
this.client = new SerialPort(this.device, {
baudrate: this.baudrate
}, false);
},
connect: function(callback) {
this.init();
this.client.open(function() {
console.log('Connected to Pi Lite');
callback();
});
},
write: function (data) {
...
The standard usage would be:
var pilite = require('pilite').PiLite;
pilite.connect(function() {
pilite.write('some data');
// calls to functions to send messages to pilite
}
I understand how to test assertions but I don't see how I can test the connectivity to the serial port.
Should I test for it or just test the functions I'm using to write to the serial port?
Edit: I'm pretty new to Nodeunit so any pointers in the right direction would be great.