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 truefalse. 可选择反转伺服运动 false
center Boolean true or false. 可选择将伺服集中在初始化上 false
controller String 默认值,比如:PCA9685。 控制器接口类型。 DEFAULT
  • 调试配置
属性名称 数据类型 值/描述 默认值 是否必须
debug Boolean truefalse.将伺服设置为调试模式 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
2
new five.Servo(10); // 将伺服电机连接到引脚10

如果需要回正,设置如下:

1
2
3
4
5
new five.Servo({
pin: 10, // 将伺服电机连接到引脚10
center: true // 启动回正
});

如果需要将伺服电机设置在指定角度范围运动,设置如下:

1
2
3
4
5
new five.Servo({
pin: 10, // 将伺服电机连接到引脚10
range: [45, 135] // 运动角度范围
});

如果伺服电机启动后,运动到指定角度,设置如下:

1
2
3
4
5
new five.Servo({
pin: 10,
startAt: 120
});

如果伺服电机启动反,运动到指定范围,并在指定角度范围工作,设置如下:

1
2
3
4
5
6
new five.Servo({
pin: 10,
range: [45, 135],
startAt: 120
});

2)Continuous类型伺服电机初始化

1
2
new five.Servo.Continuous(10);

1
2
3
4
5
new five.Servo({
pin: 10,
type: "continuous"
});

如果伺服电机需要旋转固定圈数,设置如下:

1
2
3
4
5
new five.Servo({
pin: 10,
deviceRange: [0, 2160] // 旋转6圈 = 360 \* 6 = 2160 度
});

3)带有控制驱动器设备初始化

初始化标准伺服电机:

1
2
3
4
5
new five.Servo({
controller: "PCA9685",
pin: 0
});

初始化连续伺服电机:

1
2
3
4
5
new five.Servo.Continuous({
controller: "PCA9685",
pin: 0
});

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const { Board, Servo } = require("johnny-five");
const board = new Board({port:"COM1",repl:false});

board.on("ready", () => {
console.log('board inited')

let servo = new Servo({
pin:10, // 连接到10号引脚
// range:[0,360], // 设置旋转角度范围
// center:true, // 启动后回正
// type: "continuous" // 连续转动
//startAt:90 // 开始角度
})

// 从0-180循环
servo.sweep([0,180])

});

5、仿真结果

在这里插入图片描述

6、Servo对象常用API及事件

  • **to(degrees 0-180 [, ms [, rate]])**:将伺服电机移动到以度为单位的指定位置,0-180(或任何当前有效范围)。 如果指定 ms,伺服将花费该时间量移动到该位置。 如果指定了速率,则角度变化将被拆分为 ms 选项的距离/速率步长。 如果指定的角度与当前角度相同,则不发送命令。
1
2
3
4
5
6
7
8
9
10
11
var servo = new five.Servo(10);

// 运动到90°位置
servo.to(90);

//角度变化需要500ms才能完成
servo.to(90, 500);

//角度变化需要 500ms 才能完成超过 10 个步骤
servo.to(90, 500, 10);

  • **min()**:将伺服电机设置为最小度数。 默认为 0deg,或明确的范围。
1
2
3
4
5
6
var servo = new five.Servo(10);

// 运动到 0°位置
servo.min();


或者

1
2
3
4
5
6
7
8
var servo = new five.Servo({
pin: 10,
range: [ 45, 135 ]
});

// 运行到45°位置
servo.min();

  • **max()**:将伺服电机设置为最大度数。 默认为 180 度,或明确的范围。
1
2
3
4
5
var servo = new five.Servo(10);

// 运动到135°位置
servo.max();

或者:

1
2
3
4
5
6
7
8
var servo = new five.Servo({
pin: 10,
range: [ 45, 135 ]
});

// 运动到135°位置
servo.max();

  • center([ ms [, rate ]]) :将伺服电机回正。 默认为 90 度,或指定明确的范围。 如果指定 ms,伺服电机将花费该时间量移动到该位置。 如果指定了速率,则角度变化将被拆分为 ms 选项的距离/速率步长。 如果指定的角度与当前角度相同,则不发送命令。
1
2
3
4
5
var servo = new five.Servo(10);

// 默认运行到90°位置
servo.center();

或者:

1
2
3
4
5
6
7
8
var servo = new five.Servo({
pin: 10,
range: [ 40, 80 ]
});

// 运行到60°位置
servo.center();

  • home():将 Servo 设置为它的 startAt指定的位置。
1
2
3
4
5
6
7
8
9
10
11
var servo = new five.Servo({
pin: 10,
startAt: 20
});

// 运行到90°位置
servo.to(90);

// 返回到20°位置
servo.home();

  • **sweep()**:在默认最小值和最大值之间反复驱动伺服电机。
1
2
3
4
var servo = new five.Servo(10);

servo.sweep();

  • **sweep([ low, high ])**:反复在明确范围之间驱动伺服电机。
1
2
3
4
var servo = new five.Servo(10);

servo.sweep([45, 135]);

  • **sweep(options)**:在(可选)显式区间内(可选)显式范围和(可选)显式步骤(以度为单位)之间反复驱动伺服电机。

    • options:包含如下对象

      • range:一个包含 [low, high] 边界的数组。
      • interval:半扫的间隔(例如低 -> 高;全扫为低 -> 高 -> 低)
      • step:每一步的大小,以度为单位。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var 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
2
3
4
var servo = new five.Servo(10);

servo.stop();

  • **cw(speed)**:(仅对continuous类型伺服电机有效)以 0-1 的速度顺时针移动连续伺服
1
2
3
4
5
6
7
var servo = new five.Servo({
pin: 10,
type: "continuous"
});
// 全速伺服
servo.cw(1);

  • **ccw(speed)**:(仅对continuous类型伺服电机有效)以 0-1 的速度逆时针移动连续伺服
1
2
3
4
5
6
7
var servo = new five.Servo({
pin: 10,
type: "continuous"
});
// 全速伺服
servo.ccw(1);

Servo对象事件类型如下:

  • move:complete:当定时移动完成时发出。 除非将时间参数传递给servo.to() 方法,否则该事件不会触发。

文章来源: https://iotsmart.blog.csdn.net/article/details/125050798