从串行端口接收数据时中断for循环 [英] Interrupting a for loop while receiving data from a serial port

查看:222
本文介绍了从串行端口接收数据时中断for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当程序从串行端口接收到"K"字符时,如何使程序中断已经运行的for循环?

How can I make my program interrupt an already running for loop when it receives the "K" character from a serial port ?

代码是:

import serial
from time import sleep

ser = serial.Serial(port='/dev/ttyUSB0',baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=0)

while 1:
    for line in ser.read(1):
        input+=chr(line)

        if input == 'S':
            for x in range (1 , 10):  # this is the loop i want to break
                print(x)
                sleep(1)

        if input == 'K':
            print('K received -> BREAK')
            break

        print("Finished")

这样,程序在for循环结束后打印出接收到的K-> BREAK".

That way the program prints 'K received -> BREAK' after the for loop finished.

推荐答案

您不能,因为它尚未运行.

You can't, since it is not already running.

for x in range (1, 10)循环完成执行之前,您的程序不会从输入中读取另一个字符.

Your program won't read another char from the input until the for x in range (1, 10) loop has finished executing.

想象一下输入是'SK'.您的程序将读取'S'字符并执行循环.在每次迭代中, sleep都会停止整个线程,而不仅仅是for循环.因此,当程序从for line in ser.read(1)循环中断时,在处理下一个字符'K'之前,程序将至少停止9次,每次至少一秒钟(此外,请注意,此循环将始终仅运行一次迭代,因为ser.read(1)只读取一个字节).

Imagine the input is 'SK'. Your program will read the 'S' character and execute the loop. In each iteration, sleep stops the whole thread, not just the for loop. So your program will stop 9 times for at least one second each time before processing the next character, 'K', when it will break from the for line in ser.read(1) loop (Also, note that this loop will always run for one iteration only, because ser.read(1) only reads one byte).

如果我理解正确,那么您希望在从串行输入中接收到某个字符后运行一个可能很长的任务,如果收到另一个字符,则要停止正在运行的任务. 为此,您应该在单独的线程中运行任务.

If I understand correctly, you want to run a possibly long task after receiving a certain character from the serial input, and stop the running task if you receive another character. In order to do this, you should run your task in a separate thread.

您可能希望将任务封装在管理线程的类中,但是我能想到的最简单的方法是为您的任务编写函数并在Thread中执行它.您可以使用threading.Event告诉任务在主线程中收到停止字符时停止.

You'd probably want to encapsulate your task in a class that manages the thread, but the simplest way to do this that I can think of is writing a function for your task and executing it in a Thread. You can use a threading.Event to tell the task to stop when you receive the stop character in your main thread.

import serial
import threading
from time import sleep

ser = serial.Serial(port='/dev/ttyUSB0',baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=0)

thread = None
stop_task = threading.Event()

def do_task():
    for i in xrange(10):
        if stop_task.is_set():
            break

        print(i)
        sleep(1)

while True:
    byte = ser.read(1):    # No need for a loop here, read(1) returns a length 1 string
    character = chr(byte)  # I'm not familiar with the serial module, but I think this isn't needed

    if character == 'S':
        # We check that we are not executing the task already, and if so we handle it accordingly
        if thread:
            print('Error: a task is already running!')
            continue

        # Start the task in a thread
        stop_task.clear()
        thread = threading.Thread(target=do_task)
        thread.start()
    elif character == 'K':
        print('K received -> BREAK FROM TASK')

        if thread:
            stop_task.set()
            thread = None

请记住,这一次只能同时完成一项任务,并且通常应确保启动的所有线程均已完成(在此示例中,很明显它们将在设置事件后最终完成,但是更复杂的执行可能会使线程陷入无限循环.

Keep in mind that this will only work for one task at a time only and that in general you should make sure that any thread you start finishes (in this example it is pretty clear they will finish eventually after setting the event, but more complex executions may get the thread stuck in an infinite loop).

这是一个小例子,但我希望它可以帮助您朝正确的方向前进.

It's a small example, but I hope it helps you get in the right direction.

这篇关于从串行端口接收数据时中断for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆