这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » let'sdo|2026年第1期】静音步进电机控制实践--控制电机转速

共1条 1/1 1 跳转至

let'sdo|2026年第1期】静音步进电机控制实践--控制电机转速

工程师
2026-06-22 10:21:21     打赏

image.png

查看TMC2209的引脚说明可以看出,STEP脚给脉冲信号,脉冲信号频率越高,则电机转速越快,频率越低,转速越慢。按照这个思路,开始编程。

硬件依然是树莓派PICO;TMC2209;步进电机。额外添加了一个电位器,用来控制速度。PICO的16、17、18三个脚,分别与TMC2209 的DIR、STEP、EN相连接;电位器与PICO的28脚连接。

e5ed6b2c4432fbee35ac84933469f3a3.jpg

import machine  
import utime
from machine import ADC

adc = ADC(28)  # 直接填引脚编号 28
motor_dir = machine.Pin(16, machine.Pin.OUT)  
motor_step = machine.Pin(17, machine.Pin.OUT)  
motor_en = machine.Pin(18, machine.Pin.OUT)  
button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)  
led = machine.Pin(25, machine.Pin.OUT)  
motor_en.value(0)  
motor_dir.value(0)  
while True:
    adc_value = adc.read_u16() >> 4
    print(f"原始ADC值: {adc_value:4d} ")
    motor_dir.value(0)  
    for step in range(96*8):
        adc_value = adc.read_u16() >> 4
        adc_time=adc_value-2700
        if adc_time<0:
            time=1        
        #print(f"原始ADC值: {adc_value:4d} ")
        motor_step.value(1)  
        utime.sleep_us(adc_time*5)
        motor_step.value(0)  
        utime.sleep_us(adc_time*5)
     
    motor_en.value(1)
    utime.sleep(0.1)
    motor_en.value(0)
    motor_dir.value(1)

    for step in range(96*8):
        adc_value = adc.read_u16() >> 4
        adc_time=adc_value-2700
        if adc_time<0:
            time=1
        motor_step.value(1)  
        utime.sleep_us(adc_time*5)
        motor_step.value(0)  
        utime.sleep_us(adc_time*5)
        
    motor_en.value(1)
    utime.sleep(0.5)
    motor_en.value(0)

这里使用的电位器型号是HS-S28P,在这个项目中使用有点小问题,电位器供电是5V供电,量程是从0V~5V。在树莓派PICO上,使用3.3V供电,量程无法使用全量。所以在代码中对获取到的ADC值进行了处理。电机旋转采用顺时针旋转360度,然后暂停,再逆时针旋转360度。

c8a3b50e361832945f6a440f121eed11.jpg

adc_value = adc.read_u16() >> 4
        adc_time=adc_value-2700

上电,通过旋转电位器,就能够控制电机转速。电机在低转速时,转动的很平稳,也很安静,但是转速变高后,就开始有噪音了。

098ec2962f245b24b1c0cbf33675cb2b.jpg


然后想在这个项目的基础上,添加个按键处理,翻箱倒柜,找出个按键模块。给项目添加按键控制启停功能。按键连接在PICO的0、1脚上。红色按键代表急停,蓝色按键代表启动。

import machine
import utime
from machine import ADC

keyblue = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)   # 启动
keyred  = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_UP)   # 停止

adc = ADC(28)                          # GP28
motor_dir = machine.Pin(16, machine.Pin.OUT)
motor_step = machine.Pin(17, machine.Pin.OUT)
motor_en = machine.Pin(18, machine.Pin.OUT)

led = machine.Pin(25, machine.Pin.OUT)

motor_en.value(0)      # 默认使能
motor_dir.value(0)
motor_step.value(0)

running = False        # 电机运行状态

def stop_motor():
    global running
    running = False
    motor_en.value(1)      # 关电机
    motor_step.value(0)
    led.value(0)

def start_motor():
    global running
    running = True
    motor_en.value(0)      # 开电机
    led.value(1)

# ===== 主循环 =====
while True:

    # 蓝色按键:启动
    if keyblue.value() == 0:
        utime.sleep_ms(20)          # 消抖
        if keyblue.value() == 0:
            start_motor()
            while keyblue.value() == 0:  # 等待松手
                pass

    # 红色按键:停止
    if keyred.value() == 0:
        utime.sleep_ms(20)
        if keyred.value() == 0:
            stop_motor()
            while keyred.value() == 0:
                pass

    # 如果正在运行,执行电机动作
    if running:
        adc_value = adc.read_u16() >> 4
        adc_time = adc_value - 2700
        if adc_time < 0:
            adc_time = 1

        # 正转
        motor_dir.value(0)
        for _ in range(96 * 8):
            if not running:
                break
            motor_step.value(1)
            utime.sleep_us(adc_time * 5)
            motor_step.value(0)
            utime.sleep_us(adc_time * 5)

        if not running:
            continue

        utime.sleep(0.1)

        # 反转
        motor_dir.value(1)
        for _ in range(96 * 8):
            if not running:
                break
            motor_step.value(1)
            utime.sleep_us(adc_time * 5)
            motor_step.value(0)
            utime.sleep_us(adc_time * 5)

        utime.sleep(0.5)

    else:
        utime.sleep_ms(10)

因为电机使用的是20V电源,我是采用直接用鳄鱼夹去夹线的方式给电机上电,然后在实验过程中,在夹线上电一瞬间,火光四溅,板子就悲剧了。

7542114cb315046dd984dc26e6603765.jpg

image.png


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]