Go Down

Topic: Serial Data - Integers in wrong order  (Read 153 times) previous topic - next topic

patrickstefanski

Hi,
  I'm connecting 2 Arduinos Pro Micros (though I have had this problem with all sorts of boards in similar setups) over Bluetooth using HC-05 modules. 

I set the master to print integer values with a comma between them.  Here is the code: 



Code: [Select]


#define pot A0 // potentiometer for volume control
#define trigger1 2
#define trigger2 3
#define trigger3 4
#define trigger4 5
#define trigger5 6
#define lightPin 7


int trig1;
int trig2;
int trig3;
int trig4;
int trig5;
int volumeKnob;
int state;

long previousMillis;
long interval = 40;

void pair()

{
   digitalWrite(lightPin, LOW);  // turn LED on pin  off

   while(state == 0) {
          state = digitalRead(statepin);  // check to see when BT is paired
          }

   digitalWrite(lightPin, HIGH);   // turn LED on pin 4 on
   delay(200);
   digitalWrite(lightPin, LOW);   // turn LED on pin 4 off
   delay(200);
   digitalWrite(lightPin, HIGH);   // turn LED on pin 4 on
   delay(200);
   digitalWrite(lightPin, LOW);   // turn LED on pin 4 off
   delay(500); // wait  before transmitting data
   digitalWrite(lightPin, HIGH);   // turn LED on pin 4 on


}
// -----------------------------------------------------------------------------
//                              SETUP
// -----------------------------------------------------------------------------
void setup() {
    Serial1.begin(9600);  //Start Serial1, eventually connecting to HC-05
    delay(2000);  // Startup delay

 
    pinMode(pot,INPUT);
    pinMode(trigger1, INPUT_PULLUP);
    pinMode(trigger2, INPUT_PULLUP);
    pinMode(trigger3, INPUT_PULLUP);
    pinMode(trigger4, INPUT_PULLUP);
    pinMode(trigger5, INPUT_PULLUP);
    pinMode(statepin,INPUT);
    pinMode(lightPin, OUTPUT);


  }
// -----------------------------------------------------------------------------
//                             MAIN LOOP
// -----------------------------------------------------------------------------
//Get things working in the loop then try to break out into functions.
void loop() {

    unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;

 state = digitalRead(statepin);  // check to see when BT is paired
  if (state == 0) {
    pair();
  }
  }

     trig1 = digitalRead(trigger1);
     trig2 = digitalRead(trigger2);
     trig3 = digitalRead(trigger3);
     trig4 = digitalRead(trigger4);
     trig5 = digitalRead(trigger5);
     volumeKnob = analogRead(pot);


     Serial1.print(trig1);
     Serial1.print(",");
     Serial1.print(trig2);
     Serial1.print(",");
     Serial1.print(trig3);
     Serial1.print(",");
     Serial1.print(trig4);
     Serial1.print(",");
     Serial1.print(trig5);
     Serial1.print(",");
     Serial1.println(volumeKnob);
}



And the other side is setup to parse the integers.  Like this: 

Code: [Select]

#include <SoftwareSerial.h>
int trig1;
int trig2;
int trig3;
int trig4;
int trig5;
int volumeKnob;


SoftwareSerial mySerial(15, 16); // RX, TX
// -----------------------------------------------------------------------------
//                              SETUP
// -----------------------------------------------------------------------------
void setup() {
    mySerial.begin(9600);
    Serial.begin(9600); //Start Serial

 
    delay(2000);  // Startup delay
}

// -----------------------------------------------------------------------------
//                             MAIN LOOP
// -----------------------------------------------------------------------------
//Get things working in the loop then try to break out into functions.
void loop() {

  if (mySerial.available() > 0) {

// look for the next valid integer in the incoming serial stream:

     trig1 = mySerial.parseInt();
     trig2 = mySerial.parseInt();
     trig3 = mySerial.parseInt();
     trig4 = mySerial.parseInt();
     trig5 = mySerial.parseInt();
volumeKnob = mySerial.parseInt();



    // look for the newline. That's the end of your sentence:
    if (mySerial.read() == '\n') {
    }
         }

Serial.print(trig1);
Serial.print(",");
Serial.print(trig2);
Serial.print(",");
Serial.print(trig3);
Serial.print(",");
Serial.print(trig4);
Serial.print(",");
Serial.print(trig5);
Serial.print(",");
Serial.println(volumeKnob);
}


The problem is I'm receiving data, but it's coming in in the wrong order.  Almost like instead of 1,2,3,4,5,6 it's printing to serial as 3,4,5,6,1,2.  If I reset the Arduino sometimes it's right, sometimes it's wrong. Very strange.  can anyone see what I am doing wrong?

Power_Broker

Because you have no start (or end) marker in your packet, the receiving Arduino actually has no clue which byte corresponds to which value and tends to guess. The bad thing about not having start or end markers in your packet is that if your receiving Arduino guesses wrong, it will remain "desynced" from the transmitter for ever.

You should take a look at this thread for more info on start and end markers.

A quick and easy way to determine if what I'm telling you applies to your system as it is to try turning on the receiver FIRST and after a few seconds, turn on the transmitter. This should always give you good packets. BUT, if you turn on the transmitter first and then the receiver, and you get bad packets, it is guaranteed it is because of the lack of start/end markers.
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

patrickstefanski

#2
Apr 24, 2019, 01:57 am Last Edit: Apr 24, 2019, 01:57 am by patrickstefanski
Thanks Power_Broker!  Just in hopes of learning something here;  Why isn't the line break the end  marker?  In the code (which is admittedly not my own) the note attached to this line says "that's the end of your sentence.

<code>

    // look for the newline. That's the end of your sentence:
    if (mySerial.read() == '\n') {
    }
         }

</code>

I will read through the thread you posted, and thanks again for your reply

Power_Broker

Your code for the receiver doesn't wait until you have a full packet and also doesn't do any checking to see if the packet is corrupted or not (to include detecting dropped bytes)
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

GolamMostafa

#4
Apr 24, 2019, 06:31 am Last Edit: Apr 24, 2019, 06:33 am by GolamMostafa
Alternate codes for the Receiver:
Code: [Select]

void loop()
{
   byte n = mySerial.available();
   if (n !=0)
   {
       mySerial.readBytesUntil('\n', myData, 150);//rcvd chars (except \n) are saved in null-terminated array
       parseData();
   }
}

void parseData()
{
    myData[4] = 0x00;   //replacing , (the item separator) by null byte
    trig1 = atoi(myData);
    //----------------------------------
    myData[9] = 0x00;
    trig2 = atoi(myData+5);
    //---------------------------------
    ............................................

}

Go Up