Sending sensor data over serial bus (Nano to Nano)

Hi. I am sure the answer to this is simple, I just can't work it out. (If anyone read this post straight after I posted it, apologies posted the wrong transmitter code. Corrected now)

I am new to coding and have learnt quite a bit over the last few months and now trying something a bit more ambitious. I have 1 Nano connected to 8 IR sensors. Based on the the status of these sensors, I want to communicate 3 different states to a 2nd Arduino via the serial comms bus. I decided to use int values to show the sensor state:
int sensorValue1 = 0 //sensor inactive;
int sensorValue1 = 4 //sensor has been triggered;
int sensorValue1= 16 //sensor active but not triggered;

On the receiver side, I need to do calculations with these int values.
The serial comms code I am using has been borrowed and modified for may application. I don't fully understand it, but it works if I want to display the output on my laptop. data1, data2, etc are however strings and I can't use them in calculations. I have spend hours trying to figure out how I can convert these to integers, so that the rest of my code can work with the calculations. Can anyone help please?

Transmitter code (Nano)

int rowStatus1 = 0;   // Sensor status, with test values
int rowStatus2 = 4;    // Sensor status, with test values
int rowStatus3 = 16;  // Sensor status, with test values
int rowStatus4 = 0;    // Sensor status, with test values
int rowStatus5 = 4;    // Sensor status, with test values
int rowStatus6 = 16;  // Sensor status, with test values
int rowStatus7 = 0;    // Sensor status, with test values
int rowStatus8 = 4;    // Sensor status, with test values
int serialDelay = 5000;

void setup()
{
 Serial.begin(9600);     // Open serial comms to arduino Nano
}

void loop() // run over and over
{
 Serial.print(rowStatus1);  Serial.print ("A");
 Serial.print(rowStatus2);  Serial.print ("B");
 Serial.print(rowStatus3);  Serial.print ("C");
 Serial.print(rowStatus4);  Serial.print ("D");
 Serial.print(rowStatus5);  Serial.print ("E");
 Serial.print(rowStatus6);  Serial.print ("F");
 Serial.print(rowStatus7);  Serial.print ("G");
 Serial.print(rowStatus8);  Serial.print ("H");
 Serial.print ('\n');
 delay (serialDelay);
 
  if (Serial.available())
    Serial.write(Serial.read());
}

Receiver code using a Mega for now for debugging, but will use Nano later:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
char c;
String dataIn;
int8_t indexOfA, indexOfB, indexOfC, indexOfD, indexOfE, indexOfF,
       indexOfG, indexOfH;
String data1, data2, data3, data4, data5, data6,
       data7, data8;
int rowStatus1 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus2 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus3 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered 
int rowStatus4 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus5 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus6 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus7 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
int rowStatus8 = 0;  // Read from serial port. 0 = row not active, 4 = sensor triggered, 16 = Aactive but not triggered
        
void setup()
{
 Serial.begin(9600);// Open serial communications to PC
 mySerial.begin (9600);
 Parse_the_Data();
}

void loop()
{
  while(mySerial.available()>0)
  {
    c = mySerial.read();
      if(c=='\n')
    {
      break;
    }
    else
    {
      dataIn+=c;
    }
    }
  if(c=='\n')
  {
    Parse_the_Data();
    //Show data on Serial Monitor
    Serial.println("Data4  = " + data4);
    Serial.println("Data4  = " + data4);
    Serial.println("Data4  = " + data4);
    Serial.println("Data4  = " + data4);
    Serial.println("Data5  = " + data5);
    Serial.println("Data6  = " + data6);
    Serial.println("Data7  = " + data7);
    Serial.println("Data8  = " + data8);
    Serial.println("===============================================");
   
    c=0; //reset the variable
    dataIn="";
  }
}
///////////////////////////////////////////////////////////////////////////////////////////
void Parse_the_Data()
{
  indexOfA = dataIn.indexOf("A");
  indexOfB = dataIn.indexOf("B");
  indexOfC = dataIn.indexOf("C");
  indexOfD = dataIn.indexOf("D");
  indexOfE = dataIn.indexOf("E");
  indexOfF = dataIn.indexOf("F");
  indexOfG = dataIn.indexOf("G");
  indexOfH = dataIn.indexOf("H");
 
  data1 = dataIn.substring (0, indexOfA);
  data2 = dataIn.substring (indexOfA+1, indexOfB);
  data3 = dataIn.substring (indexOfB+1, indexOfC);
  data4 = dataIn.substring (indexOfC+1, indexOfD);
  data5 = dataIn.substring (indexOfD+1, indexOfE);
  data6 = dataIn.substring (indexOfE+1, indexOfF);
  data7 = dataIn.substring (indexOfF+1, indexOfG);
  data8 = dataIn.substring (indexOfG+1, indexOfH);
      
}

I want to convert the data strings to my rowStatus integers.

Thanks
Norman

Don't use the String type on Uno or Mega. Use char arrays instead with e.g. atoi() for text to integer conversion.

My first thought would be to use char array right from the beginning. I don't see the benefit of starting with integers then converting.

The First char could be 1,2,3 matching your states.

You have 8 sensors, second char could be A,B,C,D,E,F,G,H

Or you could reverse them if the parsing becomes more advantageous.

img

Thanks JohnRob

Let me try tonight after work and I will let you know how it goes.

Thanks DrDiettrich

I will try char arrays and let you know how it goes.

@bluemanron
1. Connect NANO and mEGA as per following diagram of Fig-1.

uartNanoMega
Figure-1:

2. Upload the following sketch (your sketch of Post-1 with slight modification) in NANO.

#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5);  //SRX=DPin-4, STX=DPin-5

int rowStatus1 = 0;   // Sensor status, with test values
int rowStatus2 = 4;    // Sensor status, with test values
int rowStatus3 = 16;  // Sensor status, with test values
int rowStatus4 = 0;    // Sensor status, with test values
int rowStatus5 = 4;    // Sensor status, with test values
int rowStatus6 = 16;  // Sensor status, with test values
int rowStatus7 = 0;    // Sensor status, with test values
int rowStatus8 = 4;    // Sensor status, with test values

void setup()
{
  Serial.begin(9600);     // Open serial comms to arduino Nano
  SUART.begin(9600);
}

void loop() // run over and over
{
  SUART.print(rowStatus1);  SUART.print (',');//comma seperated data
  SUART.print(rowStatus2);  SUART.print (',');
  SUART.print(rowStatus3);  SUART.print (',');
  SUART.print(rowStatus4);  SUART.print (',');
  SUART.print(rowStatus5);  SUART.print (',');
  SUART.print(rowStatus6);  SUART.print (',');
  SUART.print(rowStatus7);  SUART.print (',');
  SUART.print(rowStatus8);  SUART.print (',');
  SUART.print ('\n');
  delay (5000);   //test interval
}

3. Upload the following sketch in MEGA.

char myData[50];
char *temPtr;

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

void loop()
{
  byte n = Serial3.available();
  if (n != 0)
  {
    byte m = Serial3.readBytesUntil('\n', myData, 50);
    myData[m] = '\0';  //null-byte
    // Serial.println(myData);
    //------------------------------
    unsigned int s1 = strtoul(myData, &temPtr, 10);
    unsigned int s2 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s3 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s4 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s5 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s6 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s7 = strtoul(temPtr + 1, &temPtr, 10);
    unsigned int s8 = strtoul(temPtr + 1, &temPtr, 10);
    //----------------------------------------------
    Serial. println(s1, DEC); Serial. println(s2, DEC);
    Serial. println(s3, DEC); Serial. println(s4, DEC);
    Serial. println(s5, DEC); Serial. println(s6, DEC);
    Serial. println(s7, DEC); Serial. println(s8, DEC);
    Serial.println("=========================");
  }
}

4. Check that the Serial Monitor of MEGA shows the received status values correctly.

4
=========================
0
4
16
0
4
16
0
4
=========================
0
4
16
0
4

5. Working Principle of strtoul() Function:
The function parses (reads a character from a character type array and checks if it is a decimal or hexadecimal digit) a string (array of characters) and stops at the non-digit character. The ASCII codes of the digits which have been parsed so far are converted into a numerical number and are saved in a variable. For example:

char myArray[] = “1234, 56, 78”;
char *temPtr;r
unsigned int x1 = strtoul(myArray, &temPtr, 10);   // x1 = 0x04D2
Serial.println(x1, DEC);  //shows: 1234

The arg3 (= 10) says that the function looks for decimal digits in the array. The parsing stops at the first comma (,); there remains the sub-array/sub-string (, 56, 78) which will be parsed next time to extract 56. Now, we need a pointer variable (*temPtr) to point the beginning of the sub-array. The arg2 (= &temPtr) passes to the pointer variable the address of the character at which parsing had stopped and thus offers a way to the strtoul() function to locate the beginning of the sub-array.

Hi everyone.

Just wanted to say thanks so much for your help. I am doing this project to help my brother (a farmer in South Africa) solve a problem with planting seeds. Its a bit time critical because the planting season starts from September and I was stuck for days with doing the serial comms coding.

The first Nano monitors 8 x IR sensor to detect the seeds dropping down a tube into the soil. It then communicates the status to the 2nd Nano in the cab of the tracktor. It works well on the bench and I should know in a few weeks how it works in real life

Thanks for the help.
Regards
Norman

1 Like