MicroPython热敏电阻步进电机温度表故障:单向移动卡死
温度控制步进电机异常循环问题
现象
- 程序初始运行正常,无大幅温度波动时工作稳定,但会出现持续判定
wanted_pos > current_pos,驱动电机一直向上移动的卡死情况 - 触发场景:程序启动后静置一段时间,或重启后快速改变温度
预期逻辑
- 读取热敏电阻温度值
TempF,转换为步进电机0-450步的目标位置:wanted_pos = TempF * 450 / 100 - 对比
wanted_pos与当前位置current_pos,根据差值正负设置方向引脚dir_pin的通断 - 计算需要移动的步数并驱动电机
- 开机初始化:若变量未赋值,将电机从0移动到初始目标位置,初始化变量后进入主循环
问题代码
from machine import ADC from machine import Pin import time import math off = 0 on = 1 dir_pin = Pin(20, Pin.OUT) # 步进电机方向引脚 1/0 step_pin = Pin(21, Pin.OUT) # 步进电机脉冲引脚 adcpin = 26 # 热敏电阻数据引脚 thermistor = ADC(adcpin) Vin = 3.3 # 系统总线电压 Ro = 10000 # 分压电阻(10k) delay = 0.006 # 步进延迟时间 # 斯泰因哈特-哈特方程常数 A = 0.001129148 B = 0.000234125 C = 0.0000000876741 def get_current_pos(steps_to_move, last_dir, last_pos): print("get current position called") if last_dir == off: current_pos = last_pos + steps_to_move print(current_pos) elif last_dir == on: current_pos = last_pos - steps_to_move print(current_pos) else: current_pos = last_pos def get_temp_pos(): print("get temp position") adc = thermistor.read_u16() Vout = (3.3/65535)*adc # 计算热敏电阻阻值 try: Rt = (Vout*Ro) / (Vin - Vout) # 斯泰因哈特-哈特方程计算开尔文温度 TempK = 1 / (A + (B * math.log(Rt)) + C * math.pow(math.log(Rt), 3)) # 转换为摄氏度和华氏度 TempC = TempK - 253.15 global TempF TempF = TempC * 1.8 + 32 if TempF > 100: global TempF TempF = 100 elif TempF < 0: global TempF TempF = 1 else: print("happy range") print(TempF) except ZeroDivisionError: global wanted_pos wanted_pos = 0 def get_wanted_pos(): global wanted_pos wanted_pos = TempF * 450 / 100 print("wanted pos") print(wanted_pos) global current_pos def get_steps_to_move(wanted_pos, current_pos): print("get steps to move") if wanted_pos > current_pos: global steps_to_move steps_to_move = wanted_pos - current_pos print(steps_to_move) elif wanted_pos < current_pos: global steps_to_move steps_to_move = current_pos - wanted_pos print(steps_to_move) print("2") elif wanted_pos == current_pos: global steps_to_move steps_to_move = 0 print(steps_to_move) else: pass def move_motor(steps_to_move): global last_pos last_pos = current_pos print("motor call") print(TempF) for _ in range(steps_to_move): step_pin.on() time.sleep(delay) step_pin.off() time.sleep(delay) time.sleep(2) def define_zero(): print("define 0") get_temp_pos() get_wanted_pos() global steps_to_move steps_to_move = wanted_pos global current_pos current_pos = wanted_pos global last_pos last_pos = current_pos global last_dir last_dir = off dir_pin.off() move_motor(steps_to_move) while True: if 'last_dir' in globals(): get_current_pos(steps_to_move, last_dir, last_pos) get_temp_pos() get_wanted_pos() if wanted_pos > current_pos: dir_pin.off() last_dir = off print("OFF") elif wanted_pos < current_pos: last_dir = on dir_pin.on() print("ON") else: ("same_error") get_steps_to_move(wanted_pos, current_pos) move_motor(steps_to_move) else: define_zero()
问题根源与修复
1. 全局变量current_pos未被正确更新
get_current_pos函数内部计算了当前位置,但未声明global current_pos,导致全局变量始终保留初始值,主循环一直认为目标位置大于当前位置,驱动电机持续向上移动。
修复:
def get_current_pos(steps_to_move, last_dir, last_pos): global current_pos # 添加全局声明 print("get current position called") if last_dir == off: current_pos = last_pos + steps_to_move print(current_pos) elif last_dir == on: current_pos = last_pos - steps_to_move print(current_pos) else: current_pos = last_pos
2. 温度转换公式错误
开尔文转摄氏度的公式写错为TempC = TempK - 253.15,正确应为TempC = TempK - 273.15,这会导致温度值计算偏差,间接引发位置判断错误。
修复:
TempC = TempK - 273.15
3. last_pos更新时机错误
move_motor函数中在电机移动前就将last_pos设为current_pos,导致last_pos无法正确记录电机移动后的实际位置。
修复:
def move_motor(steps_to_move): global last_pos print("motor call") print(TempF) for _ in range(steps_to_move): step_pin.on() time.sleep(delay) step_pin.off() time.sleep(delay) last_pos = current_pos # 移动完成后更新位置 time.sleep(2)
4. 初始化逻辑中last_pos赋值错误
define_zero中把last_pos设为目标位置current_pos,但初始化是从0移动到目标位置,last_pos应该初始为0。
修复:
def define_zero(): print("define 0") get_temp_pos() get_wanted_pos() global steps_to_move steps_to_move = wanted_pos global current_pos current_pos = wanted_pos global last_pos last_pos = 0 # 初始位置设为0 global last_dir last_dir = off dir_pin.off() move_motor(steps_to_move)
5. 浮点数精度导致的判断误差
wanted_pos是浮点数,current_pos随步数累计会出现精度偏差,直接用==判断相等会失效,需用差值阈值判断。
修复get_steps_to_move:
def get_steps_to_move(wanted_pos, current_pos): print("get steps to move") diff = abs(wanted_pos - current_pos) if diff < 0.5: # 差值小于半步则不移动 global steps_to_move steps_to_move = 0 print(steps_to_move) elif wanted_pos > current_pos: steps_to_move = round(wanted_pos - current_pos) print(steps_to_move) else: steps_to_move = round(current_pos - wanted_pos) print(steps_to_move) print("2")
内容的提问来源于stack exchange,提问作者Austin Hefley
相关产品推荐
相关产品推荐

