找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1846|回复: 0
打印 上一主题 下一主题
收起左侧

树莓派RP2350实现步进电机精确控制

[复制链接]
跳转到指定楼层
楼主
本文介绍了 树莓派 RP2350 开发板实现步进电机驱动的项目设计,主要包括旋转角度的精确控制、串口发送实现自定义角度旋转、OLED 显示旋转状态三部分。

扩展板PCB工程详见:Beetle-RP2350扩展板 - 立创开源硬件平台oshwhubcom/lijinlei0907/beetle-rp2350-expansion-board

项目介绍

包括步进电机原理、该项目使用的 28BYJ-48 步进电机,及其驱动器——ULN2003 驱动模块介绍。

步进电机原理

步进电机(Stepper Motor)是一种将电脉冲信号转换为精确角度位移的执行器件,属于开环控制电机。

核心特点:每接收一个脉冲,转子就转动一个固定的角度(称为“步距角”),无需反馈传感器即可实现位置控制。



  • 结构组成

    • 定子:绕有线圈的磁极,分为多相(常见2相、4相、5相)。
    • 转子:永磁体(永磁式)或齿状铁芯(反应式/混合式)。
    • 定子绕组按特定顺序通电,产生旋转磁场,吸引转子逐步转动。

  • 工作过程

    • 通过控制器(如单片机)发送脉冲信号,驱动电路按顺序切换定子绕组的电流方向。
    • 每切换一次,转子转动一个步距角,连续脉冲使电机连续旋转。


28BYJ-48 步进电机

28BYJ-48 是一款常见的低成本、小扭矩 5 线单极步进电机,可使用 ULN2003 控制器和单片机实现旋转控制,广泛用于打印机、扫描仪、摄像机云台、空调、家电、玩具、消费电子等领域。




参数
值/描述
电机类型
单极 4 相永磁式步进电机(5线制)
步距角
5.625°(64 步/圈),配合减速齿轮后 0.0879°(实际输出轴 4096 步/圈)
减速比
1:64(内部齿轮组减速)
额定电压
5V 或 12V DC
相电流
约 100mA(每相)
保持扭矩
约 0.1 N·m(输出轴,受减速齿轮影响)
绕组电阻
约 50Ω/相


实际输出轴步距角为 5.625°/64 ≈ 0.0879°,转一圈理论上需要 64×64=4096 步,实际可能存在误差。

详见: 28BYJ-48 数据手册.pdf (193.2 KB, 下载次数: 0)

ULN2003 驱动器

ULN2003 是一款常用的达林顿晶体管阵列芯片,专为驱动高电流负载(如继电器、步进电机、LED阵列等)设计。其作用是将 MCU 输出的弱电流信号转换为大电流输出,是控制 28BYJ-48 步进电机的核心驱动芯片。



原理图



使用时需要将 28BYJ-48 步进电机的5线快接插头与 ULN2003 模块对应接口连接,并将模块的 4 个控制引脚(信号输入端,丝印 IN1、IN2、IN3、IN4)与单片机对应引脚相连,实现控制信号输入。

详见: uln2003a.pdf (2.04 MB, 下载次数: 0)

项目方案

具体执行方案和工程测试流程如下

  • 步进电机原理
  • 旋转角度的精确控制
  • 串口发送实现自定义角度旋转
  • OLED 显示旋转状态

旋转指定角度

本节介绍并实现了指定角度的步进电机旋转控制。

硬件连接
  • GP0 ---- IN1 (ULN2003)
  • GP1 ---- IN2 (ULN2003)
  • GP18 ---- IN3 (ULN2003)
  • GP19 ---- IN4 (ULN2003)






代码


  1. '''
  2. Name: Stepper Motor driven by ULN2003
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: Rotate stepper motor (28byj-48) for custom angle.
  7. Hardware connect:
  8. 0 ---- IN1 (ULN2003)
  9. 1 ---- IN2 (ULN2003)
  10. 18 ---- IN3 (ULN2003)
  11. 19 ---- IN4 (ULN2003)
  12. '''
  13. ​
  14. from machine import Pin
  15. import utime
  16. ​
  17. # 电机控制引脚
  18. coils = [
  19.     Pin(0, Pin.OUT),  # A相 (IN1)
  20.     Pin(1, Pin.OUT),  # B相 (IN2)
  21.     Pin(18, Pin.OUT),  # C相 (IN3)
  22.     Pin(19, Pin.OUT)   # D相 (IN4)
  23. ]
  24. ​
  25. # 四相八拍步进电机的顺序值
  26. STEP_SEQ = [
  27.     [1, 0, 0, 1],  # AB'
  28.     [1, 0, 0, 0],  # A
  29.     [1, 1, 0, 0],  # AB
  30.     [0, 1, 0, 0],  # B
  31.     [0, 1, 1, 0],  # BC
  32.     [0, 0, 1, 0],  # C
  33.     [0, 0, 1, 1],  # CD
  34.     [0, 0, 0, 1]   # D
  35. ]
  36. ​
  37. '''
  38. 驱动电机旋转指定步数
  39. :param steps: 正数=顺时针,负数=逆时针
  40. :param delay_ms: 步间延时(ms),控制转速
  41. '''
  42. def step_motor(steps, delay_ms=1):
  43.     direction = 1 if steps >=0 else -1
  44.     for _ in range(abs(steps)):
  45.         for phase in range(8)[::direction]:  # 方向控制
  46.             for coil, state in zip(coils, STEP_SEQ[phase]):
  47.                 coil.value(state)
  48.             utime.sleep_ms(delay_ms)
  49. ​
  50. # 旋转角度控制
  51. def rotate_angle(angle):
  52.     steps_per_rev = 509
  53.     steps = int(angle * (steps_per_rev / 360))
  54.     step_motor(steps)
  55. ​
  56. # 释放电机扭矩
  57. def release():
  58.     for coil in coils:
  59.         coil.value(0)
  60. ​
  61. while True:
  62.     #rotate_angle(1) # 以单步方式持续转动
  63.     rotate_angle(180) # 逆时针
  64.     release()
  65.     utime.sleep_ms(2000)
  66.     rotate_angle(-90) # 顺时针
  67.     release()
  68.     utime.sleep_ms(2000)
复制代码




效果



由供电处的电压-电流计量工具可知,步进电机旋转工作时的功率约为 1W



串口自定义角度

在实现步进电机旋转驱动的基础上,进一步实现串口发送自定义角度并旋转的功能设计方案。

硬件连接
  • GP0 ---- IN1 (ULN2003)
  • GP1 ---- IN2 (ULN2003)
  • GP4 ---- IN3 (ULN2003)
  • GP5 ---- IN4 (ULN2003)
  • GP8 ---- RXD (CH340)
  • GP9 ---- TXD (CH340)





​

代码



  1. '''
  2. Name: Stepper Motor rotate custom angle from serial
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: Rotate stepper motor (28byj-48) for custom angle from UART.
  7. Hardware connect:
  8. 0 ---- IN1 (ULN2003)
  9. 1 ---- IN2 (ULN2003)
  10. 4 ---- IN3 (ULN2003)
  11. 5 ---- IN4 (ULN2003)
  12. 8 ---- RXD (CH340)
  13. 9 ---- TXD (CH340)
  14. '''
  15. ​
  16. from machine import Pin, UART
  17. import utime
  18. import ujson
  19. ​
  20. # 电机控制引脚
  21. coils = [
  22.     Pin(0, Pin.OUT),  # A相 (IN1)
  23.     Pin(1, Pin.OUT),  # B相 (IN2)
  24.     Pin(4, Pin.OUT),  # C相 (IN3)
  25.     Pin(5, Pin.OUT)   # D相 (IN4)
  26. ]
  27. ​
  28. # 四相八拍步进电机的相序
  29. STEP_SEQ = [
  30.     [1, 0, 0, 1],  # AB'
  31.     [1, 0, 0, 0],  # A
  32.     [1, 1, 0, 0],  # AB
  33.     [0, 1, 0, 0],  # B
  34.     [0, 1, 1, 0],  # BC
  35.     [0, 0, 1, 0],  # C
  36.     [0, 0, 1, 1],  # CD
  37.     [0, 0, 0, 1]   # D
  38. ]
  39. ​
  40. # 驱动电机旋转指定步数;delay_ms 步间延时(ms),控制转速
  41. def step_motor(steps, delay_ms=1):
  42.     direction = 1 if steps >=0 else -1
  43.     for _ in range(abs(steps)):
  44.         for phase in range(8)[::direction]:  # 方向控制
  45.             for coil, state in zip(coils, STEP_SEQ[phase]):
  46.                 coil.value(state)
  47.             utime.sleep_ms(delay_ms)
  48. ​
  49. # 角度控制
  50. def rotate_angle(angle):
  51.     steps_per_rev = 509
  52.     steps = int(angle * (steps_per_rev / 360))
  53.     step_motor(steps)
  54. ​
  55. # 释放电机扭矩
  56. def release():
  57.     for coil in coils:
  58.         coil.value(0)
  59. ​
  60. # 串口控制旋转角度
  61. def uart_control():
  62.     uart = machine.UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9))
  63.     while True:
  64.         if uart.any():
  65.             cmd = uart.read()
  66.             try:
  67.                 data = ujson.loads(cmd)
  68.                 rotate_angle(int(data['angle']))
  69.                 release()
  70.             except:
  71.                 uart.write('Invalid command\r\n')
  72.                 release()
  73.         else:
  74.             release()
  75.         utime.sleep_ms(100)
  76. ​
  77. # main loop
  78. while True:
  79.     uart_control()
复制代码


这里为了节能并提高效率,仅在串口发送正确指令时旋转,其他情况均释放步进电机扭矩,此时电流约为 0 .


效果



由于调用了 ujson 库,因此串口发送指令需符合 json 格式,如 {"angle":40} .

若串口发送 json 消息的格式错误,则反馈指令无效的提示。

OLED 显示旋转状态

在前面实现步进电机旋转驱动、串口自定义角度控制的基础上,进一步实现串口发送角度、旋转、OLED 状态显示的功能设计方案。

硬件连接

  • GP0 ---- IN1 (ULN2003)
  • GP1 ---- IN2 (ULN2003)
  • GP18 ---- IN3 (ULN2003)
  • GP19 ---- IN4 (ULN2003)
  • GP8 ---- RXD (CH340)
  • GP9 ---- TXD (CH340)
  • GP4 ---- SDA (OLED_SSD1306)
  • GP5 ---- SCL (OLED_SSD1306)




流程图





代码



  1. '''
  2. Name: Stepper Motor rotate custom angle from serial and OLED display
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: Rotate stepper motor (28byj-48) for custom angle from UART, and OLED display the motor state in moving or steady.
  7. Hardware connect:
  8. 0 ---- IN1 (ULN2003)
  9. 1 ---- IN2 (ULN2003)
  10. 18 ---- IN3 (ULN2003)
  11. 19 ---- IN4 (ULN2003)
  12. 8 ---- RXD (CH340)
  13. 9 ---- TXD (CH340)
  14. 4 ---- SDA (OLED_SSD1306)
  15. 5 ---- SCL (OLED_SSD1306)
  16. Serial send style: {"angle": 40}
  17. '''
  18. ​
  19. from machine import Pin, UART, SoftI2C
  20. import ssd1306 # OLED
  21. import ujson # read uart string
  22. import utime
  23. ​
  24. # ==== Initialized IIC OLED ====
  25. i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
  26. oled_width = 128
  27. oled_height = 64
  28. oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
  29. ​
  30. # display the motor state
  31. def display_motor(angle,state):
  32.     oled.fill(0)  # 清屏
  33.     oled.text("Rotate Angle: ", 0, 0)
  34.     oled.text("{:.1f} deg".format(angle), 20, 15)
  35.     oled.text("State: ", 0, 35)
  36.     if state == 1:
  37.         oled.text("Rotating ...", 20, 50)
  38.     elif state == 0:
  39.         oled.text("Reset", 20, 50)
  40.     else:
  41.         oled.text("Error", 20, 50)
  42.     oled.show()
  43. ​
  44. # 电机控制引脚
  45. coils = [
  46.     Pin(0, Pin.OUT),  # A相 (IN1)
  47.     Pin(1, Pin.OUT),  # B相 (IN2)
  48.     Pin(18, Pin.OUT),  # C相 (IN3)
  49.     Pin(19, Pin.OUT)   # D相 (IN4)
  50. ]
  51. ​
  52. # 四相八拍步进电机的相序
  53. STEP_SEQ = [
  54.     [1, 0, 0, 1],  # AB'
  55.     [1, 0, 0, 0],  # A
  56.     [1, 1, 0, 0],  # AB
  57.     [0, 1, 0, 0],  # B
  58.     [0, 1, 1, 0],  # BC
  59.     [0, 0, 1, 0],  # C
  60.     [0, 0, 1, 1],  # CD
  61.     [0, 0, 0, 1]   # D
  62. ]
  63. ​
  64. # 驱动电机旋转指定步数;delay_ms 步间延时(ms),控制转速
  65. def step_motor(steps, delay_ms=1):
  66.     direction = 1 if steps >=0 else -1
  67.     for _ in range(abs(steps)):
  68.         for phase in range(8)[::direction]:  # 方向控制
  69.             for coil, state in zip(coils, STEP_SEQ[phase]):
  70.                 coil.value(state)
  71.             utime.sleep_ms(delay_ms)
  72. ​
  73. # 角度控制
  74. def rotate_angle(angle):
  75.     steps_per_rev = 509  # 64步/拍 × 8拍 × 8相位
  76.     steps = int(angle * (steps_per_rev / 360))
  77.     step_motor(steps)
  78. ​
  79. # 释放电机扭矩
  80. def release():
  81.     for coil in coils:
  82.         coil.value(0)
  83. ​
  84. # 串口控制旋转角度
  85. def uart_control():
  86.     uart = machine.UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9))
  87.     while True:
  88.         if uart.any():
  89.             cmd = uart.read()
  90.             try:
  91.                 data = ujson.loads(cmd)
  92.                 ra = float(data['angle']) # rotate angle
  93.                 display_motor(ra,1)
  94.                 rotate_angle(ra)
  95.                 release()
  96.                 display_motor(ra,0)
  97.             except:
  98.                 uart.write('Invalid command\r\n')
  99.                 release()
  100.         else:
  101.             release()
  102.             #display_motor(0,0)
  103.         utime.sleep_ms(100)
  104. ​
  105. # main loop
  106. display_motor(0,0) # initialize OLED display
  107. while True:
  108.     uart_control()
复制代码


效果







总结

本文介绍了树莓派 RP2350 开发板实现步进电机驱动的项目设计,包括旋转角度的精确控制、串口发送实现自定义角度旋转、OLED 显示旋转状态等,为 RP2350 的开发、设计和应用提供了参考。



评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶顶 踩踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表