Arduino to Arduino serial communications help

So, I am trying to interface 2 Arduino's together via their RX and TX pins and they will not connect together for unknown reasons. I can get both the master and slave Arduino to do stuff by injecting letters into them via the serial monitor to make them work since they realize that my computer exists and is talking to it via serial, but when I connect and power them both while not hooked up to my comp and hooked up to each other via RX and TX pins, they don't do the "handshake" (this piece of code: while (!Serial) ) required for them to begin sending data over serial. The hardware side of things looks something like this: Arduino 1's RX is connected to Arduino 2's TX, and Arduino 2's RX is connected to Arduino 1's TX. I am certain it's not working since the serial pins are not firing.

Thanks for your time, and here's the code.

MASTER:

int button1 = 0;    // pushbutton
int button2 = 0;   // pushbutton
int pot = 0;    // potentiometer
int inByte = 0;         // incoming serial byte
char datasel = 'Z'; // data piece requested by slave
int firstime = 1; // for one-time-only code to the initializaton process

void setup() {

  // start serial port at 9600 bps:

  Serial.begin(9600);

  while (!Serial) {

    ; // wait for serial port to connect.

  }

  pinMode(8, INPUT);  
  pinMode(9, INPUT);
  pinMode(10, INPUT);

  establishContact();  // send a byte to establish contact until receiver responds
}

void loop() {
  
  

  // if we get a valid byte, read inputs from buttons and such

  if (Serial.available() > 0 ) {

    // get incoming byte:

    

    button1 = digitalRead(8);

    

  

   

    button2 = digitalRead(9);

    // switch potentiometer signal to PWM signal

    pot = map(analogRead(A0), 8, 1008, 0, 255);
    if (pot > 255)
      {
        pot = 255;
      }
      
       if (Serial.available() > 0 && firstime == 1) 
  // to avoid deleting imprtant bytes and to get rid of Z initializer
    {
      inByte = Serial.read();
      firstime = 0;
      Serial.print('X'); // tell slave that it's ready to send sensor values
    }
       
}
    // send REQUESTED sensor values:
    
     
     
        datasel = Serial.read(); // See what data the slave has requested
        
        if (datasel == 'A')
        {
          Serial.write(button1);
          
         
          
          Serial.print('X'); // tell slave that it's ready to send sensor values
        }
        
        else if (datasel == 'B')
        {
          Serial.write(button2);
          
           
          
          Serial.print('X'); // tell slave that it's ready to send sensor values
        }
        else if  (datasel == 'C')
        {
          Serial.write(pot);
          
           
          
          Serial.print('X'); // tell slave that it's ready to send sensor values
        }
     
     
    
   

    
      

  }


void establishContact() {

  while (Serial.available() <= 0) {

    Serial.print('Z');   // send a capital Z

    delay(300);

  }
}

SLAVE (for testing, not hooked up to anything, change if you wish)

/*

*/
int initialize = 0; // for init process
char data = 'Z'; // for data req process 
void setup() {
    Serial.begin(9600);
    
     while (!Serial) {

    ; // wait for serial port to connect.

  }
}

void loop() {
  
  // initialize AM to AS communications
  
  if (initialize == 0)
  {
   Serial.write('Z'); // do only once to INITIALIZE and NOT request data 'Z'
   initialize = 1;
  }
  
  // request sum gud shit
  
  data = Serial.read();
  
  if (data == 'X')
    
    {
   Serial.write('A');
   Serial.write('B');
   Serial.write('C');
    
    }
}

The Rx and Tx pins of AVR based boards such as the Uno and Nano are used by the hardware Serial interface to communicate with the Serial monitor and to upload code which will interfere with using them for other purposes

If you are using such a board then consider using SoftwareSerial to implement a second serial interface on the boards using other pins

If you are not using such boards then there is a good chance that the board has more built in UARTs.

Which boards are you using ?

As @UKHeliBob said... depending in the board you probably can't use the hardware serial pins.

If you use Software Serial you can use any pins.

The other important thing is that you MUST have a common GND connection between the devices.

Try the following sketch on both boards. Connect pins 7 to 8, 8 to 7, GND to GND.

Anything typed in the monitor should be shown on the other board's serial monitor.

#include <SoftwareSerial.h>

#define BAUD 38400

SoftwareSerial softSerial (7, 8);  // Rx, Tx as required.


void setup()
{
  Serial.begin(BAUD);
  softSerial.begin(BAUD);

  Serial.print("Ready @ ");
  Serial.print(BAUD);
  Serial.println(" baud");
}


void loop()
{
    while (Serial.available() > 0)
     softSerial.write(Serial.read());
  
    while (softSerial.available() > 0)
     Serial.write(softSerial.read());
}

Set the baud rate to 38400 in the monitors.

Apart, of course, from 0 and 1

... of course. The GND and 5v pins also don't work. :slight_smile:

1 Like

Using the RAW pin could also cause a few problems

What I should have said was

If you are using such a board then consider using SoftwareSerial to implement a second serial interface on the boards using other GPIO pins

It may not matter, but most master/slave systems I'm familiar with operate on the assumption that the slaves will all be awake when the master comes on line, so the master initiates all communication cycles; I note you're playing the opposite approach, where every slave wakes up and speaks without prompting. This works fine in a 1-1 approach, but often fails miserably when setting up a 'party line', or bus, approach, because it's inherently unpredictable. I suggest you code it such that each slave wakes up and listens for the master to speak.

2 UNO's and I know that. I unplug the serial pins when uploading and unplug them from my computer when testing

ill try this as a last resort, looks interesting. But first im going to try camsysca's idea and one of my own as well.

Ok, ill do this when I attempt to fix code

@red_car is correct, and this is a common misunderstanding in both serial, and RS485 bus communications.

Don't worry. I know, also I have paved the groundworks for a repair. I will edit this comment when It finally works along with the functional master/slave codes

EDIT: waiting on reply from red_Car, RXTX simply does not want to work

I am going to use this since the Arduinos simply won't recognize eachother as serial devices and send data, but first I have a question: Will what I have just stated matter to this code? want to know so I don't waste my time.

Which bit are you talking about?

Just try the sketch in post #3.

post your latest test code, and a sketch of how you have it connected. You are giving up on a process that has been done successfully thousands, perhaps millions of times.

arduino MS system

bottom arduino is slave, other one is master.

MASTER CODE



int button1 = 0;    // pushbutton
int button2 = 0;   // pushbutton
int pot = 0;    // potentiometer
int inByte = 0;         // incoming serial byte
char datasel = 'Z'; // data piece requested by slave
int firstime = 1; // for one-time-only code to the initializaton process

void setup() {

  // start serial port at 9600 bps:

  Serial.begin(9600);
  Serial.write('Z');

  while (!Serial) {

    ; // wait for serial port to connect.

  }

  pinMode(8, INPUT);  
  pinMode(9, INPUT);
  pinMode(10, INPUT);

  establishContact();  // send a byte to establish contact until receiver responds
}

void loop() {
  
  if (Serial.available() > 0) {
  
   button1 = digitalRead(8);
   
   button2 = digitalRead(9);

    // switch potentiometer signal to PWM signal

    pot = map(analogRead(A0), 8, 1008, 0, 255);
    if (pot > 255)
      {
        pot = 255;
      }
  
   // if we get a valid byte, read inputs from buttons and such

  if (Serial.available() > 0 ) {

    // get incoming byte:

     if (Serial.available() > 0 && firstime == 1) 
  // to avoid deleting imprtant bytes and to get rid of Z initializer
    {
      inByte = Serial.read();
      firstime = 0;
      Serial.print('X'); // tell slave that it's ready to send sensor values
    }
       
}
    // send REQUESTED sensor values:
    
     
     
        datasel = Serial.read(); // See what data the slave has requested
        
        if (datasel == 'A')
        {
           Serial.print('X'); // tell slave that it's ready to send sensor values
           
           button1 = button1 + '0';
           
           Serial.write(button1);
        }
        
        else if (datasel == 'B')
        {
         Serial.print('X'); // tell slave that it's ready to send sensor values
           
         Serial.write(button2);
        }
        else if  (datasel == 'C')
        {
          Serial.print('X'); // tell slave that it's ready to send sensor values
           
          Serial.write(pot);
        }
     
     }

}
void establishContact() {
   datasel = Serial.read();
 while (Serial.available() <= 0) {

    Serial.print('Z');   // send a capital Z

    delay(300);

  }
}






SLAVE CODE:

/*

*/
int initialize = 0; // for init process
char data = 'Z'; // for data req process 
int dataused = 1;
int datashake = 0;
const int led1 = 8;
int serialInArray [3];
int serialCount = 0; 
void setup() {
    Serial.begin(9600);
    pinMode(led1, OUTPUT);
    
    
     while (!Serial) {

    ; // wait for serial port to connect.

  }
}

void loop() {
  
  
  // initialize AM to AS communications
  
  if (initialize == 0)
  {
   data = Serial.read();
   Serial.write('Z'); // do only once to INITIALIZE and NOT request data 'Z'
   initialize = 1;
  }
  
  // request sum gud shit
  
  data = Serial.read();
  
  if (data == 'X')
    
    {
   Serial.write('A');
   
    delay(100);
    
   dataused = Serial.read();
   
   serialInArray[1] = dataused;

   dataused = serialInArray[1] - '0';
  
   
    delay(100);
     
    digitalWrite(led1, dataused);
    
   
   
     
     
    }
    }

  

    
  
    

PS: LED turns on/off at random, no clue why, Ill make a second post with code using the softwareserial.h library when I make it as well.

Another thing: This isn't my first rodeo with serial coms between arduinos, have old code that did not work anymore, even know it used to. Could it be a hardware issue?

Same devices?
Note on button wiring; although what you're doing might work, best success is using opposite corners of the button for connection. Reason is, usually two adjacent pins form one side of the button, the other two form the second contact, and if you've got it rotated 90 degrees, you never get a change of state because your input is always connected. Don't know if that's got any relevance, but we've seen it many times.

If the LED is flickering, your software is changing it's state. That might be a hint that something's not right in the code.

not flickering, more like i activate the pair once, led is off, reactivate one of them via reset, LED turns on and stays that way, no matter what you reset with the exception of the temporarily inactive board not supplying power

will do, and yes same boards. In case its important I did remove both of their ATmegas and put them back in between then and now.