Enviar un objeto o estructura por puerto serie en Arduino


Llevamos varias entradas profundizando en el uso avanzado del puerto serie en un procesador como Arduino. Hemos visto en el envío y recepción de datos en forma de bytes, y como aplicarlo para enviar y recibir elementos iguales en un array. En esta entrada generalizaremos el concepto para enviar o recibir un objeto u estructura por puerto serie.

Antes de meternos en código, vamos a explicar el interés que tenemos en enviar y recibir un objeto o una estructura por puerto serie, poniéndolo en contexto. Es habitual que hagamos un proyecto en el que necesitamos que dos o más procesadores se comuniquen, y en el que podemos definir el comportamiento tanto del emisor como el receptor (no es una comunicación que nos venga impuesta). Por ejemplo, controlar un vehículo desde un móvil o un brazo robótico desde un ordenador.

Necesitamos que los procesadores intercambien una determinada información, que depende del proyecto que estemos haciendo. Para ello definimos uno o varios mensajes que contengan estos datos y que pueden consistir una agrupación cualquier de otras variables básicas u objetos.

Además, por norma general, tenemos interés en que los mensajes se envíen y reciban completos y, tras verificar que el mensaje es correcto, ejecutar una acción con los datos.

Anuncio:

Si definimos una estructura que contenga nuestro mensaje, codificada de forma consensuada en emisor y receptor, y enviamos la estructura por puerto serie en forma de bytes, el mensaje se envía y recibe directamente de forma sencilla, sin necesidad de realizar conversiones ni procesamientos intermedios.

Recordar que distintos procesadores pueden emplear una cantidad distinta de bytes para representar los tipos básicos, en cuyo caso tendremos que tenerlo en cuenta en el emisor o en el receptor.

¿Cómo de complicado esta forma “pro” de comunicación? Curiosamente mucho más sencillo que estar tratando con textos, dividiendo ficheros por comas, y convirtiendo variables.

Enviar una estructura por puerto serie es tan sencillo como,

void sendStructure(byte *structurePointer, int structureLength)
{
    Serial.write(structurePointer, structureLength);
}
sendStructure((byte*)&myStruct, sizeof(myStruct));

La recepción de la estructura por puerto serie es similar, simplemente.

void recieveStructure(byte *structurePointer, int structureLength)
{
    Serial.readBytes(structurePointer, structureLength);
}
recieveStructure((byte*)&myStruct, sizeof(myStruct));

Ejemplo envío estructura por puesto serie

¿Sencillo verdad? Vamos a verlo en un ejemplo hipotético en el que enviamos la posición de un servo a un robot, y el tiempo en el que queremos que se haga el movimiento.

El código del emisor sería el siguiente,

struct servoMoveMessage
{
   int  servoNum;
   int positionGoal;
   float interval;
};
 
struct servoMoveMessage message;

void sendStructure(byte *structurePointer, int structureLength)
{
    Serial.write(structurePointer, structureLength);
}

void setup()
{
  Serial.begin(9600);
  
  message.servoNum = 10;
  message.positionGoal = 1200;
  message.interval = 2.5;  

  sendStructure((byte*)&message, sizeof(message));
}

void loop() 
{
}

Y el código del receptor

struct servoMoveMessage
{
   int  servoNum;
   int positionGoal;
   float interval;
};
 
struct servoMoveMessage message;

void recieveStructure(byte *structurePointer, int structureLength)
{
  if(Serial.available() < sizeof(message)) return;
  Serial.readBytes(structurePointer, structureLength);
}

void setup()
{
  Serial.begin(9600);
  recieveStructure((byte*)&message, sizeof(message));
}

void loop() 
{
}

Por supuesto aún podemos mejorar mucho el proceso. Por ejemplo, podemos establecer mecanismos para verificar que los datos recibidos son correctos (delimitadores de trama, checksums), un watchdog. Veremos todo esto en próximas entradas.

Si te ha gustado esta entrada y quieres leer más sobre Arduino puedes consultar la sección
tutoriales de Arduino

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.



4.5 2 votes
Article Rating

Anuncio:

Previous Enviar o recibir un array por puerto serie en Arduino
Next Caracteres de control en el puerto serie en Arduino
1 Comment
oldest
newest
Inline Feedbacks
View all comments
German Sanchez
4 years ago

Hola,
Quiero enviar por Serial – Bluetooth los datos de un Joystick de una arduino a otro. Del mando al Coche.
Me surge un problema con tu codigo cuando envio datos de forma muy rapida desde el emisor, entonces el receptor deja de recibir bien los datos.
En el loop() desde donde se envian los datos solo funciona con un delay de minimo 300 milisegundos

Si en lugar de una estructura envio un array de enteros me funcina de maravilla

Saludos

German