I made a program that sends out data to my arduino which detects what was sent and then turns on the correct pin according to what key is pressed.
When using the arduino software from my windows computer the arduino sketch works fine, I can make each pin turn on and off by sending either W A S Or D.
When sending via node the RX light on the arduino flashes but nothing else happens.
Can anyone help?
Node.js program:
var httpServer = require('http').createServer(function(req, response){ /* Serve your static files */ })
httpServer.listen(8080);
var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);
everyone.now.logStuff = function(msg){
console.log(msg);
}
var SerialPort = require('serialport2').SerialPort;
var assert = require('assert');
var portName;
if (process.platform == 'win32') {
portName = 'COM4';
} else if (process.platform == 'darwin') {
portName = '/dev/cu.usbserial-A800eFN5';
} else {
portName = '/dev/ttyUSB0';
}
var readData = '';
var sp = new SerialPort();
sp.on('close', function (err) {
console.log('port closed');
});
sp.on('error', function (err) {
console.error("error", err);
});
sp.on('open', function () {
console.log('port opened... Press reset on the Arduino.');
});
sp.open(portName, {
baudRate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
everyone.now.forward = function() {
sp.write("w");
}
everyone.now.back = function() {
sp.write("s");
}
everyone.now.left = function() {
sp.write("a");
}
everyone.now.right = function() {
sp.write("d");
}
sp.on('data', function(data) {
console.log(data.toString());
});
Arduino Program:
void setup(){
Serial.begin(9600);
Serial.write("READY");
//Set all the pins we need to output pins
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
}
void loop (){
if (Serial.available() > 0) {
//read serial as a character
char ser = Serial.read();
Serial.write(ser);
//NOTE because the serial is read as "char" and not "int", the read value must be compared to character numbers
//hence the quotes around the numbers in the case statement
switch (ser) {
case 'w':
move(8);
break;
case 's':
move(9);
break;
case 'a':
move(10);
break;
case 'q':
move(10);
move(8);
break;
case 'd':
move(11);
break;
case 'e':
move(11);
move(8);
break;
}
}
}
void move(int pin){
Serial.print(pin);
digitalWrite(pin, HIGH);
delay(1);
digitalWrite(pin, LOW);
}
I recently dabbled into this. The Arduino automatically resets when it receives serial communication from most things other than the Arduino IDE. This is why you can send from the IDE but not node.js.
I have an Uno and put a capacitor between Reset and Ground.Here's a page with some good info on the subject.
Good luck. http://arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection
On the capacitor and reset issue...
There is a small capacitor between one of the serial control lines and reset on the Arduino in the later models. This capacitor causes the Arduino to reset when the port is opened but otherwise does not interfere with normal serial operation.
This reset trick allows the code upload to reset the Arduino as part of the upload process. When the Arduino starts up the code boot loader runs first for a short time before the loaded code runs.
The upload process is: Reset the Arduino which starts the boot loader, start the upload process in the Arduino IDE, establish communications, upload, then run the loaded code. When the Arduino starts up it waits for uploads for a short period of time, if none are received, it moves on to running the code.
I find this very useful as it allows us to effectively reset the Arduino just by closing and opening the port. In the old Arduino's, without this capacitor, you had to press the reset button at the right time to get the code to upload. And the timing was such that the Arduino spent much more time waiting before it started with the uploaded code.
In the problem described here, I do not believe he was having any troubles due to the reset trick used. It should have had only the effect of resetting the Arduino when he opened the serial port, and from the looks of his information, this is a desired side-effect.
I use node on a daily basis to send actions to my Arduino via usb or via bt and it works great in both cases.
I think your problem comes from sending letters. You should send a buffer instead, with the ascii value of the letter, just like that:
myPort.write(Buffer([myValueToBeSent]));
also, for this, I think you would be better with some "logic" interface, with data headers, number of actions, stuff like that. It is no required for you but it will make your code more robust and easier to modify in the future.
Here is an example of how I do it. First, Node:
var dataHeader = 0x0f, //beginning of the data stream, very useful if you intend to send a batch of actions
myFirstAction = 0x01,
mySecondAction = 0x02,
myThirdAction = 0x03;
You then call them like you did:
everyone.now.MyBatchOfActions = function() {
sp.write(Buffer([dataHeader]));
sp.write(Buffer([0x03])); // this is the number of actions for the Arduino code
sp.write(Buffer([myFirstAction]));
sp.write(Buffer([mySecondAction]));
sp.write(Buffer([myThirdAction]));
}
This way it is easy on the Arduino to Serial.read() the data: (Note that you need to define data header and data footer somewhere)
void readCommands(){
while(Serial.available() > 0){
// Read first byte of stream.
uint8_t numberOfActions;
uint8_t recievedByte = Serial.read();
// If first byte is equal to dataHeader, lets do
if(recievedByte == DATA_HEADER){
delay(10);
// Get the number of actions to execute
numberOfActions = Serial.read();
delay(10);
// Execute each actions
for (uint8_t i = 0 ; i < numberOfActions ; i++){
// Get action type
actionType = Serial.read();
if(actionType == 0x01){
// do you first action
}
else if(actionType == 0x02{
// do your second action
}
else if(actionType == 0x03){
// do your third action
}
}
}
}
}
I hope I'm clear and I hope it helps!
Cheers!
In my case the issue was the reset, but that the serial port was opened - but not available for write until the reset has finished. Putting a 3s delay before writing to the port fixed the issue. Writing ASCII was not an issue.