Arduino与JavaScript开发实例舵机驱动
Arduino与JavaScript开发实例-舵机驱动
舵机驱动
伺服电机是一种独立的电气设备,它以高效率和高精度旋转机器的部件。
伺服机构(伺服)可以指代很多不同的机器,这些机器的使用时间比大多数人可能意识到的要长。 从本质上讲,伺服系统是任何内置反馈元件的电机驱动系统。伺服系统随处可见,从重型机械到车辆的动力转向,再到机器人技术和各种电子产品。
伺服电机一般由三个核心部件组成:直流电机、控制器电路和电位器或类似的反馈机制。 直流电机连接到齿轮箱和输出/驱动轴以增加电机的速度和扭矩。 直流电机驱动输出轴。 控制器电路解释控制器发送的信号,电位器作为控制器电路的反馈,以监测输出轴的位置。 几乎所有的爱好伺服器都有一个标准的三针、0.1 英寸间隔的连接器来为伺服器供电和控制。 不同品牌的颜色编码可能有所不同,但引脚几乎普遍采用相同的顺序。 组合在一起时,只需三根电线即可驱动和控制输出轴的方向、速度和位置。

为了将伺服器沿其运动弧线移动到某个位置,或者在连续旋转伺服器的情况下电机的速度和方向,控制器需要发送一个精确定时的信号供伺服器解释。 典型的爱好伺服器希望每 20 毫秒看到一个脉冲,该信号的宽度决定了位置。 这个宽度通常在一到两毫秒之间。 这种类型的信号控制通常被称为脉冲宽度调制,缩写为 PWM。 伺服控制器通常是一个专用硬件,可以从其他组件(如操纵杆、电位计或传感器反馈)获取输入,以设置伺服的控制信号。 其他控制选项包括使用微控制器上支持 PWM 的引脚将该信号直接发送到伺服系统。
常见的伺服电机如下:

Johnny-Five库提供了伺服电机驱动封装:Servo。本次实例将演示如何控制伺服电机。
1、Servo对象
Servo 类构造表示连接到物理板上的单个 Servo 的对象。 此类旨在与标准和连续旋转伺服系统更好地配合使用。
Servo类的构建参数如下:
- pin:伺服器所连接的引脚
- 通用配置
| 属性名称 | 数据类型 | 值/描述 | 默认值 | 是否必须 |
|---|---|---|---|---|
| pin | Number, String | 伺服器所连接的引脚 | 是 | |
| range | Array | [ lower, upper ]以度为单位的运动范围 |
[0, 180] |
否 |
| pwmRange | Array | [ min, max ] 以微秒为单位的脉冲宽度范围 |
[600, 2400] |
否 |
| deviceRange | Array | [ min, max ] 伺服的物理范围,以度为单位。 |
[0, 180] |
否 |
| type | String | “standard”, “continuous”. 创建的伺服类型 |
“standard” |
否 |
| startAt | Number | 设备范围内的任何数字。 初始化伺服的度数 | 否 | |
| offset | Number | 调整伺服的正值或负值 | false |
否 |
| invert | Boolean | true 或 false. 可选择反转伺服运动 |
false |
否 |
| center | Boolean | true or false. 可选择将伺服集中在初始化上 |
false |
否 |
| controller | String | 默认值,比如:PCA9685。 控制器接口类型。 | DEFAULT | 否 |
- 调试配置
| 属性名称 | 数据类型 | 值/描述 | 默认值 | 是否必须 |
|---|---|---|---|---|
| debug | Boolean | true或false.将伺服设置为调试模式 |
false |
no |
- 连续伺服选项
| 属性名称 | 数据类型 | 值/描述 | 默认值 | 是否必须 |
|---|---|---|---|---|
| deadband | Array | [ lower, upper ]. 伺服的死区/停止点 |
[90, 90] |
no |
注意:一些连续伺服系统没有微调停止点的微调器,而是有一个内置的“死区”范围,应该记录在案,否则需要手动测量。
- PCA9685配置
| 属性名称 | 数据类型 | 值/描述 | 默认值 | 是否必须 |
|---|---|---|---|---|
| address | Number | I2C设备地址 | 0x40 |
yes |
Servo对象属性如下:
| 属性名称 | 描述 | 是否只读 |
|---|---|---|
id |
用户可定义的 id 值。 默认为生成的 uid | No |
pin |
伺服连接到的引脚 | No |
range |
以度为单位的运动范围。 默认为 [0, 180] | No |
invert |
布尔值,指示伺服值是否反转 | No |
history |
包含每个动作记录的数组 | No |
interval |
对当前间隔的引用(如果存在) | No |
isMoving |
一个布尔标志,移动时为真,静止时为假 | No |
last |
最后的移动记录 | Yes |
position |
伺服系统在物理世界中的角度 | Yes |
value |
伺服器上次设置的角度 | No |
startAt |
初始化时指定伺服启动的角度 | No |
Servo设备初始化如下:
1)标准Servo初始化
1 | new five.Servo(10); // 将伺服电机连接到引脚10 |
如果需要回正,设置如下:
1 | new five.Servo({ |
如果需要将伺服电机设置在指定角度范围运动,设置如下:
1 | new five.Servo({ |
如果伺服电机启动后,运动到指定角度,设置如下:
1 | new five.Servo({ |
如果伺服电机启动反,运动到指定范围,并在指定角度范围工作,设置如下:
1 | new five.Servo({ |
2)Continuous类型伺服电机初始化
1 | new five.Servo.Continuous(10); |
1 | new five.Servo({ |
如果伺服电机需要旋转固定圈数,设置如下:
1 | new five.Servo({ |
3)带有控制驱动器设备初始化
初始化标准伺服电机:
1 | new five.Servo({ |
初始化连续伺服电机:
1 | new five.Servo.Continuous({ |
2、硬件准备
- Arduino Mega2560开发板一块
- Max7219 Led点阵一个(8x8)
- 杜邦线若干
- 数据线一条
仿真电路图如下:

3、软件准备
- VS Code IDE
- Arduino IDE
- NodeJs(本次使用的版本为v16.13.0)
- Visual Studio 2019
- Proteus 8.13 SP0
前面的文章已经对Arduino与JavaScript开发环境已经做了详细描述,请参考:Arduino与JavaScript开发实例-开发环境搭建
4、代码实现
1 | const { Board, Servo } = require("johnny-five"); |
5、仿真结果

6、Servo对象常用API及事件
- **to(degrees 0-180 [, ms [, rate]])**:将伺服电机移动到以度为单位的指定位置,0-180(或任何当前有效范围)。 如果指定 ms,伺服将花费该时间量移动到该位置。 如果指定了速率,则角度变化将被拆分为 ms 选项的距离/速率步长。 如果指定的角度与当前角度相同,则不发送命令。
1 | var servo = new five.Servo(10); |
- **min()**:将伺服电机设置为最小度数。 默认为 0deg,或明确的范围。
1 | var servo = new five.Servo(10); |
或者
1 | var servo = new five.Servo({ |
- **max()**:将伺服电机设置为最大度数。 默认为 180 度,或明确的范围。
1 | var servo = new five.Servo(10); |
或者:
1 | var servo = new five.Servo({ |
- center([ ms [, rate ]]) :将伺服电机回正。 默认为 90 度,或指定明确的范围。 如果指定 ms,伺服电机将花费该时间量移动到该位置。 如果指定了速率,则角度变化将被拆分为 ms 选项的距离/速率步长。 如果指定的角度与当前角度相同,则不发送命令。
1 | var servo = new five.Servo(10); |
或者:
1 | var servo = new five.Servo({ |
- home():将 Servo 设置为它的 startAt指定的位置。
1 | var servo = new five.Servo({ |
- **sweep()**:在默认最小值和最大值之间反复驱动伺服电机。
1 | var servo = new five.Servo(10); |
- **sweep([ low, high ])**:反复在明确范围之间驱动伺服电机。
1 | var servo = new five.Servo(10); |
**sweep(options)**:在(可选)显式区间内(可选)显式范围和(可选)显式步骤(以度为单位)之间反复驱动伺服电机。
options:包含如下对象
- range:一个包含 [low, high] 边界的数组。
- interval:半扫的间隔(例如低 -> 高;全扫为低 -> 高 -> 低)
- step:每一步的大小,以度为单位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var servo = new five.Servo(10);
servo.sweep({
range: [45, 135]
});
servo.sweep({
range: [45, 135],
interval: 1000,
});
servo.sweep({
range: [45, 135],
interval: 1000,
step: 10
});**stop()**:伺服电机停止工作
1 | var servo = new five.Servo(10); |
- **cw(speed)**:(仅对continuous类型伺服电机有效)以 0-1 的速度顺时针移动连续伺服
1 | var servo = new five.Servo({ |
- **ccw(speed)**:(仅对continuous类型伺服电机有效)以 0-1 的速度逆时针移动连续伺服
1 | var servo = new five.Servo({ |
Servo对象事件类型如下:
- move:complete:当定时移动完成时发出。 除非将时间参数传递给servo.to() 方法,否则该事件不会触发。
文章来源: https://iotsmart.blog.csdn.net/article/details/125050798