40浏览
查看: 40|回复: 1

[讨论] Beetle 树莓派RP2350 - 步进电机驱动

[复制链接]
本帖最后由 无垠的广袤 于 2025-5-3 04:35 编辑

本文介绍了 DFRobot Beetle RP2350 开发板实现步进电机驱动的项目设计,主要包括旋转角度的精确控制、串口发送实现自定义角度旋转、OLED 显示旋转状态三部分。

项目介绍

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

步进电机原理

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

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


Beetle 树莓派RP2350 - 步进电机驱动图1

  • 结构组成

    • 定子:绕有线圈的磁极,分为多相(常见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 步,实际可能存在误差。


ULN2003 驱动器

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

Beetle 树莓派RP2350 - 步进电机驱动图2

原理图
Beetle 树莓派RP2350 - 步进电机驱动图3


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


项目方案

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

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

旋转指定角度

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

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

Beetle 树莓派RP2350 - 步进电机驱动图4


流程图


Beetle 树莓派RP2350 - 步进电机驱动图14

代码


  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. Ref: https://pico.nxez.com/2023/11/24 ... pberry-pi-pico.html
  13. '''
  14. from machine import Pin
  15. import utime
  16. # 电机控制引脚
  17. coils = [
  18.     Pin(0, Pin.OUT),  # A相 (IN1)
  19.     Pin(1, Pin.OUT),  # B相 (IN2)
  20.     Pin(18, Pin.OUT),  # C相 (IN3)
  21.     Pin(19, Pin.OUT)   # D相 (IN4)
  22. ]
  23. # 四相八拍步进电机的顺序值
  24. STEP_SEQ = [
  25.     [1, 0, 0, 1],  # AB'
  26.     [1, 0, 0, 0],  # A
  27.     [1, 1, 0, 0],  # AB
  28.     [0, 1, 0, 0],  # B
  29.     [0, 1, 1, 0],  # BC
  30.     [0, 0, 1, 0],  # C
  31.     [0, 0, 1, 1],  # CD
  32.     [0, 0, 0, 1]   # D
  33. ]
  34. '''
  35. 驱动电机旋转指定步数
  36. :param steps: 正数=顺时针,负数=逆时针
  37. :param delay_ms: 步间延时(ms),控制转速
  38. '''
  39. def step_motor(steps, delay_ms=1):
  40.     direction = 1 if steps >=0 else -1
  41.     for _ in range(abs(steps)):
  42.         for phase in range(8)[::direction]:  # 方向控制
  43.             for coil, state in zip(coils, STEP_SEQ[phase]):
  44.                 coil.value(state)
  45.             utime.sleep_ms(delay_ms)
  46. # 旋转角度控制
  47. def rotate_angle(angle):
  48.     steps_per_rev = 509
  49.     steps = int(angle * (steps_per_rev / 360))
  50.     step_motor(steps)
  51. # 释放电机扭矩
  52. def release():
  53.     for coil in coils:
  54.         coil.value(0)
  55. while True:
  56.     #rotate_angle(1) # 以单步方式持续转动
  57.     rotate_angle(180) # 逆时针
  58.     release()
  59.     utime.sleep_ms(2000)
  60.     rotate_angle(-90) # 顺时针
  61.     release()
  62.     utime.sleep_ms(2000)
复制代码




效果
Beetle 树莓派RP2350 - 步进电机驱动图5

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

Beetle 树莓派RP2350 - 步进电机驱动图13


串口自定义角度

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

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


Beetle 树莓派RP2350 - 步进电机驱动图6



流程图

Beetle 树莓派RP2350 - 步进电机驱动图15


代码



  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. from machine import Pin, UART
  16. import utime
  17. import ujson
  18. # 电机控制引脚
  19. coils = [
  20.     Pin(0, Pin.OUT),  # A相 (IN1)
  21.     Pin(1, Pin.OUT),  # B相 (IN2)
  22.     Pin(4, Pin.OUT),  # C相 (IN3)
  23.     Pin(5, Pin.OUT)   # D相 (IN4)
  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. # 驱动电机旋转指定步数;delay_ms 步间延时(ms),控制转速
  37. def step_motor(steps, delay_ms=1):
  38.     direction = 1 if steps >=0 else -1
  39.     for _ in range(abs(steps)):
  40.         for phase in range(8)[::direction]:  # 方向控制
  41.             for coil, state in zip(coils, STEP_SEQ[phase]):
  42.                 coil.value(state)
  43.             utime.sleep_ms(delay_ms)
  44. # 角度控制
  45. def rotate_angle(angle):
  46.     steps_per_rev = 509
  47.     steps = int(angle * (steps_per_rev / 360))
  48.     step_motor(steps)
  49. # 释放电机扭矩
  50. def release():
  51.     for coil in coils:
  52.         coil.value(0)
  53. # 串口控制旋转角度
  54. def uart_control():
  55.     uart = machine.UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9))
  56.     while True:
  57.         if uart.any():
  58.             cmd = uart.read()
  59.             try:
  60.                 data = ujson.loads(cmd)
  61.                 rotate_angle(int(data['angle']))
  62.                 release()
  63.             except:
  64.                 uart.write('Invalid command\r\n')
  65.                 release()
  66.         else:
  67.             release()
  68.         utime.sleep_ms(100)
  69. # main loop
  70. while True:
  71.     uart_control()
复制代码


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


效果

Beetle 树莓派RP2350 - 步进电机驱动图7

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

Beetle 树莓派RP2350 - 步进电机驱动图8

若串口发送 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)

Beetle 树莓派RP2350 - 步进电机驱动图9


流程图


Beetle 树莓派RP2350 - 步进电机驱动图16


代码



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




效果

Beetle 树莓派RP2350 - 步进电机驱动图10

动态

Beetle 树莓派RP2350 - 步进电机驱动图11


总结

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



----------- -------------
介绍了 Beetle RP2350 开发板驱动 WS2812B 实现流水灯的项目设计。

WS2812B 流水灯

使用 neopixel 库实现 WS2812B 驱动。

WS2812 简介

WS2812 是一款集成了控制电路和发光电路的智能外控 LED 光源,通常被称为 "NeoPixel"(由 Adafruit 推广)。采用单线通信协议,能够实现全彩控制,广泛应用于 LED 灯带、装饰照明、创意项目等领域。

特点
  • 集成驱动芯片

    • WS2812 将 RGB 三色 LED 和控制器集成在一个 5050 封装的芯片内,无需外部驱动电路。

  • 单线控制(单总线协议)

    • 仅需 1 根数据线 即可控制多颗 LED,通过特定的时序信号传递颜色和亮度信息,支持级联。

  • 24 位真彩色

    • 每个 LED 可独立设置 8 位(256 级)RGB 亮度,组合出约 1600 万种颜色。

  • 响应速度快

    • 数据传输速率可达 800Kbps,刷新频率 400Hz,适合动态灯光效果。

  • 低电压供电

    • 工作电压:3.3V–5V(推荐 5V),可直接由单片机驱动。

  • 级联能力

    • 多个 WS2812 可串联,理论上仅受限于信号传输速度和电源功率。


优势:仅需 1 个 I/O 即可实现彩色灯带效果。

代码

  1. '''
  2. Name: WS2812 flow light by using neopixel
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: include 3 effects: blink, flow lights and full-color running light.
  7. URL1: https://electrocredible.com/neop ... ry-pi-pico-ws2812b/
  8. URL2: https://blog.csdn.net/jiangge12/article/details/128857863
  9. '''
  10. import neopixel
  11. from machine import Pin
  12. import time
  13. ws_pin = 27
  14. led_num = 8
  15. BRIGHTNESS = 0.05  # Adjust the brightness (0.0 - 1.0)
  16. neoRing = neopixel.NeoPixel(Pin(ws_pin), led_num)
  17. # 定义亮度
  18. def set_brightness(color):
  19.     r, g, b = color
  20.     r = int(r * BRIGHTNESS)
  21.     g = int(g * BRIGHTNESS)
  22.     b = int(b * BRIGHTNESS)
  23.     return (r, g, b)
  24. # -------------------------------------
  25. # 流水灯函数
  26. def color_wipe(color, delay):
  27.     for i in range(led_num):
  28.         neoRing = set_brightness(color)  # 设置当前 LED 的颜色
  29.         neoRing.write()  # 更新 LED 状态
  30.         time.sleep(delay)  # 延时
  31.     for i in range(led_num):
  32.         neoRing = (0, 0, 0)  # 关闭当前 LED
  33.         neoRing.write()  # 更新 LED 状态
  34.         time.sleep(delay)  # 延时
  35. # 定义流水灯循环
  36. def loop_wipe():
  37.     color_wipe((255, 0, 0), 0.1)  # 红色流水灯
  38.     color_wipe((0, 255, 0), 0.1)  # 绿色流水灯
  39.     color_wipe((0, 0, 255), 0.1)  # 蓝色流水灯
  40. # -------------------------------------
  41. # 连续流水灯函数
  42. def color_continue(color, delay):
  43.     for i in range(led_num):
  44.         neoRing = set_brightness(color)  # 设置当前 LED 的颜色
  45.         neoRing.write()  # 更新 LED 状态
  46.         time.sleep(delay)  # 延时
  47. # 定义连续流水灯循环
  48. def loop_continue():
  49.     color_continue((255, 0, 0), 0.1)  # 红色流水灯
  50.     color_continue((0, 255, 0), 0.1)  # 绿色流水灯
  51.     color_continue((0, 0, 255), 0.1)  # 蓝色流水灯
  52. # -------------------------------------
  53. # 定义闪灯循环
  54. def loop():
  55.     # Display red
  56.     color = (255, 0, 0)  # Red color
  57.     color = set_brightness(color)
  58.     neoRing.fill(color)
  59.     neoRing.write()
  60.     time.sleep(0.5)
  61.     # Display green
  62.     color = (0, 255, 0)  # Green color
  63.     color = set_brightness(color)
  64.     neoRing.fill(color)
  65.     neoRing.write()
  66.     time.sleep(0.5)
  67.     # Display blue
  68.     color = (0, 0, 255)  # Blue color
  69.     color = set_brightness(color)
  70.     neoRing.fill(color)
  71.     neoRing.write()
  72.     time.sleep(0.5)
  73. while True:
  74.     #loop()
  75.     #loop_wipe()
  76.     loop_continue()
复制代码



效果

RGB 三色流动点亮
Beetle 树莓派RP2350 - 步进电机驱动图12



全彩 RGB 流水灯设计,为后续项目增加美观的背景,突显赛博朋克风格。



无垠的广袤  初级技师
 楼主|

发表于 10 小时前

后续将增加LabVIEW控制上位机,通过发送串口指令精确控制步进电机旋转角度,将整个系统封装起来,更有利于实际应用。
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail