问题描述
我在python中运行一个简单的PID控制程序。 基本上是无限循环,从传感器读取然后计算适当的控制信号,以及向终端输出诊断信息。
但是,有时在观察诊断信息时,我想通过断开循环,接受用户输入,然后返回到完全相同的循环来更改PID系数 - 这实际上是循环使用的一些常量。 我想这么做几次。
使用'goto',这将简单易用,正是我想要的。 有人可以给我一些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
1楼
只要你在每次中断后重启“从顶部”都没问题(而不是在信号被提升时返回循环中的确切点,这是一个更难的问题):
while True:
try:
controller.main_loop()
except KeyboardInterrupt:
controller.set_coefficients()
2楼
如果您不想为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
新参数。
然而,这需要重写你的循环。
可能应该将它分成一个发生器,它将为您提供传感器数据,并进入一个实际上根据传感器值进行处理的函数。
3楼
您已经有几种方法可以与循环进行交互,我想指出另一种方法: select()
。
使用select()
,您可以等待任一用户输入。
如果添加超时,如果没有可用的用户输入,则可以进入正常循环,并与那里的硬件进行交互。
笔记:
- 这是的文档,但请考虑顶部的警告,然后查看模块。
- 与使用键盘中断的解决方案一样,此解决方案将在更改参数时停止与硬件交互。 如果这是不可接受的,则需要使用后台线程。
-
使用
select()
更普遍适用,您也可以等待网络流量。 - 您的硬件将不会尽可能频繁地进行维护,但两者之间会有固定的暂停。 从好的方面来说,你也不会使用完整的CPU。