I am having difficulty reading a USB virtual comm port into GNU Octave, and there are some bizarre goings-on that I would like some input on.
Currently I have a USB CDC virtual comm port device that I programmed to respond to commands over serial with the computer. The device is a microcontroller board (STM32F401C Discovery board) with a gryoscope. The gryoscope is read over SPI onto the microcontroller and then the micro relays the data to the computer. It waits until it receives the "x", "y", or "z" commands to send data and then it continues to send data for that coordinate until a stop bit (anything other than "x", "y", or "z", I usually use "s") is sent.
Using CuteCom I am able to interact well with the device e.g. sending the command "xs" will return a single 6-byte packet of the x-axis angular rate data (maybe something like "+00021"). Using GNU Octave and its instrument-control package I can read in all coordinates, but sending the string "xs" will cause the device to only receive the "x" byte and it will relay x-axis data continuously.
This can be worked around by adding a 1ms character delay. The STM device reading the serial commands waits 1ms between bytes it reads in as well, because previously it was able to send many strings for the x-axis before it received the "s" command.
So it works then, right? Apparently not. The strange behavior starts here, as when I run the command-then-read sequence in Octave by one time everything works, but in a loop the data read in is only the x-axis. I thought this was a timing problem, and I was curious to see what was being read from the port directly using CuteCom.
When CuteCom is monitoring the serial port for data, Octave reads data properly for the duration of the loop. But when it is not monitoring the serial port, it will only read the x-axis.
I do not understand why having CuteCom running in parallel with the Octave script would cause the process to perform as expected, but without CuteCom running the data comes in corrupted. Here is the GNU Octave script:
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 %
The result for the three axes when CuteCom is not running (note how the data is copied for all three lines, with the small delay between them):
The result for the good data output, when CuteCom is running (note the data for each axis is consistent and clear):
Has anyone come across something like this before? What mistakes were made to cause this to happen?
Thanks in advance.