Tengo dificultades para leer un puerto de comunicación virtual USB en GNU Octave, y hay algunos sucesos extraños sobre los que me gustaría recibir información.
Actualmente tengo un dispositivo de puerto de comunicación virtual USB CDC que programé para responder a los comandos en serie con la computadora. El dispositivo es una placa de microcontrolador (placa Discovery STM32F401C) con un giroscopio. El giroscopio se lee sobre SPI en el microcontrolador y luego el micro transmite los datos a la computadora. Espera hasta que recibe los comandos "x", "y" o "z" para enviar datos y luego continúa enviando datos para esa coordenada hasta un bit de parada (cualquier cosa que no sea "x", "y" o " z", normalmente uso "s").
Usando CuteCom puedo interactuar bien con el dispositivo, por ejemplo, enviar el comando "xs" devolverá un solo paquete de 6 bytes de los datos de velocidad angular del eje x (tal vez algo así como "+00021"). Usando GNU Octave y su paquete de control de instrumentos, puedo leer en todas las coordenadas, pero enviar la cadena "xs" hará que el dispositivo solo reciba el byte "x" y transmitirá datos del eje x continuamente.
Esto se puede solucionar agregando un retraso de carácter de 1 ms. El dispositivo STM que lee los comandos en serie también espera 1 ms entre los bytes que lee, porque anteriormente podía enviar muchas cadenas para el eje x antes de recibir el comando "s".
Entonces funciona, ¿verdad? Aparentemente no. El comportamiento extraño comienza aquí, ya que cuando ejecuto la secuencia de comando y luego lectura en Octave una vez todo funciona, pero en un bucle, los datos leídos son solo el eje x. Pensé que se trataba de un problema de sincronización y tenía curiosidad por ver qué se estaba leyendo directamente desde el puerto usando CuteCom.
Cuando CuteCom está monitoreando el puerto serie en busca de datos, Octave lee los datos correctamente durante la duración del bucle. Pero cuando no está monitoreando el puerto serie, solo leerá el eje x.
No entiendo por qué tener CuteCom ejecutándose en paralelo con el script de Octave haría que el proceso funcionara como se esperaba, pero sin CuteCom ejecutándose, los datos se corrompen. Aquí está el script de GNU Octave:
pkg load instrument-control;
pkg load signal;
s1 = serial("/dev/ttyACM0");
set(s1,'baudrate',115200);
set(s1, 'bytesize',8);
set(s1,'parity','n');
set(s1,'stopbits',1);
set(s1,'timeout',100); %10.0 seconds
sleep(0.5);
srl_flush(s1);
datax = [];
datay = [];
dataz = [];
negativex = false;
negativey = false;
negativez = false;
xd = 0;
yd = 0;
zd = 0;
delaytime = 1000; %delay time in microseconds (us)
hold on;
for i = 1:500
srl_write(s1,"x");
usleep(delaytime);
xd = str2num(char(srl_read(s1,6)));
srl_write(s1,"s");
usleep(delaytime);
srl_write(s1,"y");
usleep(delaytime);
yd = str2num(char(srl_read(s1,6)));
srl_write(s1,"s");
usleep(delaytime);
srl_write(s1,"z");
usleep(delaytime);
zd = str2num(char(srl_read(s1,6)));
srl_write(s1,"s");
usleep(delaytime);
datax = [datax xd];
datay = [datay yd];
dataz = [dataz zd];
if mod(i, 10) == 0
hold off;
plot(datax,'r');
hold on;
plot(datay,'b');
plot(dataz,'g');
drawnow;
endif
endfor
%
El resultado de los tres ejes cuando CuteCom no se está ejecutando (observe cómo se copian los datos para las tres líneas, con un pequeño retraso entre ellos):
El resultado de la buena salida de datos, cuando CuteCom se está ejecutando (tenga en cuenta que los datos de cada eje son coherentes y claros):
¿Alguien se ha encontrado con algo como esto antes? ¿Qué errores se cometieron para que esto sucediera?
Gracias de antemano.
Sam
He resuelto el problema, así que publicaré la respuesta. De hecho, fue un problema de tiempo. Para reparar el programa anterior, eliminé el retraso entre el comando "x" y la lectura. No puedo decir con seguridad por qué el programa no se comportaría correctamente con este retraso, pero la mejor manera de obtener los datos era eliminarlos: enviar el comando, leer inmediatamente, enviar el comando de parada, retrasar.
Gracias por la ayuda @Chris Stratton. ¡Aunque el problema era más pequeño de lo esperado!
Sam
chris stratton
read()
o incluso peorfread()
. Es posible que desee desarrollar una herramienta (en python, C o lo que sea) que obtenga datos de manera confiable y luego los canalice a su programa de trazado.sam galagher
chris stratton