Serial Communication Between 2 Arudino Unos

I am an extreme newbie and need some help. I am trying to have two Uno boards speak to each other via serial communication. I think I have the first board programmed correctly, but having trouble with the 2nd one. Basically I have a proximity sensor on Uno #1 that controls a LED on/off. I would also like to transmit data via serial to a 2nd Uno board that has a LED as well and turn that on/off with the proximity sensor connected to Uno #1. Below is my code, any ideas what I am doing wrong?

Uno #1:

const int SENSOR = 0; const int LED = 13; // LED connected to digital pin 13

int val = 0;

void setup() {

pinMode(LED, OUTPUT); pinMode(SENSOR, INPUT);

Serial.begin(9600); }

void loop() { Serial.println(val); delay(100);

val = analogRead(0);

if (val > 400) { Serial.write(0x01); digitalWrite(LED, HIGH); } else { Serial.write(0x00); digitalWrite(LED, LOW); } }

Uno #2:

const int SENSOR = 0; const int LED = 13; // LED is connected to digital pin 13

int serialdata = 0;

void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); }

void loop() { serialdata = Serial.read(); Serial.println(serialdata); delay(100);

if (serialdata = 0x01) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } }

= is assignment, == is used for testing equality.

That makes sense, but I still can't seem to get these 2 working. I have the Rx connected to Tx from each hardware serial, and a wire connected between a ground on each Arduino as well. Is my code too simple? What am I missing here?

Ardutino 1 (Send)

const int SENSOR = 0;
const int LED = 13; // LED connected to digital pin 13

int val = 0;

void setup() {

pinMode(LED, OUTPUT);
pinMode(SENSOR, INPUT);

Serial.begin(9600);
}

void loop() {
Serial.println(val);
delay(100);

val = analogRead(0);

if (val > 400) {
  Serial.write(0x01);
  digitalWrite(LED, HIGH);
} else {
  Serial.write(0x00);
  digitalWrite(LED, LOW);
}
}

Arduino 2 (Receive)

const int LED = 13; // LED is connected to digital pin 13

int serialdata = 0;

void setup() 4{
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  serialdata = Serial.read();
  Serial.println(serialdata);
  delay(100);
  
  if (serialdata == 0x01) {
    digitalWrite(LED, HIGH);
} else {
    digitalWrite(LED, LOW);
  }
}
void setup() 4{
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

Does this even compile?

No it doesn't, sorry I was taking a screenshot on my mac and press the wrong key which put a 4 into the code by mistake. Here is the corrected code.

Arduino 1 (Send)

const int SENSOR = 0;
const int LED = 13; // LED connected to digital pin 13

int val = 0;

void setup() {

pinMode(LED, OUTPUT);
pinMode(SENSOR, INPUT);

Serial.begin(9600);
}

void loop() {
Serial.println(val);
delay(100);

val = analogRead(0);

if (val > 400) {
  Serial.write(0x01);
  digitalWrite(LED, HIGH);
} else {
  Serial.write(0x00);
  digitalWrite(LED, LOW);
}
}

Arduino 2 (Receive)

const int LED = 13; // LED is connected to digital pin 13

int serialdata = 0;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  serialdata = Serial.read();
  Serial.println(serialdata);
  delay(100);
  
  if (serialdata == 0x01) {
    digitalWrite(LED, HIGH);
} else {
    digitalWrite(LED, LOW);
  }
}
void loop() {
  serialdata = Serial.read();
  Serial.println(serialdata);
  delay(100);
  
  if (serialdata == 0x01) {
    digitalWrite(LED, HIGH);
} else {
    digitalWrite(LED, LOW);
  }
}

Serial.read() isn't blocking, so it will return -1 when there is not data. As you know -1 is not equal to 1, so I wouldn't expect the LED to be lit for more than 100 ms. You should be using Serial.available() to make sure there is data to read before taking action on it.

This might seem like a silly question, but, why are you tying up the hardware serial port exchanging data? Use two other pins, and SoftwareSerial. Then, you can use the hardware serial port for debugging.

Also, describing exactly what the problem is would be helpful. As it is, say val is 430. You are sending ‘4’, ‘3’, ‘0’, , and , and then, after a short pause, 0x01 from one Arduino to another.

The ‘4’, ‘3’, ‘0’, , and will turn the LED off on the receiver. The 0x01 will turn the LED on. But, the next set of data will immediately follow that, and turn the LED off again.

I'll try the Serial.available() and see what happens. But to explain further the project...

I have a proximity sensor on Arduino 1, if the reading from the sensor (val) is greater than 400, it turns on the LED on Arduino 1. I want to hook up Arduino 2 so that it's LED will turn on at the same time as the LED on Arduino 1. Here is a picture of my setup (with power unplugged).

A little judicious use of serial.available should sort matters out. I'd be inclined to send something more readable than 0 and 1 though, perhaps 'H' and 'L'. That way, you can test each module independently using the IDE's serial terminal.

I'll try that, good idea. I finally got it to work using the hardware ports, however there is about a 6 second lag between the two Arduinos. What is that about? Is there a fix?

spidervann: What is that about?

I suppose it's something your code is doing.

I think it may be something my code is not doing, like setting a faster send/receive rate. I tried messing with baud, but didn't see any improvement. Any suggestions or is it just the limitation of the hardware?

A 6 second delay is an eternity for the Arduino, so there is likely something wrong with the code. You haven’t posted updated code, so it’s hard to help.

Arrch: A 6 second delay is an eternity for the Arduino...

Thank you for confirming that, below is my updated code I am currently working with:

Arduino 1 (Send)

const int SENSOR = 0;
const int LED = 13; // LED connected to digital pin 13

int val = 0;

void setup() {

pinMode(LED, OUTPUT);
pinMode(SENSOR, INPUT);

Serial.begin(9600);
}

void loop() {

val = analogRead(0);

if (val > 400) {
  Serial.write('H');
  digitalWrite(LED, HIGH);
} else {
  Serial.write('L');
  digitalWrite(LED, LOW);
}
}

Arduino 2 (Receive)

const int LED = 13; // LED is connected to digital pin 13

int serialdata = 0;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
  serialdata = Serial.read();
  if (serialdata == 'H') {
    digitalWrite(LED, HIGH);
} else {
    digitalWrite(LED, LOW);  
  Serial.println(serialdata);
}
  }
}

Try this (else if):

void loop() {
  if (Serial.available() > 0) {
  serialdata = Serial.read();
  if (serialdata == 'H') {
    digitalWrite(LED, HIGH);
} else if (serialdata == 'L') {
    digitalWrite(LED, LOW);  
  Serial.println(serialdata);
}
  }
}

Also, proper indentation goes a long way in people helping you with your code. On a smaller program, it's not going to make a huge difference, but it's good practice for larger projects. To indent properly, place each curly brace on it's own line and use the Tools > Auto Format option.

Thanks Arrch, I tried the (else if) but stil experience the 6 sec lag. How close to simultaneous should I expect?

I don't think this is the cause of your issue, but the sending arduino is spamming the other with continuous writes. It's really only necessary when the LED state needs to change. Keep the state in a variable and only when you need to change it would you transmit anything.

I'm not sure why the receiver echos back to the sender if it doesn't get an 'H' either.

What I'd do though first is test each module independently with the IDE as I alluded to above.

There seem to be three mistakes.

The sender is sending data as fast as it can without regard for the limitations of the serial link. This means that the link is permanently congested so any message indicating a change in the input value has to sit in the serial buffer while the previously queued messages slowly trickle across the link.

The receiver is outputting several character each time it receives an 'L' character. This means that while it is receiving 'L' its serial output stream will be congested since it has to wait to output several characters for each one it receives. Meanwhile of course its receive buffer is full of stale messages that all have to be read and processed before the new input value is finally noticed.

Finally, the sender is not consuming the output from the receiver so the return serial stream will be stalled anyway.

If your goal is to have low latency then you need to throttle the transmission frequency so that the sender's outgoing serial buffer remains clear, and take out the code from the receiver to trace the incoming values, or change the output format so that it outputs no more than one output character per input character and then add code to the sender to read from the return serial stream.

Hi , maybe you can try to use virtual wire or wire library in i2c.. For use serial you never to disabile serial use for program arduino ... My understanding was that ...

Regards Gnux