serial communication - Arduino to Arduino

Hi Guys,

Iam trying to design a serial communication system. In this circuit I want to control two LEDs (green and red) via two pots, but actually the circuit doesn’t work. I was adding the circuit, using RS232 shield with dp9 cable to link the two Arduinos. For a better understanding of my problem I was adding the code.

I thought the problem is: - The transmitter Arduino doesn’t send the value, or

  • The receiver Arduno doesn’t receive the value
// transmitter Arduino Code
const float referenceVolts = 5;  
const float resistorFactor = 512 ;

const int ledRed = 0;  
const int ledGreen = 1;  

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

void loop()
{
int valRed = analogRead(ledRed);  
float voltsRed = (valRed / resistorFactor) * referenceVolts ;  

Serial.print("XRed = "); 
Serial.println(voltsRed);   


int valGreen = analogRead(ledGreen);  
float voltsGreen = (valGreen / resistorFactor) * referenceVolts ;  

Serial.print("XGreen = ");  
Serial.println(voltsGreen);  
}
// receiver Arduno Code
int RedledPin = 9;
int GreenledPin = 10;

int XRed;
int XGreen;

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

void loop()
{
int VoltR = 25.5 * XRed; //10volt *25.5 = 255
analogWrite(RedledPin, VoltR); 

int VoltG = 25.5 * XGreen;
analogWrite(RedledPin, VoltG);  
}

Thanks for helping.

Where is Serial.read() in receiver code? Actually there is nothing reading (receiving data) in the receiver code.

You don't need any shield to use serial communication between two Arduinos. I assume you are NOT using two Megas - which would be easier. With two Unos just use SoftwareSerial to create a second Serial port on each of them and connect the SoftwareSerial Rx andTx pins (in both directions) and GND.

Use one of the examples in serial input basics to receive the data and make the transmission of the data compatible.

...R

I've used the below simple serial test code to communicate between two arduinos.

//zoomkat 3-5-12 simple delimited ',' string tx/rx 
//from serial port input (via serial monitor)
//and print result out serial port
//Connect the sending arduino rx pin to the receiving arduino rx pin. 
//Connect the arduino grounds together. 
//What is sent to the tx arduino is received on the rx arduino.
//Open serial monitor on both arduinos to test
//A diode between the slave tx and master rx is suggested 
//for isolation, with diode band attached to slave tx side. 
//

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >0) {
        Serial.print(readString); //prints string to serial port out
        Serial.println(','); //prints delimiting ","
        //do stuff with the captured readString 
        readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Thank you for the reply’s.

I use for the receiver Arduino the code from Reply #23 in the Thread from Robin2 to receiving the Datas: serial input basics (I didn't know that the Programming for serial communication is so difficult)

Now I extend the code to control the LED.

The Arduino receive XRed and XGreen value in this form like: “XRed = 10” , “XGreen = 4”

How can I integrate the values in this Loop?

Void LED ()
{
int VoltR = 25.5 * XRed; //10volt *25.5 = 255
analogWrite(RedledPin, VoltR); 

int VoltG = 25.5 * XGreen;
analogWrite(RedledPin, VoltG);  
}

I try many things but it doesn’t work.

Thanks for helping.

LLucas: Thank you for the reply’s.

I use for the receiver Arduino the code from Reply #23

Post your complete program so that we can see all the details. The devil is in the details - especially in programming.

I think the relevant code is in Reply #25 rather than #23

I didn't know that the Programming for serial communication is so difficult

It's not really difficult - you just need a systematic approach. Once you have a function that works you can just copy and paste into any program that needs it.

...R

I use the code from Reply #25.

Here is the complete code, I mark my part with comment

I use the Serial Monitor to see my result.

as an an example: For the test I write the command in the Serial Monitor for 9 V:

<XRed = 9>

Now i want to integrate the values “9” in this function

VoltR = 25.5 * XRed // XRed = 9

// Code for Receiver Arduino
const byte numChars = 90;
char receivedChars[numChars];

boolean newData = false;


int RedledPin   = 9;   // Red LED,   connected to digital pin 9
int GreenledPin = 10;  // Red LED,   connected to digital pin 10

float XRed;
float XGreen;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready -->");
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
  doOtherStuff();  
  led(); // <------------- declaration the function LED 
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;
  
  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) { // <<== NEW - get all bytes from buffer
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
  }
}

void doOtherStuff() {
  delay(20); // <<===NEW - This just simulates time spent elsewhere in a big program
}


void led() // <-------- 
{
int VoltR = 25.5 * XRed; // the MAX is 10V :  10volt *25.5 = 255
analogWrite(RedledPin, VoltR); 

    Serial.print(" val for LED red: "); // <---- i can see the result when i opnen the Serial Monitor
    Serial.println(VoltR);
 
int VoltG = 25.5 * XGreen; // the MAX is 10V :  10volt *25.5 = 255
analogWrite(GreenledPin, VoltG);  

    Serial.print(" val for LED green: ");
    Serial.println(VoltG);
delay (1000);
}

You need to process the data that you receive. In the function led() the Arduino don’t know wath is XRed or XGreen.

Something like this will work:

// Code for Receiver Arduino
const byte numChars = 90;
char receivedChars[numChars];

boolean newData = false;


int RedledPin   = 9;   // Red LED,   connected to digital pin 9
int GreenledPin = 10;  // Red LED,   connected to digital pin 10

float XRed;
float XGreen;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready -->");
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
  doOtherStuff();  
  led(); // <------------- declaration the function LED
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) { // <<== NEW - get all bytes from buffer
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    //newData = false;
  }
}

void doOtherStuff() {
  delay(20); // <<===NEW - This just simulates time spent elsewhere in a big program
}


void led() // <--------
{
const byte numComm = 10;
char command[numComm];
byte i=0;

const byte numVal = 10;
char value[numVal];
byte j=0;

  if (newData == true) {
    newData = false;
    while (receivedChars[i] != '=' && receivedChars[i] != '0' && i < numChars) {
      command[i] = receivedChars[i];
      i++;
      
    }
    command[i] = '\0';
    i++; // remove '=' sign
    j=i;
    
    while (receivedChars[j] != '\0' && j < numChars) {
      value[j-i] = receivedChars[j];
      j++;
    }
    value[j-i] = '\0';
    
    Serial.print("command: ");
    Serial.println(command);    
    
    Serial.print("value: ");
    Serial.println(value);    
    
    if (strcmp(command,"XRed") == 0) {
      XRed = atoi(value);
    }
    else if (strcmp(command,"XGreen") == 0) {
      XGreen = atoi(value);
    }
    else {
      Serial.println("Sintax ERROR!");    
    }
    
    int VoltR = 25.5 * XRed; // the MAX is 10V :  10volt *25.5 = 255
    analogWrite(RedledPin, VoltR);

    Serial.print(" val for LED red: "); // <---- i can see the result when i opnen the Serial Monitor
    Serial.println(VoltR);

    int VoltG = 25.5 * XGreen; // the MAX is 10V :  10volt *25.5 = 255
    analogWrite(GreenledPin, VoltG);  

    Serial.print(" val for LED green: ");
    Serial.println(VoltG);
  }
}

LLucas:
Here is the complete code, I mark my part with comment

I think @luisilva’s code will do what you want.

Your comment
led(); // <------------- declaration the function LED
should be
led(); // <------------- call the function LED

You can remove the function doOtherStuff() and all references to it. It just wastes time - which is what it was designed for.

You might want to consider sending simpler commands.
For example <XRed = 9> could probably be reduced to and then the data could be parsed more easily with, for example

ledColour = receivedChars[0]
ledValue = receivedChars[1]

In serial input basics there is a parse example. As written it is designed for Comma Separated Values (CSV) but it would be easy to change it to use the = sign as the separator

…R

Robin2:
(…)

You might want to consider sending simpler commands.
For example <XRed = 9> could probably be reduced to and then the data could be parsed more easily with, for example

ledColour = receivedChars[0]

ledValue = receivedChars[1]




(...)

I don’t know if this will work. Actually, the value of each colour can vary from 0 to 10, and if this is done like this you miss the value 10.

luisilva: I don't know if this will work. Actually, the value of each colour can vary from 0 to 10, and if this is done like this you miss the value 10.

Fair point. I had not realized that.

But it could still be simplified more than the OP's present system. For instance he could use Hex values which allows 0 to 15 in a single character :)

Really the important point is that if the parts have a fixed length there would be no need to search for the relevant bytes.

...R

Actually, the value of each colour can vary from 0 to 10, and if this is done like this you miss the value 10.

If you need to send a specific value to a specific component, you might try something similar to the below servo control code.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

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

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Hi zoomkat, I have tried out your code, and it works. But I can see a little problem with servos. While i rotate Poti1 to set up Servo1, the other few Servo shake a little bit (about one degree). I think the Signal disturbs other servos. Is there a possibility that “digital outputs” separate from each other to avoid the interaction? For example, if I use two potis and two servos on one Arduino board, the servo will work very fine without any interaction. If you wants, I can upload a video on vimeo to show my problem.

For example, if I use two potis and two servos on one Arduino board, the servo will work very fine without any interaction.

The most common issues with servos is trying to power the servos from the arduino instead of from an external power supply, and failing to connect the servo ground to the arduino ground.