手把手教你用 MicroPython 玩转幻尔串口舵机,代码+教程全公开

原文链接:

FreakStudio的博客

摘要

MicroPython串口舵机库,支持幻尔科技全系列舵机,支持mpremote工具一键导入,28条指令全测试。

往期推荐:

学嵌入式的你,还不会面向对象??!

全网最适合入门的面向对象编程教程:00 面向对象设计方法导论

全网最适合入门的面向对象编程教程:01 面向对象编程的基本概念

全网最适合入门的面向对象编程教程:02 类和对象的 Python 实现-使用 Python 创建类

全网最适合入门的面向对象编程教程:03 类和对象的 Python 实现-为自定义类添加属性

全网最适合入门的面向对象编程教程:04 类和对象的Python实现-为自定义类添加方法

全网最适合入门的面向对象编程教程:05 类和对象的Python实现-PyCharm代码标签

全网最适合入门的面向对象编程教程:06 类和对象的Python实现-自定义类的数据封装

全网最适合入门的面向对象编程教程:07 类和对象的Python实现-类型注解

全网最适合入门的面向对象编程教程:08 类和对象的Python实现-@property装饰器

全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系

全网最适合入门的面向对象编程教程:10 类和对象的Python实现-类的继承和里氏替换原则

全网最适合入门的面向对象编程教程:11 类和对象的Python实现-子类调用父类方法

全网最适合入门的面向对象编程教程:12 类和对象的Python实现-Python使用logging模块输出程序运行日志

全网最适合入门的面向对象编程教程:13 类和对象的Python实现-可视化阅读代码神器Sourcetrail的安装使用

全网最适合入门的面向对象编程教程:全网最适合入门的面向对象编程教程:14 类和对象的Python实现-类的静态方法和类方法

全网最适合入门的面向对象编程教程:15 类和对象的 Python 实现-__slots__魔法方法

全网最适合入门的面向对象编程教程:16 类和对象的Python实现-多态、方法重写与开闭原则

全网最适合入门的面向对象编程教程:17 类和对象的Python实现-鸭子类型与“file-like object“

全网最适合入门的面向对象编程教程:18 类和对象的Python实现-多重继承与PyQtGraph串口数据绘制曲线图

全网最适合入门的面向对象编程教程:19 类和对象的 Python 实现-使用 PyCharm 自动生成文件注释和函数注释

全网最适合入门的面向对象编程教程:20 类和对象的Python实现-组合关系的实现与CSV文件保存

全网最适合入门的面向对象编程教程:21 类和对象的Python实现-多文件的组织:模块module和包package

全网最适合入门的面向对象编程教程:22 类和对象的Python实现-异常和语法错误

全网最适合入门的面向对象编程教程:23 类和对象的Python实现-抛出异常

全网最适合入门的面向对象编程教程:24 类和对象的Python实现-异常的捕获与处理

全网最适合入门的面向对象编程教程:25 类和对象的Python实现-Python判断输入数据类型

全网最适合入门的面向对象编程教程:26 类和对象的Python实现-上下文管理器和with语句

全网最适合入门的面向对象编程教程:27 类和对象的Python实现-Python中异常层级与自定义异常类的实现

全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规范大汇总

全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用

全网最适合入门的面向对象编程教程:30 Python的内置数据类型-object根类

全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type

全网最适合入门的面向对象编程教程:32 Python的内置数据类型-类Class和实例Instance

全网最适合入门的面向对象编程教程:33 Python的内置数据类型-对象Object和类型Type的关系

全网最适合入门的面向对象编程教程:34 Python的内置数据类型-Python常用复合数据类型:元组和命名元组

全网最适合入门的面向对象编程教程:35 Python的内置数据类型-文档字符串和__doc__属性

全网最适合入门的面向对象编程教程:36 Python的内置数据类型-字典

全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式

全网最适合入门的面向对象编程教程:38 Python常用复合数据类型-使用列表实现堆栈、队列和双端队列

全网最适合入门的面向对象编程教程:39 Python常用复合数据类型-集合

全网最适合入门的面向对象编程教程:40 Python常用复合数据类型-枚举和enum模块的使用

全网最适合入门的面向对象编程教程:41 Python常用复合数据类型-队列(FIFO、LIFO、优先级队列、双端队列和环形队列)

全网最适合入门的面向对象编程教程:42 Python常用复合数据类型-collections容器数据类型

全网最适合入门的面向对象编程教程:43 Python常用复合数据类型-扩展内置数据类型

全网最适合入门的面向对象编程教程:44 Python内置函数与魔法方法-重写内置类型的魔法方法

全网最适合入门的面向对象编程教程:45 Python实现常见数据结构-链表、树、哈希表、图和堆

全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架

全网最适合入门的面向对象编程教程:47 Python函数方法与接口-回调函数Callback

全网最适合入门的面向对象编程教程:48 Python函数方法与接口-位置参数、默认参数、可变参数和关键字参数

全网最适合入门的面向对象编程教程:49 Python函数方法与接口-函数与方法的区别和lamda匿名函数

全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类

全网最适合入门的面向对象编程教程:51 Python函数方法与接口-使用Zope实现接口

全网最适合入门的面向对象编程教程:52 Python函数方法与接口-Protocol协议与接口

全网最适合入门的面向对象编程教程:53 Python字符串与序列化-字符串与字符编码

全网最适合入门的面向对象编程教程:54 Python字符串与序列化-字符串格式化与format方法

全网最适合入门的面向对象编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串

全网最适合入门的面向对象编程教程:56 Python字符串与序列化-正则表达式和re模块应用

全网最适合入门的面向对象编程教程:57 Python字符串与序列化-序列化与反序列化

全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现

全网最适合入门的面向对象编程教程:59 Python并行与并发-并行与并发和线程与进程

更多精彩内容可看:

给你的 Python 加加速:一文速通 Python 并行计算

一文搞懂 CM3 单片机调试原理

肝了半个月,嵌入式技术栈大汇总出炉

电子计算机类比赛的“武林秘籍”

一个MicroPython的开源项目集锦:awesome-micropython,包含各个方面的Micropython工具库

Avnet ZUBoard 1CG开发板—深度学习新选择

工程师不要迷信开源代码,还要注重基本功

什么?配色个性化的电机驱动模块?!!

什么?XIAO主控新出三款扩展板!

1.原先库存在的问题

image

这里,我们看厂家提供的MicroPython库中代码:

image
image

实际上,并没有很好的实现功能解耦和充分利用Python面向对象的特性。
可以看到,多个方法中间存在重复的收发逻辑:
image
同时,UART 波特率(115200)、超时时间(50ms)等硬编码在代码中,而非可配置:
image
并且,无 API 文档和示例代码,不利于用户快速上手,也缺乏必要的入口参数校验机制,如判断舵机ID、角度范围、速度范围是否合理:
image

因此,我决定自己写一个MicroPython版本的幻尔科技串口舵机库。
仓库地址为:
Freak嵌入式-MicroPython串口舵机库

我也将其发布到了PyPi上(虽然不适合发布到上面,只是方便后期讲解Python发布第三方库):
Freak嵌入式-MicroPython串口舵机库-PyPi
image

2.serial_servo库介绍

2.1 简介与主要特性

通过串口舵机库,用户可以控制多个舵机的角度、速度等参数,实现高效、灵活的舵机控制,程序中使用了串口通讯与舵机进行数据交互,提供了完整的控制命令和反馈解析功能。

推荐大家使用我们的串口舵机扩展板,感谢支持:
Freak嵌入式-多米诺系列-串口舵机驱动板
主要特性包括:

  • 使用UART串口与舵机通信,支持多舵机控制。
  • 支持舵机的角度、速度、工作模式等多种设置。
  • 支持舵机温度、电压、角度等实时读取。
  • 校验和机制确保数据传输的完整性,幻尔科技串口舵机28条指令全部实现,并且封装为类。
  • 完整的异常捕获机制,对入口参数进行详细检查。
  • 注释完善,所有方法和类均提供了类型注解。

该类封装了舵机控制相关的所有功能,包括生成和发送控制指令、接收舵机反馈、读取舵机状态等。
UART_SERVO_Class

  • __init__(self, uart: UART) -> None:初始化串口舵机控制类。
  • calculate_checksum(data: list[int]) -> int:计算校验和,确保数据的完整性和正确性。
  • build_packet(servo_id: int, cmd: int, params: list[int]) -> bytearray:构建舵机控制指令包。
  • send_command(servo_id: int, cmd: int, params: list[int] = []) -> None:发送控制指令到指定舵机。
  • receive_command(expected_cmd: int, expected_data_len: int) -> list:接收并解析舵机返回的指令数据包。
  • move_servo_immediate(servo_id: int, angle: float, time_ms: int) -> None:立即控制舵机转动到指定角度。
  • get_servo_move_immediate(servo_id: int) -> tuple:获取舵机的预设角度和时间。
  • move_servo_with_time_delay(servo_id: int, angle: float, time_ms: int) -> None:控制舵机延迟转动到指定角度。
  • get_servo_move_with_time_delay(servo_id: int) -> tuple:获取舵机的延迟转动角度和时间。
  • start_servo(servo_id: int) -> None:启动舵机的转动。
  • stop_servo(servo_id: int) -> None:立即停止舵机转动并停在当前角度位置。
  • set_servo_id(servo_id: int, new_id: int) -> None:设置舵机的新 ID 值。
  • get_servo_id(servo_id: int) -> int:获取舵机的 ID。
  • set_servo_angle_offset(servo_id: int, angle: float, save_to_memory: bool = False) -> None:根据角度值调整舵机的偏差。
  • get_servo_angle_offset(servo_id: int) -> float:获取舵机的偏差角度。
  • set_servo_angle_range(servo_id: int, min_angle: float, max_angle: float) -> None:设置舵机的最小和最大角度限制。
  • get_servo_angle_range(servo_id: int) -> tuple:获取舵机的角度限位。
  • set_servo_vin_range(servo_id: int, min_vin: float, max_vin: float) -> None:设置舵机的最小和最大输入电压限制。
  • get_servo_vin_range(servo_id: int) -> tuple:获取舵机的电压限制值。
  • set_servo_temp_range(servo_id: int, max_temp: int) -> None:设置舵机的最高温度限制。
  • get_servo_temp_range(servo_id: int) -> int:获取舵机的内部最高温度限制值。
  • read_servo_temp(servo_id: int) -> int:获取舵机的实时温度。
  • read_servo_voltage(servo_id: int) -> float:获取舵机的实时输入电压。
  • read_servo_pos(servo_id: int) -> float:获取舵机的实时角度位置。
  • set_servo_mode_and_speed(servo_id: int, mode: int, speed: int) -> None:设置舵机的工作模式和电机转速。
  • get_servo_mode_and_speed(servo_id: int) -> tuple:获取舵机的工作模式和转动速度。
  • set_servo_motor_load(servo_id: int, unload: bool) -> None:设置舵机的电机是否卸载掉电。
  • get_servo_motor_load_status(servo_id: int) -> bool:获取舵机电机是否装载或卸载。
  • set_servo_led(servo_id: int, led_on: bool) -> None:设置舵机的 LED 灯的亮灭状态。
  • get_servo_led(servo_id: int) -> bool:获取舵机 LED 的亮灭状态。
  • set_servo_led_alarm(servo_id: int, alarm_code: int) -> None:设置舵机 LED 闪烁报警对应的故障值。
  • get_servo_led_alarm(servo_id: int) -> int:获取舵机 LED 故障报警状态。

2.2 核心方法介绍

该类的核心是通过 UART(串口通信)与舵机通信。类中的常量定义包括了多种控制命令和舵机相关的设置。这些常量包括了指令的编号、参数长度和返回数据长度。例如:

  • SERVO_MOVE_TIME_WRITESERVO_MOVE_TIME_READ 是与舵机位置控制相关的指令及其参数格式。
  • SERVO_ID_WRITESERVO_ID_READ 是与舵机ID相关的读写指令。

这些常量帮助类在进行通信时,能确保发送正确的指令和正确解析返回的数据。

READ_COMMANDS 集合定义了所有读取命令的编号,这些命令对应舵机的数据读取请求,例如,读取舵机的实时电压、角度、温度等信息。
这个集合便于在 receive_command() 方法中判断接收到的数据是否为期望的读取命令。

串口舵机类的核心方法为:

  • 构建数据包方法 build_packet:该方法用于构建舵机控制的指令包,指令包由以下部分组成:
    • 帧头:固定为 0x55, 0x55
    • 舵机ID:唯一标识每个舵机
    • 数据长度:包括指令和参数
    • 指令编号:具体的控制指令
    • 参数:控制指令的参数
    • 校验和:用于校验数据包的完整性

build_packet

  • 发送指令方法 send_command:该方法构建指令包并通过 UART 发送给舵机,它调用了build_packet()来构造数据包,
    并通过self.uart.write()发送数据。

send_command

  • 接收指令方法 receive_commandreceive_command() 方法用于接收来自舵机的反馈数据,此方法的工作过程如下:
    1. 命令验证:确认接收到的是读取命令,而不是其他类型的命令。
    2. 数据检查:检查数据的帧头是否正确,命令编号是否匹配,数据长度是否符合预期。
    3. 校验和验证:验证接收到的数据包的校验和是否正确,确保数据未被篡改。
    4. 数据解析:根据返回的数据长度,解析并返回舵机的状态或数据(例如电压、角度等)。
    5. 如果数据包无效(如校验和错误、数据长度不符等),该方法将返回空列表。

receive_command

SerialServo 类的设计通过封装舵机控制指令和数据包的构建逻辑,简化了舵机通信过程,核心思路是通过统一的数据包格式和校验机制确保指令的正确传输,
结合 UART 通信接口实现与舵机的高效交互。类内指令常量和参数处理使得操作更加清晰易懂,
同时通过校验和和数据长度的验证确保数据的完整性和可靠性。

3.如何使用

3.1 安装依赖

在运行示例程序之前,确保你的环境中安装了machinetime等模块。你可以通过MicroPython的包管理器安装依赖。

您可以使用如下语句和 mpremote 工具安装该库:

mpremote mip install https://github.com/leezisheng/freakstudio-micropython-libraries/tree/main/serial_servo

或者(推荐):

mpremote mip install github:leezisheng/freakstudio-micropython-libraries/serial_servo

安装进行中会显示:

(base) PS D:\lee\windows terminal\terminal-1.17.11461.0> mpremote mip install github:leezisheng/freakstudio-micropython-libraries/serial_servo
Install github:leezisheng/freakstudio-micropython-libraries/serial_servo
Installing github:leezisheng/freakstudio-micropython-libraries/serial_servo/package.json to /lib
Installing: /lib/serial_servo/__init__.py
Installing: /lib/serial_servo/serial_servo.py
Installing micropython-machine (latest) from https://micropython.org/pi/v2 to /lib
Package may be partially installed
mpremote: Package not found: https://micropython.org/pi/v2/package/6/micropython-machine/latest.json

安装完成后,通过mpremote工具,连接你的开发板,如果成功安装,会显示如下信息:

(base) PS D:\lee\windows terminal\terminal-1.17.11461.0> mpremote connect COM8
Connected to MicroPython at COM8
Use Ctrl-] or Ctrl-x to exit this shell>>> import os
>>> os.listdir()
['lib']
>>> from serial_servo import SerialServo
>>>

如果通过 mpremote 安装失败,您可以选择手动安装库,即选择 Download ZIP,然后解压文件。

  1. 将该程序文件保存为 serial_servo.py
  2. 确保使用的主控板通过舵机驱动扩展板已连接好舵机和串口,接线供电无异常。
  3. 在MicroPython环境中,通过import serial_servo导入该模块。

3.2 使用示例

在使用前,我们需要注意:

  • 硬件连接:确保舵机的电源和控制线正确连接
  • 串口通信参数设置:串口通信的波特率必须与舵机的波特率匹配,为115200,数据位为8,无校验位,停止位为1。
  • 响应等待:每次发送指令后,最好等待舵机响应,避免指令丢失。

你可以像下面这样,去调用串口舵机控制类中方法控制舵机或者读取其状态:

from machine import Pin, UART
from serial_servo import SerialServo# 配置UART串口
uart = UART(1, baudrate=115200, tx=Pin(4), rx=Pin(5))# 初始化串口舵机控制类
servo = SerialServo(uart)# 控制舵机转到指定角度
servo.move_servo_immediate(servo_id=1, angle=90.0, time_ms=1000)# 获取舵机的角度和时间设置
angle, time = servo.get_servo_move_immediate(servo_id=1)
print(f"Servo ID: 1, Angle: {angle}, Time: {time}")

下面是实测的相关图片:
image
image
image
image

如有任何问题或需要帮助,请通过 10696531183@qq.com 联系开发者。

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/890942.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Plombery:将Python脚本的执行与Web界面的可视化监控完美结合的Python任务调度工具

还在为定时运行Python脚本而苦恼吗?还在为复杂的调度系统而头疼吗?今天,就让Plombery帮你解决这些问题!Plombery是一个简单易用的Python任务调度器,拥有友好的Web界面和REST API,让你轻松管理和监控你的Python脚本。告别复杂的配置和代码,Plombery将带你进入高效、便捷的…

AQS的acquire(int arg) 方法底层源码

一、定义 acquire(int arg) 是 AQS(AbstractQueuedSynchronizer)中的一个核心方法,用于在独占模式下获取同步状态。如果当前线程无法获取同步状态,则将其加入等待队列并阻塞,直到成功获取同步状态或被中断 1、acquire(int arg) 方法的作用功能:尝试获取同步状态(独占模式…

【钓鱼邮件】春节复工近期常见的钓鱼邮件

本期主要分享2025年2月常见的钓鱼邮件样本,特别提醒广大用户在春节复工高峰期加强安全防范。 补贴类钓鱼邮件 春节之后,五险一金补贴、年终奖补贴相关的钓鱼邮件依旧频发。钓鱼手法也有所提升,攻击者通常将通知内容放到附件中,并且对附件设置访问密码,试图绕过反垃圾系统检…

HTTP协议与RESTful API实战手册(终章):构建企业级API的九大秘籍

title: HTTP协议与RESTful API实战手册(终章):构建企业级API的九大秘籍 🔐 date: 2025/2/28 updated: 2025/2/28 author: cmdragon excerpt: 🏭 本文作为系列终章,通过物流管理系统的案例,揭秘API开发的完整流程。你将掌握: 深度解读28个HTTP协议进阶特性(ETag/CO…

第一周实验:二次开发

来源 来自大一舍友C++大作业。该项目模拟了一个图书管理系统,涉及到用户对于书籍的查看、借阅与归还,管理员对于书籍相关信息的增删改查。 运行环境+运行结果的截图 运行环境:Windows 11 + Visual Studio 2022main.cpp #include<Windows.h> #include "Account.h&…

学习笔记之day02 Linux-基础篇-系统安装

​1、操作系统简介操作系统:人与计算机硬件交互的中介Linux:内核+Shell +扩展软件Windows:内核+explorer.exe+软件类比法:计算机硬件 -- 内核 == 蛋黄 / Shell == 蛋清 / 外围应用程序 == 蛋壳常见的操作系统:Windows、Linux、DOS、UnixLinux操作系统开放源代码、可以自由…

绝缘电阻测试仪科普

什么是绝缘电阻绝缘电阻是指两个绝缘介质间的电阻,当另一端安装有电压源时,绝缘介质内电荷不能流动,因而受电压源作用,在另一端产生电势差,形成电阻抵消电压势差而不致使电荷漏出。一般情况下,绝缘电阻越大,电气设备的安全性就越好,缺陷率也越低。 为什么测量绝缘电阻绝…

【CodeForces训练记录】Educational Codeforces Round 175 (Rated for Div. 2)

训练情况赛后反思 CD连续卡题,D题树上层序遍历+加法原理,鉴定为基本的图论数据结构没学好 A题 直接打表,对于 i%3 = i%5 的情况,我们发现有三个一组,三个一组连续的数,每组第一个数之间差 15,所以我们 / 15 * 3 先把整组的数量算出来,再求是组内第几个,就能得到答案了…

软工五问

这个作业属于哪个课程 课程链接这个作业要求在哪里 作业要求这个作业的目标 学习使用markdown, 接触GitHub, 建立个人博客个人介绍 📋标签 广东湛江 人 期望成为 golang后端工程师 学习经历持续学习golang及其框架, 设计模式 持续学习后端各个组件的可靠高效解决方案兴趣爱好…

清华大学推出的5册免费的 DeepSeek 学习使用指南!

前言 在当今这个信息洪流、技术飞速迭代的时代,DeepSeek的横空出世极大地降低了普通人利用人工智能技术的门槛。然而,尽管机遇就在眼前,仍有不少朋友面对DeepSeek感到无从下手,不知如何利用它来紧握时代赋予的红利。对此,清华大学展现出了高度的社会责任感与前瞻性,推出了…

拆解分析行业头部米家绿米燃气报警器怎么样?

小米绿米天然气卫士拆解,内置Zigbee模组,需要连接Zigbee 3.0网关 或者 具备Zigbee 3.0网关功能的设备报警 天然气是每家每户日常生活中都会使用到的清洁能源,因此对于天然气的安全防护时刻不能放松。小米天然气卫士是小米与业内知名品牌 赛特威尔 联手打造的一款产品,可探测…

C++ DLL 供 C# AnyCPU 调用 【 OpenCV onnxruntime】

背景 C++ 打包的DLL用到 OpenCV,用到 onnxruntime C# 软件需要打包成Any CPU版本,即可以在 x86下使用,也可以在x64下使用 C# 前端想把 C++ dll与依赖放在单独的”Libs“文件夹中,不是"Dubug"下 难点: 在C++ 中, OpenCV 和 onnxruntime 分别有x64和x86两个版本,…