Problem receiving data with radiohead

Hey there. I’m working in a project with autonomous vehicle information like GPS data, orientation of the vehicle, and other data. For comunicate the vehicle and a base station in ground i’m ussing RF433 Mhz with the library RadioHead.
Currently i had create a comunicate protocol for sendind differents types of message. The protocol works when i prove the sendind of an unique proof message, but, when i send differents messages the data that i saw in the Serial it’s quite strange.

Here you have the TX sketch were i’m sending three types of messages. For each message i’m sending it 10 times and then, i send 10 times the next message.

#include <RH_ASK.h>

#include <SPI.h>

RH_ASK rf_driver;
int count = 1;
int aux = 1;

void setup() {
  // Initialize ASK Object
  rf_driver.init();
}

void loop() {
  const char *msg1 = "001";
  const char *msg2 = "01-29.96705-71.356491200";
  const char *msg3 = "022103";
  if (count == 10) {
    aux++;
    count = 0;
  }
  if(aux > 3){
    aux = 1;
  }
  if (aux == 1) {
    rf_driver.send((uint8_t *)msg1, strlen(msg1));
    rf_driver.waitPacketSent();
  } else if (aux == 2) {
    rf_driver.send((uint8_t *)msg2, strlen(msg2));
    rf_driver.waitPacketSent();
  } else if (aux == 3) {
    rf_driver.send((uint8_t *)msg3, strlen(msg3));
    rf_driver.waitPacketSent();
  }
  count++;
}

Then here you have the RX sketch, were the message it’s received and proccesed.

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>
uint8_t buf[27];
uint8_t buflen = sizeof(buf);

// Create Amplitude Shift Keying Object
RH_ASK rf_driver;
int tipoMsje;
int tipoNavegacion;
int radioLlegada;
boolean llegadaPorDerecha;
boolean llegadaLineal;
int partEntera;
float partDecimal;
float latitud;
float longitud;
void setup()
{
  // Initialize ASK Object
  rf_driver.init();
  // Setup Serial Monitor
  Serial.begin(9600);
}

void loop() {
  if (rf_driver.recv(buf, &buflen))
  {
    tipoMsje = ((char)buf[1]) - 48;
    if (tipoMsje == 0) {
      Serial.print("Set Navegación: ");
      tipoNavegacion = ((char)buf[2]) - 48;
      if (tipoNavegacion == 0) {
        Serial.print("Manual");
      } else if (tipoNavegacion == 1) {
        Serial.print("Autonoma");
      }
    } else if (tipoMsje == 1) {
      Serial.print("Agregar punto objetivo: ");
      char dat1 = (char)buf[2];
      int dat2 = ((char)buf[3]) - 48;
      int dat3 = ((char)buf[4]) - 48;
      Serial.print((char)buf[3]);Serial.print(" ")
      partEntera = dat2 * 10 + dat3;
      int dat4 = ((char)buf[6]) - 48;
      int dat5 = ((char)buf[7]) - 48;
      int dat6 = ((char)buf[8]) - 48;
      int dat7 = ((char)buf[9]) - 48;
      int dat8 = ((char)buf[10]) - 48;
      partDecimal = ((float)dat4 * 1000.00 + (float)dat5 * 100.00 + (float)dat6 * 10.00 + (float)dat7) / 10000.00;
      latitud = partEntera + partDecimal;
      if (dat1 == '-') {
        latitud = latitud * -1;
      }
      char dat9 = (char)buf[11];
      int dat10 = ((char)buf[12]) - 48;
      int dat11 = ((char)buf[13]) - 48;
      partEntera = dat10 * 10 + dat11;
      int dat12 = ((char)buf[15]) - 48;
      int dat13 = ((char)buf[16]) - 48;
      int dat14 = ((char)buf[17]) - 48;
      int dat15 = ((char)buf[18]) - 48;
      int dat16 = ((char)buf[19]) - 48;
      partDecimal = ((float) dat12 * 1000.00 + (float) dat13 * 100.00 + (float) dat14 * 10.00 + (float) dat15) / 10000.00;
      longitud = partEntera + partDecimal;
      if (dat9 == '-') {
        longitud = longitud * -1;
      }
      int dat17 = ((char)buf[20]) - 48;
      if (dat17 == 0) {
        //Aqui se levanta flag de llegada el punto de forma lineal
        llegadaLineal = true;
        Serial.print("Latitud: "); Serial.print(latitud, 4); Serial.print(" Longitud: "); Serial.print(longitud, 4); Serial.print(" trayectoria lineal");
      } else if (dat17 == 1) {
        llegadaLineal = false;
        int dat18 = ((char)buf[21]) - 48;
        int dat19 = ((char)buf[22]) - 48;
        radioLlegada = dat18 * 10 + dat19;
        int dat20 = ((char)buf[23]) - 48;
        if (dat20 == 0) {
          llegadaPorDerecha = false;
          Serial.print("Latitud: "); Serial.print(latitud, 4); Serial.print(" Longitud: "); Serial.print(longitud, 4); Serial.print(" trayectoria curva con radio: "); Serial.print(radioLlegada); Serial.print(" por la izquierda");
        } else if (dat20 == 1) {
          llegadaPorDerecha = true;
          Serial.print("Latitud: "); Serial.print(latitud, 4); Serial.print(" Longitud: "); Serial.print(longitud, 4); Serial.print(" trayectoria curva con radio: "); Serial.print(radioLlegada); Serial.print(" por la derecha");
        }
      }
    }else if(tipoMsje == 2){
      int dat21 = ((char)buf[2]) - 48;
      if(dat21 == 1){
        //Solicitud de información de estado
        int dat22 = ((char)buf[3]) - 48;
        int dat23 = ((char)buf[4]) - 48;
        int estado = dat22*10+dat23;
        Serial.print("Solicitud estado: ");Serial.print(estado);
      }else if(dat21 == 2){
        //Accion antes de comenzar trayectoria a punto objetivo
        int dat24 = ((char)buf[3]) - 48;
        int dat25 = ((char)buf[4]) - 48;
        int dat26 = ((char)buf[5]) - 48;
        int val = dat25*10 + dat26;
        if(dat24 == 1){
          //Accion de parpadear led "val" veces
          Serial.print("Antes de llegar Parpadear led x");Serial.print(val);
        }else if(dat24 == 2){
          //Accion de esperar "val" segundos
          Serial.print("Antes de llegar Wait ");Serial.print(val);Serial.print(" segundos");
        }
      }else if(dat21 == 3){
        //Accion en el punto objetivo
        int dat24 = ((char)buf[3]) - 48;
        int dat25 = ((char)buf[4]) - 48;
        int dat26 = ((char)buf[5]) - 48;
        int val = dat25*10 + dat26;
        if(dat24 == 1){
          //Accion de parpadear led "val" veces
          Serial.print("En el punto Parpadear led x");Serial.print(val);
        }else if(dat24 == 2){
          //Accion de esperar "val" segundos
          Serial.print("En el punto Wait ");Serial.print(val);Serial.print(" segundos");
        }
      }else if(dat21 == 4){
        //HANDLER MISION
        int dat24 = ((char)buf[3]) - 48;
        if(dat24 == 0){
          //HALT MISION
          Serial.print("STOP MISION");
        }else if(dat24 == 1){
          //CONTINUE MISION
          Serial.print("RESUME MISION");
        }
      } 
    }
    Serial.println();

  }
}

The output for this it’s like:

Agregar punto objetivo: Latitud: -29.9670 Longitud: -71.3564 trayectoria curva con radio: 20 por la izquierda → (10 times)

Antes de llegar Parpadear led x3 → (10 times)

Set Navegación: Autonoma → (10 times)

Agregar punto objetivo: Latitud: -10.9670 Longitud: -71.3564 trayectoria curva con radio: 20 por la izquierda → (10 times)

In BOLD you have strange thing. All the other message it’s received good, but, this value change.
I think that the problem it’s in the way that i’m sendind the message but i really don’t understand why i’m getting this strange problem.
Thanks.

felixnilo:
The protocol works when i prove the sendind of an unique proof message, but, when i send differents messages the data that i saw in the Serial it’s quite strange.

I’m not sure what that means, but the first thing you should do is confirm that your actual messages are getting through error-free. You need to start with much simpler / cleaner code. These are untested, but they do compile:

Transmitter:

#include "Arduino.h"
#include <RH_ASK.h>
#include <SPI.h>

RH_ASK rf_driver;

const char * const msg[] = {
  "001",
  "01-29.96705-71.356491200",
  "022103"
};

const uint8_t numMessages = sizeof(msg) / sizeof(msg[0]);

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("Starting");
  rf_driver.init();
}

void loop() {
  static uint8_t count = 0;
  static uint8_t aux = 0;

  Serial.print("Sending Message # ");
  Serial.print(aux);
  Serial.print(", = ");
  Serial.println(msg[aux]);
  rf_driver.send((uint8_t *) msg[aux], strlen(msg[aux]));

  count++;
  if (count >= 10) {
    aux++;
    if (aux >= numMessages) {
      aux = 0;
    }
  }
  delay(500);
}

Receiver:

#include "Arduino.h"
#include <RH_ASK.h>
#include <SPI.h>

uint8_t buf[31];
const uint8_t buflen = sizeof(buf);

RH_ASK rf_driver;

void setup()
{
  Serial.begin(115200);
  delay(2000);
  Serial.println("Starting");
  rf_driver.init();
}

void loop() {
  uint8_t msgLen;

  msgLen = buflen - 1;  // save room for terminating null
  if (rf_driver.recv(buf, &msgLen)) {
    Serial.print("Received Message, Length = ");
    Serial.print(msgLen);
    Serial.print(", Content = ");
    buf[msgLen] = '\0';   // add terminating null
    Serial.println((char *) buf);
  }
}

If messages get through successfully, you need to work on your data protocol and receiving algorithm. It’s too complex and convoluted. I would decide on what data needs to be sent (GPS lat / long, orientation, status, commands, etc) and put all that data in a struct. Then send the entire struct (in binary) every time. That way you don’t need to decode a protocol. All data will be in the struct once it’s populated from your receive buffer (confirm that received message is proper length every time, perhaps include a checksum in the struct).

So, i think that the problem it's because i didn't put a null in the end of the buffer right?
I'll add a null in the end of the buffer and i tell you run the program.
And the protocol it's quite neccesary in this case, because there are many differents types of messages. So, the struct that i need it's quite big, so i prefer to send an only message for something in particular.

Thanks for your help.

That was the problem. I don't really know why it's neccesary to add the NULL at the end of the array, but, it's work, all the messages are decoding and reading right.
Thanks men. C:

felixnilo:
I don't really know why it's neccesary to add the NULL at the end of the array, but, it's work, all the messages are decoding and reading right.

Read about c-strings.

felixnilo:
And the protocol it's quite neccesary in this case, because there are many differents types of messages. So, the struct that i need it's quite big, so i prefer to send an only message for something in particular.

Well, it’s your project. If it were my project, I’d use a struct / union configuration that would probably be smaller to send as binary (and more elegant) than the ASCII messages you’re sending now. Something like:

struct messageStruct {
  uint8_t tipoMsje;
  union {
    struct  {
      uint8_t tipo;
    } Navegacion;

    struct {
      float latitud;
      float longitud;
      uint16_t radioLlegada;
      bool llegadaPorDerecha;
    } objetivo;

    struct {
      uint8_t tipo;
      union {
        uint8_t Accion;
        uint8_t estado;
        uint8_t val;
        uint8_t mission;
      };
    } Solicitud;
  };
};

But, as I said, it’s your project.

So do i think that the struct it's more elegant than sending the data in ASCII.
I'll get in consideration your suggest.
Thanks again.