Node.js SerialPort Arduino Timing Issue - node.js

I'm trying to get my Raspberry Pi/Node.js to communicate with an Arduino Uno using node-serialport. I'm having trouble with the following block of code:
Raspberry Pi
var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort("/dev/ttyACM0", {
baudrate: 9600
});
serialPort.on("open", function () {
console.log('open');
serialPort.on('data', function(data) {
console.log('data received: ' + data);
});
serialPort.write(new Buffer('4','ascii'), function(err, results) {
console.log('err ' + err);
console.log('results ' + results);
});
});
Arduino
// LED on pin 12
int led = 12;
// Incoming serial data
int data=0;
void setup() {
// Pin 12 set to OUTPUT
pinMode(led, OUTPUT);
// Start listening on the serialport
Serial.begin(9600);
}
void loop() {
if(Serial.available()>0){
// Read from serialport
data = Serial.read();
// Check and see if data received == 4
if(data=='4') {
// Blink the LED 3 times
for(int i=0;i<3;i++){
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led,LOW);
delay(1000);
}
// Reset data to 0
data=0;
}
}
}
I am only able to get the Arduino to blink the LED if I wrap a for loop around the serialPort.write() function. At the 40th loop iteration or so the LED finally starts blinking and will continue blinking until serialPort.write() loop is finished. This leads me to believe that I'm encountering some sort of timing issue. I'm looking for a more elegent (and non-blocking) solution to blinking the LED on the Arduino via the Pi. Any help would be greatly appreciated.
Thanks!
Bobby

The problem had to do with Arduino's "AutoReset" see more here.
I didn't actually disable autoreset... I went ahead and implemented the code I posted above. I require user interaction to trigger SerialPort.write(). This works as long as there is a few seconds between when the serial connection is opened and the first write.

My guess is that new Buffer('4','ascii') is doing an ASCII string, and not an ASCII character. The difference being that you're not sending 4, or 44444444… using your loop but 4\0 or 4\04\04\04\04\04\04\0… using your loop.
So when you do Serial.available(), it returns 2, as it got two byte buffered, but you only read one byte. As the buffer of the Arduino is a circular buffer that gets overwritten with new data over time, what can happen is that you're only reading the \0s, until over time the timings shift and you get to read only the 4s.
My advice would be to either read as many characters as there is in the buffer, or simply discard invalid reads, as Serial.read() return -1 when the buffer is empty:
const int led=12;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Read from serialport
int data = Serial.read();
// Check and see if data received == 4
// and thus discard data==-1 or data==`\0`
if(data=='4') {
// Blink the LED 3 times
for(int i=0;i<3;i++){
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led,LOW);
delay(1000);
}
}
}

Related

How to send float values from one bluetooth module to other(HC 05)

I am doing a project where I need to send data from ultrasonic sensor wirelessly present in one arduino to other arduino where I need these values in Serial monitor. But the problem is I cannot able to send these values through bluetooth. I tried to send one character, it is appearing in serial monitor.. But when I tried to the same for integer values it is not appearing in serial monitor.
I have configured Master and Slave modes for the Bluetooth. I have uploaded the image of the code which I am using to send these values. Please help me on this. Thanks in advance .
code
//# transmitting end
#define trigPin 12
#define echoPin 11
void setup() {
Serial.begin(38400); // Default communication rate of the Bluetooth module
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
long duration;
float distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
Serial.println(distance,2); // Sends floatValue
delay(500);
}
//# receving end
#include <SoftwareSerial.h>
#define led 13
SoftwareSerial BTSerial(10, 11);
int data=0;
void setup() {
pinMode(led,OUTPUT);
Serial.begin(38400);
BTSerial.begin(38400); // Default communication rate of the Bluetooth module
}
void loop() {
int number;
if(Serial.available() > 0){ // Checks data is from the serial port
data = BTSerial.read(); // Reads the data from the serial port
//analogWrite(led,data);
delay(10);
//Serial.println(data);
}
Serial.println(data);
}
I need integer values at the serial monitor. But there I am getting some symbols like ?/<>..
From the Arduino reference, Serial.read() only reads the first available byte available in the Serial buffer. As an int is coded on 8 bytes, I would say that you need to read the incoming bytes sequentially in order to get the full value.
Maybe you can implement this by putting (Serial.available() > 0) in a while loop, concatenate the values you get in a char[8] for instance and then convert this char to a integer value.
Also, beware that you are sending floats and not int.
Thanks for the help..!
I modified the code in the receiver end to get the float values from the transmitter.. Here is my modified code
#include <SoftwareSerial.h>
int bluetoothTx = 10;
int bluetoothRx = 11;
String content; //content buffer to concatenate characters
char character; //To store single character
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup(){
bluetooth.begin(38400);
Serial.begin(9600);
}
void loop(){
bluetooth();
}
void bluetooth(){ //
while(bluetooth.available()){
character = bluetooth.read();
content.concat(character);
if(character == '\r'){ // find if there is carriage return
Serial.print(content); //display content (Use baud rate 9600)
content = ""; //clear buffer
Serial.println();
}
}
}

Arduino transmission Data by HC-05(Bluetooth)

platform:Arduino UNO, Arduino Mega2560, HC-05
Here shows the detail.
In Arduino UNO(Master), I encode
Serial.print("A 1 2 3 4 5;");
In Arduino Mega2560(slave), I encode
void setup()
{
//connect to the PC
Serial.begin(9600);
//connect to the Arduino UNO(By bluetooth)
Serial1.begin(38400);
}
void loop()
{
//its value > 0
Serial.println(Serial1.available());
//output : 128 or 248
Serial.print(Serial1.read());
delay(1000);
}
The value of Serial.available() > 0 is true,
but the print result of Serial.print(Serial1.read()); is abnormal. it print
I want to know the reason and its solution.Thanks!
I'm assuming that you made sure that both the Bluetooth devices are connected properly and the baud rates are matched.
Now, one problem might be the buffer might be full. On the sender's side, provide a delay equal to or slightly higher than the delay on the receiver's side.
Next, on the receiver side, change void loop to this:
void loop(){
if(Serial1.avaialable() > 0){
char value = Serial1.read();
Serial.println(value);
delay(1000);
}
}

My HC-05 Bluetooth module is not receiving correct data

I'm trying to built a LED blinker using HC-05, but I encountered an error.
Here is the Arduino code:
int data = 0; //Variable for storing received data
void setup()
{
Serial.begin(9600); //Sets the baud for serial data transmission
pinMode(13, OUTPUT); //Sets digital pin 13 as output pin
}
void loop()
{
if(Serial.available()) // Send data only when you receive data:
{
data = Serial.read(); //Read the incoming data & store into data
Serial.print(data); //Print Value inside data in Serial monitor
Serial.print("\n");
if(data == 1) // Checks whether value of data is equal to 1
digitalWrite(13, HIGH); //If value is 1 then LED turns ON
else if(data == 0) // Checks whether value of data is equal to 0
digitalWrite(13, LOW); //If value is 0 then LED turns OFF
}
}
No matter which button I press on or off, the value of int data will remain same (255).
I also used many apps so I think it is not an app problem.
I found an answer to this problem.
Just change the baud rate and observe the output. My module is working perfectly on 38400.
I hope this will help you out.

Arduino Serial receives false data

I am working on a project in which I use a phone app that I built in order to use Google's Speech Recognizer, connect my phone with my Arduino via Bluetooth and then when I say a word it sends the word in order to display it in a LCD.
The phone App works great with no problems. The problem is in the Arduino code. When I say the word hello for example the Arduino receives ello. I know that it receives it because I also use the Serial monitor to display the data in my computer screen except the LCD. Then after Arduino receives the first chunk of data if I send a second word like world Arduino receives elloorld. So it not only misses again the first letter of the word but also the Serial Port is not empty it in the end of the loop.
I tried with data += c; instead of data.concat(c); and the difference is that the second word isn't elloorld and it is just orld
Here is my code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 9, 8, 7, 6, 5, 4, 3, 2);
char c;
String data = "";
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
}
void loop() {
lcd.clear(); //clean the lcd
lcd.home(); // set the cursor in the up left corner
while(Serial.available() > 0){
c = Serial.read();
data.concat(c);
}
if(data.length() > 0){
Serial.println(data);
}
lcd.print(data);
delay(3000);
data = "";
}
If in the end of the loop I try to clean the Serial Port with this code:
while(Serial.available() > 0){
Serial.read();
}
Then the arduino doesn't receive data at all.
Your code wakes up every 3000 ms, then processes everything that is pending in the Serial input buffer and falls asleep again.
If you remove that ugly String data and the ugly delay(3000) and the unnecessary while, you can try this simple loop:
unsigned long lastreceived;
void loop() {
if (Serial.available()) {
lcd.write(Serial.read());
lastreceived=millis();
}
if (millis() - lastreceived > 1000) {
// after one second of silence, prepare for a new message
lcd.clear();
lcd.home();
lastreceived=millis(); // don't clear too often
}
}

How to convert the incoming characters coming from gsm module into a string?

Its my first time to use gsm shield to my arduino so I'm kinda confused so i need directions. My aim is to read the message sent to my gsm shield then compare that message into a specific string. if they are the same, arduino will do something. Example is, the GSM shield received a text message containing STATUS, the arduino will do something. The problem I'm stuck up with now is how to read the incoming characters from the gsm module into a single string then compare that string into a specific word. I have this code as of now.
#include <SoftwareSerial.h>
#include <String.h>
char inchar[255];
SoftwareSerial cell(2,3);
int led1 = 22;
#define powerOn 4
int i;
//char comparestring[160];
char command[]={'S','T','A','T','U','S','\0'}; // this is a string for command ended with null terminator
void setup()
{
// ilagay sa loob ng setup
digitalWrite(powerOn, HIGH);
delay(1500);
digitalWrite(powerOn, LOW);
delay(5000);
pinMode(led1, OUTPUT);
digitalWrite(led1, LOW);
Serial.begin(9600);
cell.b-egin(9600);
delay(30000);
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=1,2,0,0,0 "); // set module to send SMS data to serial out upon receipt
delay(200);
Serial.println("GSM SHIELD IS NOW OK AND READY");
}
void loop()
{
while(cell.available() >0)
{
inchar[i]=cell.read();
i++;
inchar[i] = '\0';
Serial.print(inchar);
if (inchar==command)
{
digitalWrite(led1, HIGH);
cell.write("AT+CMGS=\"");
cell.write("09267955775");
cell.write("\"\r");
delay(1000);
cell.write("\nTerminal Monitoring System");
delay(1000);
cell.write(0x1A); // End the SMS with a control-z
}
else
{
Serial.println("\nInvalid Keyword! Type ?");
dig-italWrite(led1, LOW);
}
}
}
these codes are the codes that supposed to do the trick but i think its not working. I hope you can teach me the right way. Thank you!
while(cell.available() >0)
{
inchar[i]=cell.read();
i++;
inchar[i] = '\0';
Serial.print(inchar);
if (inchar==command)
inchar is a string so try using strcmp(inchar,command) for comparing the two.

Resources