Yes i've tried your code @pythoncoder and can't get the problem to occour. Even with a run time of 5 minutes.
As you'll see my initial code is a myth but represents the problem. What i'm doing is measuring analog pins and transmitting them over UART to a second pyboard. The second pyboard writes this info to disk and I analysis the data by converting it to a csv file. When the data set is small enough.
Code: Select all
# file data_logger.py
import pyb
import time
import array
import ustruct
# These 2 are for performace and consistency. use of
# .enable_irq() and disable.irq() take longer but improve
# consistency
import gc
import machine
import micropython
micropython.alloc_emergency_exception_buf(200)
SHORT_CHAR = 'h'
HEADER_FORMAT = '<ii' + SHORT_CHAR
SIZE_OF_HEADER = ustruct.calcsize(HEADER_FORMAT)
SHORT_FORMAT = '<' + SHORT_CHAR
SIZE_OF_SHORT = ustruct.calcsize(SHORT_FORMAT)
SIZE_OF_INT = ustruct.calcsize('<i')
BUFFER_SIZE = const(1024)
BAUD = const(112500)
BITS = const(8)
class logger_Tx():
def __init__(self, uart, sensor_pins, timer, freq):
self.data_points = len(sensor_pins)
self.buffer_ = bytearray(((self.data_points - 1) * SIZE_OF_SHORT)\
+ SIZE_OF_HEADER)
self.timer = pyb.Timer(timer, freq = freq)
self.sensors = []
for sp in sensor_pins:
self.sensors.append(pyb.ADC(sp))
self.uart = pyb.UART(uart, BAUD, BITS, parity = None, stop =1,\
flow = 0, timeout_char = 0)
def begin(self):
gc.disable()
self.check = 0
self.start = time.ticks_us()
self.timer.counter(0)
self.timer.callback(self.transmit)
def end(self):
self.timer.callback(None)
gc.enable()
def timed(self):
gc.disable()
self.check = 0
self.start = time.ticks_us()
self.transmit(None)
end = time.ticks_us()
gc.enable()
return time.ticks_diff(end, self.start)
@micropython.native
def transmit(self, timer):
machine.disable_irq()
self.check += 1
ustruct.pack_into(HEADER_FORMAT, self.buffer_, 0, self.check,\
time.ticks_diff(time.ticks_us(), self.start),
self.sensors[0].read())
index = SIZE_OF_HEADER
for s in range(1, self.data_points):
ustruct.pack_into(SHORT_FORMAT, self.buffer_, index,\
self.sensors[s].read())
index += SIZE_OF_SHORT
self.uart.write(self.buffer_)
machine.enable_irq()
Here's a main.py to run the logger.
It's sampling pin X1 at 900Hz
Code: Select all
import pyb
import data_logger
log = data_logger.logger_Tx(6 ,('X1', ), 12, 900)
switch = pyb.Switch()
yellow = pyb.LED(3)
def main():
# press and release USR switch
while not switch.value():
pass
while switch.value():
pass
# press USR switch to halt
log.begin()
yellow.on()
while not switch.value():
pyb.delay(1000)
log.end()
yellow.off()
if __name__ == '__main__':
main()
Thanks for looking at this.
Although it doesn't happen at 1.6Khz i get a lot more transmission errors.