Communication between Arduinos

Hi,
I'm making a project which requires 2 Arduinos to talk together. My wiring is simple:
TX <---> RX
RX <---> TX
GND <---> GND

Here is my master code:

char mystr[5] = "Hello";
int led = 4;

void setup() {
Serial.begin(9600);
}
void loop() {
    Serial.write(mystr,5);
    delay(1000);
}

Slave code:

char mystr[10]

void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
Serial.readBytes(mystr,5);
Serial.println(mystr);
delay(1000);

This code gets a serial signal to the slave Arduino and it prints it, but I don't know how to get the code to recognize what is sent in order to turn on an led from there. I tried this:

 incomingByte = Serial.read();
  if (incomingByte == "Hello") {
    digitalWrite(4, HIGH);
  }
}

, but it didn't work. :confused:
Any ideas? Help would be appreciated.
Thanks in advance,
Kyle

that's not goodchar mystr[5] = "Hello";a cString embeds a hidden trailing NULL (0) char at the end, so "Hello" requires 6 bytes to be stored

if you don't send the trailing 0, then you need to add it in the buffer after receiving the data

comparing two cString can be done with strcmp() or if you don't have the trailing null char strncmp()

since you hardwire the number of bytes, your code won't be much flexible. I would suggest to study Serial Input Basics to handle this

The problem is I don't know how to properly compare the data that is sent from the master Arduino to the slave Arduino. I'm assuming it's impossible to do it with a char because you would've just pointed out the flaw in my code, so which should I use. I tried int as well, but I can't seem to get that to work either.
I'll continue to look through what you gave me, but I'm not finding it to be useful at this moment.

Have you read Robin2's rather excellent Serial Input Basics - updated - Introductory Tutorials - Arduino Forum ?

I have and I am continuing to, but remember that I don't care if the data shows up on the serial. I just the slave Arduino to know what the master Arduino sent.

incomingByte = Serial.read();
  if (incomingByte == "Hello") {
    digitalWrite(4, HIGH);
  }
}

Tell me what is wrong with that, it's a basic mistake.

You could try something like:

if (mystr[0] == 'H' && mystr[1] == 'e' && mystr[2] == 'l' && mystr[3] == 'l' && mystr[4] == 'o') {
  digitalWrite(4, HIGH);
} else {
  digitalWrite(4, LOW);
}

Not tested other than I have used something like that in my own code.

1. Build the following connections (Fig-1) between two UNOs using Software UART Ports as the Hardware UART Ports are engaged with Serial Monitor and IDE for sketch debugging and uploading.
uartUnoNano.png
Figure-1:

2. Now carry out the following steps:
(1) Create SUART Port for Transmitter (UNO).
(2) Keep sending the following string to Receiver (NANO) at 1-sec interval

char mystr[] = "Hello"; //array contains 6 items with null-char as the last item

(3) Create SUART Port for Receiver (NANO)
(4) Keep receiving the string from UNO and check that it matches with "Hello" and then show it on SM2 (Serial Monitor 2) and blink LED1.

3. Convert the tasks of Step-2 into the following sketches and upload them into UNO and NANO.
Sketch for UNO

#include<SoftwareSerial.h>  //include this file
SoftwareSerial SUART(2, 3);  //SRX = DPin-2, STX = DPin-3
char myStr[] = "Hello"; //array holds 6 items with null-char

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  SUART.print(myStr);  //send the ASCII codes of the charcaters of myStr to NANO using SUART Port
  SUART.print('\n');   //send Newline character
  delay(1000);
}

Sketch for NANO

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3);
char myStr[20] = "";

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
}

void loop()
{
  byte n = SUART.available(); //check that a charcater has arrived from UNO
  if (n != 0)
  {
    SUART.readBytesUntil('\n', myStr, 20);//store received string in myStr[] array; blocking codes; better to replace by nonblocking codes
    byte x = strcmp(myStr, "Hello"); //comparing null-char terminated strings
    if (x == 0)  //strings are matched
    {
      Serial.println(myStr);  //show the received string on SM2
      digitalWrite(4, HIGH);
      delay(200);
      digitalWrite(4, LOW);
      memset(myStr, 0, 20);  //array is reset to 0s.
    }
  }
}

4. Press the RESET key of both UNO and NANO.
5. Check that the message Hello is appearing on SM2 (Fig-2) at 1-sec interval.
SMgq.png
Figure-2: Serial Monitor (SM2) of NANO

6. Check that LED1 at DPin-4 also makes a blink at 1-sec interval to indicate that the received string has matched with "Hello".

SMgq.png

uartUnoNano.png

That’s how you can compare it with strncmp()

if (!strncmp(mystr,"Hello", 5)) {
  // you received Hello
  ... 
} else {
  // you got something else 
  ...
}

you can also use memcmp()

GolamMostafa:
1. Build the following connections (Fig-1) between two UNOs using Software UART Ports as the Hardware UART Ports are engaged with Serial Monitor and IDE for sketch debugging and uploading.

Figure-1:

2. Now carry out the following steps:
(1) Create SUART Port for Transmitter (UNO).
(2) Keep sending the following string to Receiver (NANO) at 1-sec interval

char mystr[] = "Hello"; //array contains 6 items with null-char as the last item

(3) Create SUART Port for Receiver (NANO)
(4) Keep receiving the string from UNO and check that it matches with "Hello" and then show it on SM2 (Serial Monitor 2) and blink LED1.

3. Convert the tasks of Step-2 into the following sketches and upload them into UNO and NANO.
Sketch for UNO

#include<SoftwareSerial.h>  //include this file

SoftwareSerial SUART(2, 3);  //SRX = DPin-2, STX = DPin-3
char myStr[] = "Hello"; //array holds 6 items with null-char

void setup()
{
 Serial.begin(9600);
 SUART.begin(9600);
}

void loop()
{
 SUART.print(myStr);  //send the ASCII codes of the charcaters of myStr to NANO using SUART Port
 SUART.print('\n');   //send Newline character
 delay(1000);
}




**Sketch for NANO**


#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3);
char myStr[20] = "";

void setup()
{
 Serial.begin(9600);
 SUART.begin(9600);
 pinMode(13, OUTPUT);
 digitalWrite(13, LOW);
}

void loop()
{
 byte n = SUART.available(); //check that a charcater has arrived from UNO
 if (n != 0)
 {
   SUART.readBytesUntil('\n', myStr, 20);//store received string in myStr[] array
   byte x = strcmp(myStr, "Hello"); //comparing null-char terminated strings
   if (x == 0)  //strings are matched
   {
     Serial.println(myStr);  //show the received string on SM2
     digitalWrite(13, HIGH);
     delay(200);
     digitalWrite(13, LOW);
     memset(myStr, 0, 20);  //array is rest to 0s.
   }
 }
}



**4.** Press the RESET key of both UNO and NANO.
**5.** Check that the message Hello is appearing on SM2 at 1-sec interval.
![SMgq.png|605x464](upload://nW6KtUsJm6JDruJvg8uE6NgiabI.png)

**6.** Check that LED1 at DPin-4 makes a blink at 1-sec interval as well to indicate the received string has matched with "Hello".

:fearful: :fearful: :fearful: :fearful: :fearful: :fearful: :fearful: :fearful:

J-M-L:
That’s how you can compare it with strncmp()

if (!strncmp(mystr,"Hello", 5)) {

// you received Hello
 ...
} else {
 // you got something else
 ...
}



you can also use memcmp()
Thank you J-M-L, I didn't want to have to do GolamMastafa's thing :D

What @GolamMustafa was suggesting was a detailed way to help you understand Serial communication. You’d have nothing to loose to explore and learn more.

The problem with

 if (incomingByte == "Hello") {

is that you are not using Arduino Strings

String input;

if (input == "Hello") {

works as expected

To read a String you can use

input = Serial.readString();

Which just reads until the data stop coming.

The advantages of using Strings over the solutions posted above are
i) if (input == "Hello") { work as you would like
ii) you don't have to worry about the exact length of the message. If/when you decide
to send "Hello turn the led On" Strings will just work, where as the solutions above will stop working

The disadvantage of Serial.readString(); is that it will block your receiving loop() for 1sec.
That may not be a problem in your case.

If it is this, method will read a String terminated by '\n' (newline) without blocking

// read Serial until until_c char found, returns true when found else false
// non-blocking, until_c is returned as last char in String, updates input String with chars read
bool readStringUntil(String& input, char until_c) {
  while (Serial.available()) {
    char c = Serial.read();
    input += c;
    if (c == until_c) {
      return true;
    }
  }
  return false;
}

void loop() {
  if (readStringUntil(input, '\n')) { // read until find newline
    Serial.print(F(" got a line of input '")); Serial.print(input); Serial.println("'");
    input.trim(); // remove leading spaces and traling '\n'
    if (input == "Hello") {
         // turn led on
    }
    input = ""; // clear after processing for next line
  }
}

The sending code is just

String cmd;

void loop() {
 if (sendCmd) {
   cmd = "Hello";
   Serial.println(cmd);
 }
}

If you are using Arduino Strings, check out my tutorial on Taming Arduino Strings

As an alternative to sending full Strings, you could just send single chars like 'Y' and 'N'
then the receiver (non-blocking) looks like

void loop() {
  char c = Serial.read(); // note read() returns an int, char c = converts it to a char
  if (c != -1) {   // read() return -1 if there is nothing to be read.
    // got a char handle it
    Serial.println(c);
    if (c == 'Y') {
      // turn led on
     } else if (c == 'N') {
      // turn led off
     } // else ignore this char
  }
}

You can send a lot of unique commands using 'A' .. 'Z' and 'a' .. 'z' and '0' to '9'
The sends are faster also sense less data is being sent/received.

A problem I'm having is that I send 1 command to tell it a true state and then another to make that state false but I can't make the Arduino know which one came first. Is there any code that can do this?

I am writing a general purpose Serial transfer sketch and schematics for various boards (UNO, Mega2560, ESP8266,ESP32, PC-python)
The sketches works with both Software Serial and hardware Serial and synchronize msg/responses between boards
So it holds up sending any other cmds until the last one was received and acted on and responded to.
The msg format is simply any text (the sketch adds replaces any newlines with spaces and adds the newline msg terminator)
The sketch also adds a checksum to pick up msg corruption.
The sketch is very tolerant to delays in the loop() code on either board.
If you want to be a beta tester, drop me a PM.

Here is a draft of the software and board circuits I have so far
https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/ComsPair.html

Have you managed to use software serial successfully on an ESP8266? I couldn't get it to work then read that the reason is that the interrupts needed for WiFi mess up the timing needed for SWS.

Are you aware of:

Serial.swap();

?
Which puts the hardware serial port on GPIO 13 and 15?

I'm pretty sure you are in breach of the Arduino licence by reserving all rights as you have shown on your web site. If you are going to use Arduino products and software you have to comply with their licence.

Thanks for the swap tip.
I have tested the basic transfer but so far not with the WiFi running. Looking forward to real world testing.
The text for this case says

Using a software serial library is not ideal. You should always use a hardware serial connection if available.

Opps this is a draft, missed the acknowledgment Arduino
The other pages have this text at the bottom

For use of the Arduino name see http://arduino.cc/en/Main/FAQ

Let me fix that page.

Just tested with ESP8266 running a Telnet connection.
No checksum errors observed in the Serial connection between UNO SoftwareSerial and ESP8266 SoftwareSerial at 9600
All the ESP8266 Debug msg also sent to the Telnet connection. So seems good so far.
BUT a hardware serial connection (on both sides) is still preferable.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.