Pages: [1] 2   Go Down
Author Topic: Arduino-to-Arduino serial sending array  (Read 1370 times)
0 Members and 1 Guest are viewing this topic.
Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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:
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?!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49270
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First, this is unnecessary:
Code:
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:
Code:
Serial.write(transArray, 19);

Second, this is plain wrong:
Code:
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.
Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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().
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
 
   ===================
    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:
Code:
#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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49270
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49270
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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).
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...?
Code:
if (Serial.available()>=19)
     {
     for (int i=0; i<19; i++) { incomingBytes[i] = Serial.read(); }
     }
« Last Edit: April 20, 2013, 02:31:40 pm by ThomsonPA » Logged

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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:
Code:
byte transArray[19];         // An Array to store all the data
 
Serial.write(transArray, 19);

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26274
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
i<20
Oops
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Scotland, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
i<20
Oops

Have i missed something...? :O
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26274
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No, you've gained something
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: