I am returning to my minimal code example because I seem to have some other timing weirdness in my MPU9250 data collection loop.
Just to re-establish the problems I am seeing:
When sending data without calling the "send_now()" function I get significant data dropouts. I lose almost half of my 20byte writes while sending 20k iterations over a ~5.13sec time period:

I seem to get no (?) dropouts calling "send_now()" inside my loop, but now it takes me ~20sec to send the 20k writes:

The loop time seems to increase after the first ~10 iterations (corresponding to about 200 bytes of data being sent over serial USB)...
Here is the code for the teensy:
Code:
#pragma GCC optimize ("-O2")
// library imports
#include <Arduino.h>
#include <cstdio>
void setup()
{
Serial.begin(9600); // USB is always 12 Mbit/sec
delay(10000); //wait for user to start up serial listener...
}
char datastring[100];
void fillbuffer(uint32_t iterationCount, uint32_t timeStart, uint32_t timeNow, uint32_t timeDelta)
{
sprintf(datastring,"S\n%lu\n%lu\n%lu\n", iterationCount, timeNow - timeStart, timeDelta);
sprintf(&datastring[strlen(datastring)], "%03d\n\n", 4+strlen(datastring));
}
void loop()
{
// test serial output
uint32_t timePrev = 0;
uint32_t timeStart = micros();
uint32_t samples = 20000;
timePrev = timeStart;
for (uint32_t iterationCount = 0; iterationCount<samples; iterationCount++){
uint32_t timeNow = micros();
fillbuffer(iterationCount, timeStart, timeNow, timeNow-timePrev);
timePrev = timeNow;
Serial.print(datastring);
Serial.send_now();
//Serial.flush();
}
}
and in python:
Code:
#!/usr/bin/env python
import serial # requires pyserial
import sys, os
def collectRawData(port, samples):
collected_data = False
serial_timeouts = 0
f = open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'raw.txt'), 'w')
f.seek(0)
with serial.Serial(port, timeout=0.01) as ser:
i = 0
while i<samples:
i += 1
newline = ser.readline()
if not newline:
serial_timeouts+=1
else:
collected_data = True
serial_timeouts = 0
if collected_data and serial_timeouts>100:
break
f.write(newline)
if (i%1000) == 0:
print i
f.close()
def parseRawData():
message_length = 4 # S, i, t, dt
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'parsed.csv'), 'w') as out:
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'raw.txt'), 'r') as f:
state = 0
buffer = ""
line_number = 0
data_iteration = 0
for line in f:
if line[0] is "S":
state = 1
elif state > 0 and state < message_length:
buffer = buffer + line.strip() + ", "
state += 1
elif state == message_length:
buffer = buffer + line.strip() + "\n"
state += 1
elif state == message_length + 1:
if line.strip():
print "****** (not handled) unexpected text: '", line.strip(), "' @ line ", line_number
else:
data_iteration = int(buffer.split(',')[0])
out.write(buffer)
buffer = ""
state = 0 # reset for next S
else:
print "syncing to 'S' @ line", line_number
if state == 0:
print "writing error line to file"
buffer = str(data_iteration + 1) + ', ' + ( '-9999, '*(message_length-1) ) + '\n'
out.write(buffer)
buffer = ""
state = -1 #don't write multiple error lines
line_number +=1
if __name__ == '__main__':
collectRawData('COM7', 500000)
parseRawData()
I'm just using excel to make plots.