Python:如何中断,然后返回while循环,没有goto?

时间:2015-10-22 05:26:27

标签: python pid goto

我在python中运行一个简单的PID控制程序。基本上是无限循环,从传感器读取然后计算适当的控制信号,以及向终端输出诊断信息。

然而,有时在观察诊断信息时,我想通过断开循环,接受用户输入,然后返回到相同的方式来更改PID系数 - 这实际上是循环使用的一些常量。环。我想这样做很多次。

随着'转到'这将简单易行,正是我想要的。有人可以给我一些python伪代码吗?我无法真正想到如何做到这一点。我可以使用CTRL + C异常处理程序中断循环,但是我无法返回主循环。

必须有一些非常简单的方法来做到这一点,但我无法想到它。思考? 我的代码中的代码段:

while True:
        t0 = get_temp_deg_c(thermocouple1)
        print "Hose Temperature = " + str(t0) + " deg C"

        t1 = get_temp_deg_c(thermocouple2)
        print "Valve Temperature = " + str(t1) + " deg C"

        # write temps to file
        fi.write(str(t0))
        fi.write(" " + str(t1) + "\n")

        error = setpoint - t0

        print "Setpoint = " + str(setpoint) + " deg C"
        print "Error = " + str(error) + " deg C"

        percent_error = error/setpoint*100
        print "Percent error = " + str(percent_error) + " %"

        duty_out = p.GenOut(percent_error)
        print "PID controller duty output: " + str(duty_out) + " %"
        # clamp the output
        if(duty_out) > 100:
            duty_out = 100
        if(duty_out < 0):
            duty_out = 0

        PWM.set_duty_cycle(PWM_pin, duty_out)

        # do we need to increment the setpoint?
        if( (setpoint - setpoint_precision) ... # omitted logic here

        # Here we return to the top

3 个答案:

答案 0 :(得分:1)

只要你在每次中断后重启“从顶部”都没问题(而不是在信号被提升时返回循环中的确切点,这是一个更难的问题):

while True:
    try:
        controller.main_loop()
    except KeyboardInterrupt:
        controller.set_coefficients()

答案 1 :(得分:0)

如果您不想为IO使用单独的线程,可以使用生成器来保持您在KeyboardInterrupts中循环的状态。

some_parameter = 1

def do_pid_stuff():
    while True:
        sensor_data1 = 'data'
        sensor_data2 = 'data'
        sensor_data3 = 'data'
        yield 'based on sensor_data1 ' * some_parameter
        yield 'based on sensor_data2 ' * some_parameter
        yield 'based on sensor_data3 ' * some_parameter


stuff = do_pid_stuff()
while True:
    try:
        for control_signal in stuff:
            print(control_signal)
    except KeyboardInterrupt:
        some_parameter = int(input())

因此主循环将继续使用上次执行的yield中的新参数。然而,这需要重写你的循环。可能应该将它分成一个生成器,它将为您提供传感器数据,并将其转换为实际根据传感器值执行操作的函数。

答案 2 :(得分:0)

您已经有几种与循环互动的方式,我想指出另一种方式:select()。使用select(),您可以等待用户输入。如果添加超时,如果没有可用的用户输入,则可以进入正常循环,并与那里的硬件进行交互。

注意:

  • 此处是select的文档,但请在顶部考虑警告,然后查看selectors模块。
  • 此解决方案与使用键盘中断的解决方案一样,在更改参数时将停止与硬件交互。如果这是不可接受的,则需要使用后台线程。
  • 使用select()更为普遍适用,您也可以等待网络流量。
  • 您的硬件将不会尽可能频繁地进行维护,但两者之间会有固定的暂停。从好的方面来说,你也不会使用完整的CPU。