3

I have Python 2.7.4 and pyserial-2.5 win32 installed on my PC. Here I am using a microcontroller device as a master (primary) and my pc as a slave (secondary). Here every time microcontroller will transmit data, and my PC has to receive the data through serial port. I want a code in Python to receive continuous data. Here the transmitted data size will vary all the time. Here I wrote a code to transmit data, and the code is

import serial
ser= serial.serial("COM10", 9600)
ser.write("Hello world\n")
x = ser.readline()
print(x)     

With this code I can transmit data to the other PC, I crosschecked by opening HyperTerminal on the other PC and I can see the transmitted data (hello world).

I also wrote the code to receive data:

import serial
ser=serial.serial("COM10", 9600)  
while 1:
if ser.inwaiting():
val = ser.readline(ser.inwaiting())
 print(val)  

if I send the data (how are you) from HyperTerminal, I can receive the data in my PC, with the above code.

Until this every thing is fine.

My question now is, when the microcontroller is transmitting variable data at variable time periods, I need to receive that data in my PC with Python. Do I need to use a buffer to store the received data? If yes, how will the code be? Why and how to use a buffer in Python? According to my search in internet, buffer is used to slice the string.

3
  • I don't understand your question very well, do you want to just store the data instead of printing it? In that case, create a new list (data = []) and append the content you receive inside the loop (data.append(val)) Commented Jun 2, 2013 at 10:56
  • Do i need to store the transmitted data in buffer before printing it? Commented Jun 4, 2013 at 6:33
  • What do you mean by "buffer"? A list is a valid structure for storing the data you want. Commented Jun 4, 2013 at 19:29

1 Answer 1

3

Typically what you do for communicating with a micro is to use single characters for something lightweight or create a communication protocol. Basically you have a start flag, end flag, and some sort of checksum to make sure the data gets across correctly. There are many ways to do this.

The below code is for Python 3. You may have to make changes for bytes data.

# On micro
data = b"[Hello,1234]"
serial.write(data)

On the computer you would run

def read_data(ser, buf=b'', callback=None):
    if callback is None:
        callback = print

    # Read enough data for a message
    buf += ser.read(ser.inwaiting()) # If you are using threading +10 or something so the thread has to wait for more data, this makes the thread sleep and allows the main thread to run.
    while b"[" not in buf or b"]" not in buf:
        buf += ser.read(ser.inwaiting())

    # There may be multiple messages received
    while b"[" in buf and b']' in buf:
        # Find the message
        start = buf.find(b'[')
        buf = buf[start+1:]
        end = buf.find(b']')
        msg_parts = buf[:end].split(",") # buf now has b"Hello, 1234"
        buf = buf[end+1:]

        # Check the checksum to make sure the data is valid
        if msg_parts[-1] == b"1234": # There are many different ways to make a good checksum
            callback(msg_parts[:-1])

   return buf

running = True
ser = serial.serial("COM10", 9600)
buf = b''
while running:
    buf = read_data(ser, buf)

Threading is useful if you are using a GUI. Then you can have your thread read data in the background while your GUI displays the data.

import time
import threading

running = threading.Event()
running.set()
def thread_read(ser, callback=None):
    buf = b''
    while running.is_set():
        buf = read_data(ser, buf, callback)

def msg_parsed(msg_parts):
    # Do something with the parsed data
    print(msg_parsed)

ser = serial.serial("COM10", 9600)
th = threading.Thread(target=thread_read, args=(ser, msg_parsed))
th.start()


# Do other stuff while the thread is running in the background
start = time.clock()
duration = 5 # Run for 5 seconds
while running.is_set():
    time.sleep(1) # Do other processing instead of sleep
    if time.clock() - start > duration
        running.clear()

th.join() # Wait for the thread to finish up and exit
ser.close() # Close the serial port

Note that in the threading example I use a callback which is a function that gets passed as a variable and gets called later. The other way this is done is by putting the data in a Queue and then processing the data in the Queue in a different part of the code.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.