Arduino-to-Arduino serial sending array

Hey there guys,

I am trying to send 19 bytes from one Arduino to another (some analog inputs from the first Arduino).

The sending code is simple, using Serial Write:

for (int i=0; i<19; i++) { Serial.write(transArray[i]); }

For some reason on the receiving end, the incoming Array is in the wrong places, but if i was to send only 3 array values, they arrive in the correct place:

The receiving code:

if(Serial.available())
    {
     for (int i=0; i<19; i++) { incomingBytes[i] = Serial.read(); }
    }

Then from here i use them by printing to an LCD.

reading in 3 works fine (i = 3) but above this they appear in the wrong place, what's happening?!

First, this is unnecessary:

for (int i=0; i<19; i++) { Serial.write(transArray[i]); }

The write() method is overloaded to take one or two arguments. You could use the correct method:

Serial.write(transArray, 19);

Second, this is plain wrong:

if(Serial.available())
    {
     for (int i=0; i<19; i++) { incomingBytes[i] = Serial.read(); }
    }

If there is one or more bytes of serial data, it is NOT ok to read all 19 of them.

We would like to see the whole sketch (both of them).
I don't know if transArray[] is an integer or character array.

What would you like to transmit ?
Binary data, or readable data ?
Do you want to transmit a start and stop character ?

If you want to transmit readable data, you could send something like this: "<123,124,125,126>". The "<" is the start, the ">" is the stop, and the data are readable integers seperated with commas.
The transmitter could use Serial.print(), and the receiver could use Serial.parseInt().

Thank you for your help,

PaulS: I tried your solution for the writing, error: "No matching function for call to 'HardwareSerial::write(int [19],int)'
And what is your suggestion for reading?

The full code for Erdin:

Sending:

   ===================
    GLOBAL VARIABLES
   ===================*/
  
#include <SoftwareSerial.h>

SoftwareSerial mySerial =  SoftwareSerial(0, 1);

  int joyxread,joyyread,fwd,rev,left,right,dccch;
  int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15;
  int a = 3;      // Pin which controls INPUT 1 on the L298N
  int b = 4;      // Pin which controls INPUT 2 on the L298N
  int en = 2;     // Pin which controls ENABLE A on the L298N
   
  int transArray[19];         // An Array to store all the data
  int speedCommand = 0x60;
  int lightingCommand = 0x9F;
   
   
  void write1() 
  {
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    delayMicroseconds(48);
    digitalWrite(a, LOW);
    digitalWrite(b, HIGH);
    delayMicroseconds(48);
  }
   
  void write0() 
  {
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    delayMicroseconds(96);
    digitalWrite(a, LOW);
    digitalWrite(b, HIGH);
    delayMicroseconds(96);
  }
   
  void writeByte(int b) {
    for (int i = 7; i >= 0; i--) {
      if ((b & (1 << i)) > 0) {
        write1();
      } else {
        write0();
      }
    }
  }
   
  void writeCmd(int addr, int data)
  {
    int checksum = addr ^ data;
   
    // Preamble
    for (int i = 0; i < 14; i++)
      write1();
   
    // Packet Start
    write0();
     
    writeByte(addr);
   
    // Data Start
    write0();
    writeByte(data);
   
    // Error Start
    write0();
    writeByte(checksum);
   
    // Packet End
    write1();
    write1();
  }
   
  void setup() {
    Serial.begin(9600);
    mySerial.begin(9600);
    pinMode(a, OUTPUT);
    pinMode(b, OUTPUT);
    pinMode(en, OUTPUT);
   
    digitalWrite(en, HIGH);
   
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    dccch = 3;
  }
   
  void loop() {
    writeCmd(dccch, speedCommand);
    delayMicroseconds(10000);
    writeCmd(dccch, lightingCommand);
    JoystickCmd();
    delayMicroseconds(10000);
  }
  
  
  void JoystickCmd()
  {
        joyxread = analogRead(A0);                     // Read the X Axis from the Joystick (Up/Down)
        joyyread = analogRead(A1);                     // Read the Y Axis from the Joystick (Up/Down)
        
        
        joyxread = map(joyxread, 400, 615, 100, 0);     // Map the Joystick and add Nulled Zones
        fwd = map(joyxread, 52, 96, 0, 10);
        rev = map(joyxread, 45, 0, 0, 10);
        if(fwd < 0)      { fwd = 0;  }
        if(fwd > 100)    { fwd = 10; }
        if(rev < 0)      { rev = 0;  }
        if(rev > 100)    { rev = 10; }
  
        joyyread = map(joyyread, 400, 615, 100, 0);     // Map the Joystick and add Nulled Zones
        left = map(joyyread, 52, 96, 0, 10);
        right = map(joyyread, 45, 0, 0, 10);
        if(left < 0)  { left = 0;  }
        if(right < 0) { right = 0; }
        if(left > 2)  {dccch++; delay(300);}
        if(right > 2) {dccch--; delay(300);}
                    
  // Create DCC
  if(fwd > 0)
  {
  speedCommand = speedCommand & ~0x20;
  speedCommand = (speedCommand & ~0x1F) | (fwd);
  }
  
  if(rev > 0)
  {
    speedCommand = speedCommand | 0x20;
    speedCommand = (speedCommand & ~0x1F) | (rev);
  }
  
  
  // Transmission & TOD
  transArray[0] = fwd;
  transArray[1] = rev;
  transArray[2] = dccch;
  transArray[3] = analogRead(A0)/4;
        transArray[4] = analogRead(A1)/4;
        transArray[5] = analogRead(A2)/4;
        transArray[6] = analogRead(A3)/4;
        transArray[7] = analogRead(A4)/4;
        transArray[8] = analogRead(A5)/4;
        transArray[9] = analogRead(A6)/4;
        transArray[10] = analogRead(A7)/4;
        transArray[11] = analogRead(A8)/4;
        transArray[12] = analogRead(A9)/4;
        transArray[13] = analogRead(A10)/4;
        transArray[14] = analogRead(A11)/4;
        transArray[15] = analogRead(A12)/4;
        transArray[16] = analogRead(A13)/4;
        transArray[17] = analogRead(A14)/4;
        transArray[18] = analogRead(A15)/4;
  
for (int i=0; i<19; i++) { Serial.write(transArray, 19); }
}

Reading:

#include <SoftwareSerial.h>
SoftwareSerial mySerial =  SoftwareSerial(0, 1);

#include <TVout.h>
#include <fontALL.h>
/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/
int incomingBytes[19];
int i;
TVout TV;

void setup() 
{
  Serial.begin(9600);
  mySerial.begin(9600);
  TV.begin(PAL,480,234);       // Set up the Screen Resolution and Type of Output
  TV.clear_screen();           // Clear the LCD Display
}

void loop() 
  { // Incoming Data
    //int availableBytes = Serial.available();
    if(Serial.available())
    {
     for (int i=0; i<19; i++) { incomingBytes[i] = Serial.read(); }
    }   
  // Display on the LCD:
  TV.select_font(font6x8);     // Set up Text Font Size
  TV.print(90,0,"Kinord");
  TV.print(0,50,"- Control Information -");
  
  
  TV.print(0,85,"Forward Power : ");
  TV.print(incomingBytes[0]);
  TV.print("    ");
  
  TV.print(0,100,"Reverse Power : ");
  TV.print(incomingBytes[1]);
  TV.print("    ");
  
  TV.select_font(font4x6);
  TV.print(0,70,"DCC Channel : ");
  TV.print(incomingBytes[2]);
  TV.print("    ");
  
  // Train Data
  TV.print("(");
  if(incomingBytes[2] == 1)     {TV.print("ScotRail Class 158");}
  else if(incomingBytes[2] == 2){TV.print("Freightliner Class 66 - 66610");}
  else if(incomingBytes[2] == 3){TV.print("EWS Class 67 - 67030");}
  else if(incomingBytes[2] == 4){TV.print("Network Rail MPV");}
  else                          {TV.print("No Information Available");}
                                 TV.print(")                            ");
                                 
                                 
                                 
                                 
                                 // Sensors Debug:
                                 
                                 TV.print(0,120,"A5 : ");  TV.print(incomingBytes[8]);  TV.print("    ");
                                 TV.print(0,135,"A6 : ");  TV.print(incomingBytes[9]);  TV.print("    ");
                                 TV.print(0,150,"A7 : ");  TV.print(incomingBytes[10]);  TV.print("    ");
                                 TV.print(0,165,"A8 : ");  TV.print(incomingBytes[11]);  TV.print("    ");
                                 TV.print(0,180,"A9 : ");  TV.print(incomingBytes[12]);  TV.print("    ");
                                 TV.print(0,195,"A10 : ");  TV.print(incomingBytes[13]);  TV.print("    ");
                                 TV.print(0,210,"A11 : ");  TV.print(incomingBytes[14]);  TV.print("    ");
                                 TV.print(0,225,"A12 : ");  TV.print(incomingBytes[15]);  TV.print("    ");
                                 TV.print(0,240,"A13 : ");  TV.print(incomingBytes[16]);  TV.print("    ");
                      
    
}

I would like to transmit the integers please.

If you are using the Serial.write() function, that IMPLIES binary data, which IMPLIES bytes. Why are you then not using byte as the array type?

PaulS:
If you are using the Serial.write() function, that IMPLIES binary data, which IMPLIES bytes. Why are you then not using byte as the array type?

Thanks very much, what would your suggestion be for reading as an alternative to what i have done?

Regards

what would your suggestion be for reading as an alternative to what i have done?

You have several choices. You could change the sender to send data differently. You could send the data as text, adding start and end of packet markers, with delimiters between the values. This is a for more robust process, and easier to ensure that the integrity of the packet is maintained. The drawback is that the packet becomes much larger and more resources are need to convert the values to text and to parse the text and convert the text back to values.

Or, you could just tell yourself that data will never get lost, and simply wait for 19 bytes to be available, and then read all 19 and assume that they represent a complete packet (as opposed to some from one packet and some from another).

PaulS:
Or, you could just tell yourself that data will never get lost, and simply wait for 19 bytes to be available, and then read all 19 and assume that they represent a complete packet (as opposed to some from one packet and some from another).

Well i think i will take the risk and just assume there is no packet loss. There is no serious problem if a packet is lost and the connection is not over a long distance.

Therefore...?

if (Serial.available()>=19)
     {
     for (int i=0; i<19; i++) { incomingBytes[i] = Serial.read(); }
     }

Well i think i will take the risk and just assume there is no packet loss. There is no serious problem if a packet is lost and the connection is not over a long distance.

It is not just an issue of packet loss. If you wait for 19 bytes and 1 is lost you will be out of sync forever, e.g. say you lose byte 4, you will read 5 as 4 and 6 as 5 etc. and so on. This did happen to me once (but only ever once) and all of my packets were out of sync. The only way to fix it was to reset. I now (nearly) always use at least a packet terminator.

Zaplady:

Well i think i will take the risk and just assume there is no packet loss. There is no serious problem if a packet is lost and the connection is not over a long distance.

It is not just an issue of packet loss. If you wait for 19 bytes and 1 is lost you will be out of sync forever, e.g. say you lose byte 4, you will read 5 as 4 and 6 as 5 etc. and so on. This did happen to me once (but only ever once) and all of my packets were out of sync. The only way to fix it was to reset. I now (nearly) always use at least a packet terminator.

Yes i suppose your right, but getting it working and saving to the correct array position is first priority.

Sending:

 byte transArray[19];         // An Array to store all the data
  
Serial.write(transArray, 19);

Receiving:

    if (Serial.available() >= 19)
     {
       for (int i=0; i<20; i++) { incomingBytes[i] = Serial.read(); }
     }
i<20

Oops

Can you tell which Arduino boards you are using ?
The transmitter uses SoftwareSerial on pin 0 and 1, but the internal hardware serial port is on pin 0 and 1 on most boards.

Erdin:
Can you tell which Arduino boards you are using ?
The transmitter uses SoftwareSerial on pin 0 and 1, but the internal hardware serial port is on pin 0 and 1 on most boards.

It's mega to mega

AWOL:

i<20

Oops

Have i missed something...? :open_mouth:

No, you've gained something

AWOL:
No, you've gained something

Ah yes of course, must be tired.

Better, some strange numbers coming through, around 50 when i was expecting about 230+

Better, some strange numbers coming through, around 50 when i was expecting about 230+

Since you are using two Megas, you should connect RX1 and TX1 together, and leave the main serial port for talking to the PC. Echo the values in the array on one side. Echo the values in the array on the other side. If there is a discrepancy, you have one issue. If the arrays are the same, you have another issue. As it is, you are flying blind, and I don't think your pilot's license allows IFR yet.

PaulS:

Better, some strange numbers coming through, around 50 when i was expecting about 230+

Since you are using two Megas, you should connect RX1 and TX1 together, and leave the main serial port for talking to the PC. Echo the values in the array on one side. Echo the values in the array on the other side. If there is a discrepancy, you have one issue. If the arrays are the same, you have another issue. As it is, you are flying blind, and I don't think your pilot's license allows IFR yet.

As you suggested, something very strange going on...

Output:

0:0
1:0
2:3
3:127
4:127
5:127
6:127
7:127
8:125
9:131
10:125
11:137
12:122
13:137
14:142
15:151
16:139
17:126
18:125

Input:

0:49
1:52
2:51
3:13
4:10
5:49
6:13
7:10
8:49
9:50
10:53
11:13
12:10
13:48
14:13
15:13
16:10
17:51
18:13

ASCII codes.

As you suggested, something very strange going on...

I agree. Every time you post code, it disappears. At least, I'm assuming that you posted it.