1

I have a microcontroller that sends data via UART at 3 MBaud. The microcontroller sends a start/status Byte every 8000 Bytes. I d'like my python script to read all data and analyse the data between the start bytes.

I know that Python is able to handle 3 MBaud since that code snippet shows the correct positions of start bytes:

ser =  serial.Serial('COM3', 3000000, timeout=None)

_RawData = ser.read(100000)

for cnt in range(0, 100000, 1):
    #search for start byte and print the position    
    if(_RawData[cnt] < 128): print(cnt)

But I need to constantly read the data stream, with that example I loose data between the "ser.read(x)" commands. So I need to compare the data while reading the stream:

ser =  serial.Serial('COM3', 3000000, timeout=None)

_RawData = []
cnt = 0

for c in ser.read():   
    cnt += 1 
    #search for start byte    
    if(c < 128):
        #print start byte position
        print(cnt)

        # -= start thread =-

        _RawData.clear()
    _RawData.append(c)

But found out that reading one single byte is too slow for that baudrate, the start byte position is practically randomly generated. Is there a way I can read my data stream, without loss?

Mathiable
  • 21
  • 2
  • 1
    No editorial on the OP, but it's hilarious that python even has the ability to talk to a uart. I guess when all you have is a hammer, everything looks like a nail. – nicomp Nov 08 '16 at 00:19
  • The `print` is probably slowing you down (the terminal is probably slower than your uart). Other than that, the normal pattern is `for chunk in s.read(chunksize): for ch in chunk: ...` – thebjorn Nov 08 '16 at 00:36
  • 1
    @ nicomp: Whats wrong with UART? It's still the easiest way to get data from a microcontroller to the PC. And with help from an FTDI chip you can have it USB powered with a speed upto 3Mbps. Just because it's an old protocoll doesn't mean it's bad. – Mathiable Nov 08 '16 at 11:55
  • @Mathiable I love UARTs, I am commenting on the fact that a high-level interpreted language can talk to a UART. – nicomp Nov 08 '16 at 21:05
  • @ nicomp: sorry, I seem to have missinterpreted you there. I'ts indeed verry handy, where I work the whole testing team works with python and pyserial to test our hardware. Complex test sequences are written in verry short time. They might have infected me a bit. – Mathiable Nov 08 '16 at 21:27
  • @nicomp Python is a 25-year old general purpose programming language with almost 100,000 packages on PyPI, the package index. It's more a question of what it *can't* talk to at this point. :-) – Ben Hoyt Nov 08 '16 at 21:28

1 Answers1

1

I manage to get it to work for me. As suggested in other threads, I implemented the function ser.inWaiting(), which gives the number of bytes waiting in the input buffer (which on my system is limited to 4096 Bytes) and read that amount from uart. Then I looked for the start byte and started a thread to analyse the data:

ser =  serial.Serial('COM3', 3000000, timeout=None)
_RawData = []

while True:
    #get data in input buffer
    bytesToRead = ser.inWaiting()
    Buffer = ser.read(bytesToRead)

    for cnt in range(0,bytesToRead,1):
        #search for start byte   
        if(Buffer[cnt] < 128):
            #print bytes between start bytes
            print(len(_RawData))

            # -= start thread =-

            _RawData.clear()

        _RawData.append(Buffer[cnt])

    #wait a short time for the buffer to fill    
    time.sleep(0.001)

That seems to work for now. Thanks for the help.

Mathiable
  • 21
  • 2