Estoy implementando un filtro para mi sensor IMU y, por lo tanto, quiero visualizar datos casi en tiempo real en la computadora. Utilizo la comunicación en serie binaria para facilitar la parte de envío del arduino (hasta donde yo sé, el serial.print es bastante lento). Así que divido mi int16_t en dos bytes y lo envío, como:
Serial.write ((uint8_t) (gx >> 8)); Serial.write ((uint8_t) (gx & 0xFF));
Después de eso, envío directamente el siguiente número (3 en total por ahora, tal vez hasta 7 números de 2 bytes en el futuro) Leí la cosa en matlab con:
dt (k) = toc; tic; bindata ([1: 6], k) = fread (s, [6,1], ' int8 '); time = cumsum (dt (1: k));
Que lee 6 bytes (3 números) y luego recalculo la representación binaria, los concateno y obtengo el número original (si alguien puede sugerir una manera más fácil ... Encontré matlab bastante poco práctico aquí).
El problema es que los números se mezclan con el tiempo. En ocasiones, cuando no se lee un byte o algo así, los bytes se estropean y se produce un número sin sentido. Se omite un número completo (2 bytes) para una muestra exactamente. En lugar de este número uno, hay dos veces. La siguiente muestra, el orden está desordenado (desplazado, de modo que el primer número sea el segundo). Este proceso aparece después de unos 30 segundos, a veces unos minutos. Después de la primera vez, sigue cambiando y saltando.
¿Alguien puede decirme qué hacer aquí? ¿Puedo incluir algún 'punto de interrupción' / terminador de línea, donde el lector (matlab) sepa, que estamos al comienzo del primer número? ¿O cómo se hace esto en realidad?
Supongo que debo agregar mi objetivo principal: quiero hacer que el envío del arduino sea lo más rápido posible. No deberían ser necesarios cálculos adicionales (si es posible). Y: la razón de estos cambios parece ser la demora (lentitud). Sospecho que es una lectura lenta de matlab, ya que vi scripts de procesamiento fluido en la lectura de HIL. Sin embargo, los errores se han detenido desde que reduje la tasa de baude. Solo los números incorrectos siguen siendo el problema.
¿Puede existir la posibilidad de recorrer el fread y leer y almacenar los valores después de un 'encabezado' agregado? Entonces, digamos que ocurre un pedido incorrecto. Luego descarto todo hasta el siguiente carácter / byte 'a' y uso los siguientes 6 bytes para producir mis 3 valores. Luego espero una 'a' de nuevo. Para eso tendría que hacer un bucle fread (s, [1,1], 'int8'); y busque el encabezado.
Código arduino completo:
// Programa para enviar los datos giroscópicos / acel mediante puerto serie // programas matlab correspondientes: sensing.m y sensing_binary .m // 2 bucles de seguridad para garantizar un tiempo de muestreo constante // #define DEBUG # include "GY86.h" #include "Wire.h" GY86 gy86; int16_t ax, ay, az; int16_t gx, gy, gz; uint32_t currenttime = 0; uint32_t starttime = 0; uint32_t starttime2 = 0; // #define OUTPUT_ACCEL_COUNTS # define OUTPUT_GYRO_COUNTS // #define OUTPUT_ACCEL_BINARY // #define OUTPUT_GYRO_BINARYvoid setup () {9600 ).begin gy86.setup ();} bucle vacío () {tiempo actual = milis (); if (hora actual-hora de inicio > 9) {while (micros () - hora de inicio2 < 9000) {} hora de inicio2 = micros (); // leer las medidas de aceleración / giro sin procesar del dispositivo gy86.getSensorValues (&ax, &ay, &az, &gx, &gy, &gz); // comprobando constantes // gx = -29; // gy = 245; // gz = 17; #ifdef OUTPUT_GYRO_COUNTS Serial.print ((int) gx); Serial.print (F ("\ t")); Serial.print ((int) gy); Serial.print (F ("\ t")); Serial.print ((int) gz); Serial.print (F ("\ t")); # endif # ifdef OUTPUT_ACCEL_COUNTS Serial.print (ax); Serial.print (F ("\ t")); Serial.print (ay); Serial.print (F ("\ t")); Serial.println (az); Serial.print (F ("\ t")); # endif
#si está definido (OUTPUT_ACCEL_COUNTS) || definido (OUTPUT_GYRO_COUNTS) Serial.print (F ("\ n")); # endif # ifdef OUTPUT_ACCEL_BINARY Serial.write ((uint8_t) (ax >> 8)); Serial.write ((uint8_t) (ax & 0xFF)); Serial.write ((uint8_t) (ay >> 8)); Serial.write ((uint8_t) (ay & 0xFF)); Serial.write ((uint8_t) (az >> 8)); Serial.write ((uint8_t) (az & 0xFF)); # endif # ifdef OUTPUT_GYRO_BINARY Serial.write ((uint8_t) (gx >> 8)); Serial.write ((uint8_t) (gx & 0xFF)); Serial.write ((uint8_t) (gy >> 8)); Serial.write ((uint8_t) (gy & 0xFF)); Serial.write ((uint8_t) (gz >> 8)); Serial.write ((uint8_t) (gz & 0xFF)); # endif hora de inicio = hora actual; }}