分类目录归档:机器人小组

关于步进电机的一切

什么是步进电机?

components_IMG_4838.jpg

步进电机是以不连续的步进移动的直流电机。 他们有多个线圈组织在称为“相”的组里。通过依次给每相励磁,电机将旋转, 每次一步。

通过计算机控制的步进,可以实现非常精确的定位和/或速度控制。因此,步进电机是许多精密运动控制应用的首选电机。

步进电机有许多不同的尺寸和样式和电气特性。 本指南详细说明你应该如何选择正确的电机。

4相单极电机

维基共享资源

步进电机的优点

▪  可用于定位场合 – 由于步进机以精确的可重复步骤移动,它们在卓越应用中需要精确定位,如3D打印机,CNC,相机平台和X,Y 绘图仪。一些磁盘驱动器还使用步进电机来定位读/写头。

▪ 精确的速度控制 – 精确的移动增量也允许对过程自动化和机器人的旋转速度进行出色的控制。

▪低速时能保持大扭矩 – 正常的直流电机在低速时不具有很大的扭矩。一个步进电机在低速时具有最大转矩,因此它们是一个对于需要低速度,高精度应用不错的选择。

components_IMG_4796_crop.jpg

步进电机的局限性

▪ 低效率 – 与直流电机不同,步进电机电流消耗独立于负载。.当他们空载时,他们得到的电流最多。正因如此,它们常常运行发热。

▪ 有限的高速扭矩 -一般来说,步进电机在高速时比低速具有较小的转矩 。一些步进器被优化以获得更好的高速性能 ,是它们需要与适当的驱动程序配对以实现该性能 。

▪ 没有反馈 – 与伺服电机不同,大多数步进器没有积分反馈位置。虽然可以实现运行“开环”的高精度。限位开关或通常为了安全和/或建立参考位置需要“本部”检测器。

步进电机类型

有各种各样的步进电机类型,其中一些需要非常专业的驱动程序。为了我们的目的,我们将重点介绍可用普通驱动器驱动的步进电机。它们是:永磁式或混合式步进电机,两相双极或四相单极

components_IMG_4810_crop.jpg

电机尺寸

首先要考虑的事情之一是电机必须做的工作。正如你所期望的,更大电机能够提供更多的功率。步进电机的尺寸范围从比花生较小到大如NEMA 57的怪物。

大多数电机具有额定转矩。这是你需要看看决定电机是否有足够的力矩做你想要的。

NEMA 17是用于3D打印机和小型数控铣床的常用尺寸。更小的电机找到应用于许多仿生机械上。较大的NEMA框架在CNC机床和工业应用中是常见的。

NEMA数字定义了用于安装电机的标准面板尺寸。他们不定义电机的其他特性。两个不同的NEMA 17电机可能有完全不同的电气或机械规格,并且不一定可互换。

components_IMG_4799.jpg

步骤计数

接下来要考虑的是您需要的定位分辨率。每步的步数转速范围为4至400。常用的步数为24,48和200。

分辨率通常表示为每步的度数。 1.8°电机与200步/转电机相同。

高分辨率的牺牲是速度和扭矩。高步进电机比相同尺寸下的RPM低于最大值。与这些类似尺寸的低速计数电机相比,转动这些电机所需的更高的步进速度导致更低的转矩。

components_IMG_4797.jpg

齿轮

实现高定位分辨率的另一种方法是使用齿轮传动。 一个32:1齿轮系应用于 8步/转电机的输出将产生512步电机。

齿轮系还将增加电动机的扭矩。 一些微小的齿轮步进器是能够产生令人印象深刻的扭矩。 但是权衡当然是速度。 齿轮式步进电机通常受到限制去低转速应用。

components_1253-01.jpg

轴样式

另一个要考虑的是如何电机将与驱动系统的其余部分接口。电机有多种轴类型

▪圆形或“D”轴:这些有多种标准直径,还有许多滑轮,齿轮和轴耦合器来配合设计。 “D”轴有一个扁平侧以帮助防止滑动。当涉及运用高扭矩时,这些轴形是我们能用到的

▪齿轮轴:一些轴具有磨入其中的齿轮齿。这些通常设计成与模块化齿轮系匹配丝杠轴

▪丝杠轴: 带有丝杠轴的电机用于构建直线执行器。这些的微型版本可以在许多磁盘驱动器中作为磁头定位器。

components_IMG_4814.jpg

接线

步进电机接线有许多变化。为了我们的目的,我们将专注于可以使用常用驱动程序驱动的步进器。这些是连接为2相双极或4相单极的永磁或混合步进电机。

components_IMG_4837.jpg

线圈和相位

步进电机可以具有任何数量的线圈。但是这些被以称为“相”的组连接。一相中的所有线圈被一起激发。

components_winding_types_2.png

单极与双极

单极 驱动器,总是以相同的方式给相位通电。 一个领导,“共同”领导,将总是负数。 另一个引线将始终为正。 可以实现单极驱动器 与简单的晶体管电路。 缺点是只有较低的扭矩 可以一次对一半线圈通电。

双极 驱动器使用H桥电路实际上反转通过相的电流。通过使极性交替地对相进行通电,可以使所有线圈工作以转动电动机

电机具有2组线圈。 4相单极电机具有4.两相双极电机将具有4个电线 – 每相2个。一些电机带有灵活的接线,允许您将电机作为双极或单极运行。

5-Wire Motor

This style is common in smaller unipolar motors. All of the common coil wires are tied together internally abd brought out as a 5th wire. This motor can only be driven as a unipolar motor.

6-Wire Motor

This motor only joins the common wires of 2 paired phases. These two wires can be joined to create a 5-wire unipolar motor.

Or you just can ignore them and treat it like a bipolar motor!

8-Wire Motor

The 8-wire unipolar is the most versatile motor of all. It can be driven in several ways:

  • 4-phase unipolar – All the common wires are connected together – just like a 5-wire motor.
  • 2-phase series bipolar – The phases are connected in series – just like a 6-wire motor.
  • 2-phase parallel bipolar– The phases are connected in parallel. This results in half the resistance and inductance – but requires twice the current to drive. The advantage of this wiring is higher torque and top speed.

components_IMG_4796_crop.jpg

 

驱动步进电机

Step in time, step in time
Come on, mateys, step in time
Step in time
Step in time, step in time
Step in time, step in time
Never need a reason, never need a rhyme
We step in time, we step in time

“Step In Time”
Robert B. Sherman and Richard M. Sherman

components_IMG_4805.jpg

驱动步进电机比驱动普通有刷直流电机复杂一些。步进电机需要步进控制器以及时地对相进行通电以使电机转向

components_IMG_4817_cropped.jpg

简单单极驱动器

最简单的驱动器类型可以用少量晶体管构建。 这些按顺序简单地接通和断开,以使相位通电并使电动机步机进。 单极驱动器的构建相对便宜,但只能使用单极电机。 在Arduino官网有一个很好的教程教你如何使用。

components_H-Bridge.jpg

简单的双H桥驱动器

驱动双极电机需要两个完整的H桥,因此它可以反转到相的电流。H桥可能很难从头开始构建。但是有很多H桥芯片可以简化任务。

L293D是最受欢迎和最经济的芯片之一。这些可以在大多数第一代Motor Shield的核心中发现,包括令人难以置信的流行的V1 Adafruit Motor Shield。

在Adafruit学习中有一个关于使用裸L293D和Arduino系统的优秀教程:

components_1438-00.jpg

Adafruit Motor Shield V2

Adafruit Motor Shield V2是基于L293D的基本控制器的一大进步。 V2 shield u使用两个TB6612 MOSFET驱动器 。与L293D相比,TB6612提供两倍的电流容量和更低的电压下降,来更有效地驱动你的步进电机。

有2个驱动器芯片和4个完整的H桥,每个shield可以驱动多达两个步进电机。驱动器芯片通过专用的PWM驱动器芯片与I2C接口连接。 这释放了很多 的GPIO引脚用于其他用途,并使屏蔽层也可堆叠。你最多可以叠加32个用2个IO引脚来控制64个电机!

此驱动程序的完整细节可以在学习系统中找到。

components_IMG_4840_crop.jpg

高级CNC控制器

gShield和TinyG CNC控制器板使您更接近工业级步进器的性能。这些电路板具有恒流“斩波器”驱动器,可以调节,来为电机提供最大的扭矩和速度。

TinyG CNC具有板载G代码解释器和4个电机输出,使其成为适用于中小型4轴CNC机床的完整嵌入式解决方案。

正如您所期望的,这些高级的高性能主板比较复杂,适合有经验的用户使用。

这些板及其操作的详细信息可以在TinyG WikiSynthetos Forums中找到。

 

选择合适的驱动代码驱动步进电机

components_IMG_4842_crop.jpg

现在我们来到最重要的部分:确保您的电机和驱动程序兼容。

不匹配的电机和驱动器可能会导致令人失望的性能。 或更糟:损坏电机和/或控制器。

如果你的选择不明智,你可能会遇到这个家伙:

components_691-00.jpg

了解驱动程序规格

驱动程序规范中的两个最重要的参数是:

▪ 电压 – 驱动器可以提供给电机的最大电压。

▪ 持续电流 – 驱动器可以提供给电机的最大电流。

额定的“峰值”电流不适用于步进电机。 始终遵循“持续”电流的额定值。

了解电机规格

您还需要知道电机的电气规格。 有2个关键参数:

▪ 每相的电流 – 这是电机绕组可以处理而不过热的最大电流。

▪ 每相电阻 – 这是每相的电阻

A通常表示额定电压。它通常从上面的两个参数计算,但不总是。 最好根据上述参数使用欧姆定律计算它。

components_Ohm.png

遵守定律!

步进电机的相是电感器,因此它们会抵抗电流的快速变化。 但是在每个步骤结束时或者当电机不运动时,它们表现得像纯电阻负载,并且会遵守欧姆定律.。

静止也就是步进电机吸收最大电流时。 所以欧姆定律可以让我们使用电机规格来计算驱动器的电流要求。

电压=电流x电阻

或者

电流=电压/电阻

这些公式应严格应用于所有“恒压”步进控制器。 这包括来自Adafruit的V1和V2 Motor Shields,以及几乎所有其它基于L293D的控制器。

但是一些电机具有非常低的线圈电阻。严格遵循这些公式,驱动电压将小于5v,性能会不好。这种类型的电机与恒压驱动器不匹配。这些步进器需要更专门的控制器。

违背定律?

这不可能违背欧姆定律。如果你尝试,你将必须被回答蓝烟怪物。 然而,这里还有一些其他规律在起作用。 洛伦兹,法拉第和欧姆定律的专业知识可以帮助您提高电机的性能。

步进线圈在被通电时产生磁场。 根据法拉第定律,变化的磁场在线圈中感应出电流。 根据洛伦兹定律,该电流将在产生电场的电流的相反方向上。 该反向电流被称为“反向电动势”或“反向电动势”。

这个反电动势增加了线圈的“阻抗”或有效电阻。 所以欧姆定律仍然适用 – 但这是对这个阻抗,而不是简单的相电阻。 该阻抗限制每个步骤开始时流过线圈的电流。

components_IMG_4840.jpg

斩波传动

斩波器“恒定电流”驱动通过以更高的电压驱动电机来补偿反电动势。 使用斩波器驱动几倍步进电机的额定电压的是不寻常的。

为了在这些较高的电压下保持安全,斩波器驱动器还监测输送到电动机的电流,并在它超过预设电平之前“斩断”它。

通过在更高的电压处开始,斩波器驱动器能够在步骤开始时向线圈输送更多的电流,增加可用转矩。 除了以较慢的速度增加扭矩之外,它还允许更高的最高速度。

选择斩波器驱动器并为特定电机配置它需要很好地了解电机和控制器。

常问问题

这个电机能和我的shield一起工作吗?

您需要知道电机规格以及控制器规格。 获取该信息后,请检查“将驱动程序与步进器匹配”页面,查看它们是否兼容。

这是一个NEMA 17,所以它应该工作,对吧?

NEMA框架尺寸标准仅定义安装面板的尺寸。 要确定它是否兼容,您需要知道电机的电气规格。

如果没有电机规格怎么办?

参见Jason的反向工程步进电机电线引脚。 这将告诉你相电阻。 对于相电流,您可以基于类似设计的电机和类似的相电阻进行估计。

当有疑问时,一般最好安全地使用较低的电流!

我的项目需要什么尺寸的电机?

大多数电机具有扭矩规格 – 通常为英寸/盎司或牛顿/厘米。 一英寸/盎司意味着电动机可以从轴的中心在一英寸处施加一盎司的力。 例如,它可以使用2“直径滑轮保持1盎司。

在计算项目所需的扭矩时,请确保允许加速所需和克服摩擦的额外扭矩。 将质量块从静止位置提升所需的扭矩要比将其简单地拿着更大。

.如果你的项目需要大扭矩和不高速度,考虑一个齿轮步进。

如何将我的电机连接到Motor Shield?

对于从Adafruit购买的电机,产品说明中列出了接线说明。

对于其他电机,如果可以,请检查电机规格表。

如果你没有规格表,检查Jason反向工程步进电机电线引脚

这个电源可以与我的电机工作吗?

首先确保它不超过电机或控制器的额定电压。通常可以在较低的电压下运行电机,但是你将获得较小的扭矩。

接下来,检查电流额定值。大多数步进模式一次为两相通电,因此电流额定值应至少为电机每相电流的两倍。

*这适用于恒压驱动器。 对于斩波驱动控制器,请检查控制器的说明。

components_IMG_4810_crop.jpg

资源

网上有很多优秀的有关步进电机的信息。 这里有一些我们最喜欢的链接:

Wikipedia Stepper Motor Page

RepRap Stepper Motor Page

Jones on Stepper Motors

Jason on reverse engineering the stepper wire pinouts

components_IMG_4838.jpg

 

 


本文由翻译美国开源硬件厂商Adafruit(阿达水果公司)的相关教程翻译,原始教程由Bill Earl编写,为便于理解和方便读者学习使用,我们已去函与原作者沟通关于本教程翻译中文并发布的相关使用权限,部分内容为适应国内使用场景稍有删改或整合,以上翻译内容仅用于学习交流分享,不得用于盈利等商业用途。

原始文章及相关素材链接:

https://learn.adafruit.com/all-about-stepper-motors/what-is-a-stepper-motor

	

简版Fritz表情机器人安装

欢迎购买简易版开源表情机器人Fritz套件,如果您看完本教程后对此制作感兴趣,可以考虑从下述淘宝网址购买我们提供的配套套件:

http://t.cn/R5IhT1s(由新浪提供的短链接,点击后跳转到淘宝)

安装简介

为了降低安装难度,本款去掉了眼球和脖子的动作,需要的可选用高配版。

可以参考

需要的工具:

  1. 热胶枪
  2. 螺丝刀
  3. 电脑
  4. 耐心

安装木板部分

所有的舵机需要先转到最中间的位置!!!

安装底座

连接处需要热熔胶固定

1

P51202-191313

安装下巴

用舵机里面带的螺丝固定舵机和木板

左侧的铜柱起固定作用

2

P51202-192031

安装脸

此处用的是短螺丝和铜柱。

要把3D打印的眼皮和铁丝安装在一起。

3

P51202-192909

P51202-192925

安装后脑

4

P51202-193038

P51202-193050

总组装

此处要把舵机和舵盘连上

5

QQ图片20151203131630

连接电路

Arduino固定上,连接电机的连线,插上USB

F0A0B846-A22C-44C8-B7A1-D025FF5BE3EE 02

装配完成!

烧录Arduino程序

打开Arduino软件,没装过Arduino的可以在下述网址中下载并找到运行程序

http://pan.baidu.com/s/1gfCuNGf

03

文件 -> 打开,找到》》》》》

双击 Fritz.ino

04

在工具菜单项里设置 板 为 Arduino Uno,串口选中。

05

点击 上传

06

成功!

配置电脑控制程序

可以在下述网址中下载并找到运行程序

http://pan.baidu.com/s/1gfCuNGf

打开fritz.exe,等待连接成功

07

打开 set motor

08

全打勾,

09

拖动一下眼眉,看看是不是能控制啦!

10

恭喜你!大功告成!

步进电机基础知识与Arduino控制

步进电机是将脉冲信号转换成机械运动的一种特殊电机。步进电机在使用时不需要额外的反馈,这是因为除非失步,否则步进电机每次转动时的角度已知的,由于它的角度位置已知就能精确控制电机运动的位置。一般我们会用Arduino驱动的小型步进电机有以下两种。

steper01steper02

步进电机内部实际上产生了一个可以旋转的磁场,如图所示,当旋转磁场依次切换时,转子(rotor)就会随之转动相应的角度。当磁场旋转过快或者转子上所带负载的转动惯量太大时,转子无法跟上步伐,就会造成失步。

 steper03steper04

从步进电机的矩频特性图上可知,步进电机以越快的速度运行,所能输出的转矩越小,否则将会造成失步。每种不同规格的步进电机都有类似的矩频特性曲线,详细图表需要查阅其规格书。

steper05

图 矩频特性

步进电机的磁极数量规格和接线规格很多,为简化问题,我们这里就先只以四相步进电机为例进行讨论。所谓四相,就是说电机内部有4对磁极,此外还有一个公共端(COM)接电源, ABCD是四线的接头。而四相电机的可以向外引出六条接线(两条COM共同接入Vcc),即GNDABCD,也可以引出五条线,如图所示,所以有成为六线四相制和五线四相制。

steper06

                                    六线四相制                                              五线四相制

下表中1表示高电平、0表示低电平,我们以下述最简单的一相励磁方式来驱动步进电机

steper07

这种方式,电机在每个瞬间只有一个线圈导通,消耗电力小但在切换瞬间没有任何的电磁作用转子上,容易造成振动,也容易因为惯性而失步。

二相励磁方式

这种方式输出的转矩较大且振动较少,切换过程中至少有一个线圈通电作用于转子,使得输出的转矩较大,振动较小,也比一相励磁较为平稳,不易失步。

steper08

步进角是步进电机每前进一个步序所转过的角度。在不超载也不失步的情况下,给电机加上一个脉冲信号,它就转过一个步距角。这一简单的线性关系,使得步进电机速度和位置的控制变得十分简单。

综合上述两种驱动信号,下面提出一相励磁和二相励磁交替进行的方式,没传送一个励磁信号,步进电机前进半个步距角。其特点是分辨率高,运转更加平滑。

二相励磁方式

steper09

下面是这三种驱动方式的时序波形图

steper10

驱动问题

不要天真的以为可以直接将Arduino的端口和ABCD分别相连,因为Arduino的数字I/O口最大只能通过约40mA的电流。因此,我们想到了使用晶体管进行放大。常用的方法有三种:

steper11

  1. 直接利用晶体管来驱动,这需要你对电机和晶体管的详细参数有一定了解,才能选择恰当的参数去匹配他们。此外,还必须使用二极管来处理当电机内部线圈产生感应电动势逆向流入晶体管而对晶体管造成损害。

  1. 使用诸如ULN2003ULN2803这样的激励器,它实际是内部集成好了放大功能的集成电路芯片,此外也无需额外添加二极管,因为它已经内置了。

  2. 使用光耦,在驱动芯片或者晶体管的前端再加入光耦合器,以加强隔离步进电机的反电动势,以免损害Arduino

steper12

 

  1. 使用L293D这样的H桥的方式来驱动步进电机,详细请参考上两节介绍的L293 Motor Sheild官网的说明。

steper13steper14

我们以ULN2003为例,现有的驱动板可以用来驱动步进电机,我们只需要选择Arduino的四个输出端口用杜邦线分别连接驱动板的IN1IN2IN3IN4,再用外置电源连接驱动板的5-12V+接口,并把电源和Arduino的地(GND)与驱动板的()共线即可。

steper15

steper16

ULN2003采用的是达林顿管(Darlington transistor)方式来增强对大电流负载(如步进电机)的驱动,所谓达林顿管其实就是二级放大的三极管而已(如右图所示),经过恰当的三极管型号选择匹配后,两次放大的三极管驱动能力比一个三极管更强。详情请参考ULN2003DataSheet。但无论哪种方式,记住,使用额外的外接电源来驱动晶体管和集成芯片,它才是电机的真正的能量提供者。

关于实际的步距角

前面所讲述的其实是一个简化模型,真正的步进电机步距角比较小。因为采用了图所示的多齿结构,这种结构类似于游标卡尺的工作原理,所以实际4相步进电机的步距角并非360°/8 = 45°。根据其规格书,本节范例所用的步进电机的步距角是5.625°,如果采用一二相励磁方式,则可以达到其一半的分辨率。

steper17

如果图所示仍然令你感到困惑,可以查看下面这个网址所示的动画。

www.pengky.cn/cizudj/bujin-DDJ2/bujinDDJ-DH.flv

/* 
 步进电机速度控制示例
 
本示例程序用于驱动非极性步进电机。
电机的接口连接至Arduino的8至11号端口
变阻器连接至模拟端口A0

电机将沿着顺时针方向旋转,电位器的模拟量越高,步进电机的转速就越快。
因为setSpeed()函数将设定每一步序的时间间隔。你可能会发现当电位器模拟量太低时,电机将会停止旋转。
*/

#include <Stepper.h>

const int stepsPerRevolution = 200;

Stepper myStepper(stepsPerRevolution, 8,9,10,11);            

int stepCount = 0;

void setup()
{
}

void loop()
{
  int sensorReading = analogRead(A0);
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  if (motorSpeed > 0)
{
    myStepper.setSpeed(motorSpeed);
    myStepper.step(stepsPerRevolution/100);
  } 
}

关于精确驱动大功率步进电机的原理,请参考

http://www.szleadtech.com.cn/jishu/article_det.aspx?Id=6

steper18steper19

上图所示类型是一般功率较大的步进电机,在爱好者自制的3D打印机如RapRepCNC系统中常常见到,驱动他们最好使用专用的驱动模块,如图所示。

选用电机及其控制系统需要适当的权衡。例如,不要将步进电机用于高速应用,也不要将直流电机用于低速高转矩场合。步进电机已经具备了半闭环反馈,所以直接应用即可,而直流电机则适用于高速带传动等,如需要更大的转矩,则需要如齿轮等机构来转换,当然如果你想精确的控制直流电机,也可以在其中添加编码器,然后用微控制器去检测电动机的精确位置和速度。而将减速增转矩以及精确位置反馈的功能集合到一起的装置,就是下一节介绍的伺服电机(舵机)。

Arduino控制的机械臂

有同学说我这个机械臂很像挖掘机,好吧,考不上蓝翔的同学们看过来!

【点击此处下载机械臂结构的CAD图】可以直接发图给淘宝的店家加工,这里默认亚克力板的厚度为2.4mm。

工具:1、热熔胶枪;2、电烙铁;3、螺丝刀套件

材料:

Arduino UNO                                       x 1

旋转式电位器                                       x 4

自锁开关                                                x 1

MG995舵机                                           x 4

SG90舵机                                              x 1

5-9V电源                                                 —

一些线材                                                 —

需要用到的标准件有:M4*10螺栓18个,M4螺母18个,M2*6圆头带垫自攻螺丝。M4螺母和螺栓可用【膨胀塑料卡扣】代替。

        从视频中可以看到,机械臂实际上是在模仿一个4连杆机构的动作,而连杆的转动副就是旋转电位器。所以整个系统可以分为【机械臂主体】和【控制器】2个部分来制作。

一、机械臂主体

         主要结构为标称3mm的(实际为2.4mm)亚克力板材。

         舵机采用4个MG995(要求有十字、六角、圆盘配件包)和1个SG90(任意配件)。

         SG90与机械爪子之间靠粘合剂固定。螺栓+螺母作为轴承时可用粘合剂固定螺母在螺栓上的位置。

        由于加工精度和材料的物理特性,各板相接的榫位可能不能很好地卡住甚至出现断裂的情况,可以选择放弃榫接而采用热熔胶或者粘合剂进行固定。

        本人在制作实物的过程中发现一些设计问题,由于疏忽,也许并未能把所有的问题都在设计图中重新修改,敬请原谅。

        使用者可以一次加工更多的零件作为后备,防止在有零件损坏的情况下没有备用零件。

        下载本文的附件,在淘宝搜索“亚克力加工 激光”搜索到相关店家,联系客服,选好合适的亚克力板材(3mm),发送dwg文件给客服,确认无误后下单即可。

ATTENTION:
        【水深!对于价格一定要货比三家!同时要确认板材实际厚度为2.4mm!】

sg90舵机
sg90舵机
mg995舵机
                mg995舵机

预调电位器预调电位器

舵机的安装
            舵机的安装
舵机的安装
             舵机的安装
爪子细节
              爪子细节
安装好的样子
                                                 安装好的样子

由于有些部分已用热熔胶固定,Ttable不再将其分解拍照了。附件里每个dwg文件都只是机械臂的一部分,使用者们可以对照着先拼装出各个部分,再总装起来。

使用的过程中,Ttable发现它容易倒,使用者可以通过修改底盘的设计或者为底盘增加一点配重来解决这个问题。

 

 

二、连杆控制器

这部分没什么好说的,随便找点杆状材料,转动副是电位器,用热熔胶粘成连杆就行,可谓简单粗暴。

IMG_20141006_203839 IMG_20141006_203854

不过要注意两点:一是要注意电位器的初始位置要能使每个节点的运动范围和机械臂对应关节的运动范围保持一致;二是,如果你使用碳膜电位器(如图),你会发现接触不良的频率非常高,所以要用足够的热熔胶来固定电位器引脚的接线。

要用足够的热熔胶来固定
要用足够的热熔胶来固定
末端是一个自锁开关,用来控制爪子。
末端是一个自锁开关,用来控制爪子。

 

制作完两个部分之后,就可以把所有东西连接起来了。

从上面可以看到控制器的接线非常混乱……线多没办法,而且线要足够长,避免影响控制器的活动范围。同理,机械臂的舵机线也要足够长。

接线图
接线图(有一个button忘了画,其实就是一个button,连接arduino的数字0口)

 

为了防止干扰,机械臂和Arduino要使用两个独立的电源。我用的是2组串联的18650电池。另外,供给机械臂的电压不可以高于9V,否则会烧坏SG90。

 

后来我使用万能板来代替面包板
后来我使用万能板来代替面包板

 

 

用简陋的排针来和Arduino链接
用简陋的排针来和Arduino链接

最后,代码来了。

继续阅读Arduino控制的机械臂

电池的分类和特性

一次性电池(Primary Battery)俗称“用完即弃”电池,因为它们的电量耗尽后,无法再充电使用,只能丢弃。常见的一次性电池包括:
锌锰电池—电压约1.5V,电池容量较低,能输出的电池也较低,几乎被碱锰电池所取代,唯独是不会在长期存放后漏出有害腐蚀液体,所以仍被使用于低用电量同时需长期使用的装置,例如钟、红外线摇控等。
碱锰电池—电压约1.5V,电池容量及输出的电池较锌锰电池高,但不及镍氢电池,长期存放后漏出有害腐蚀液体。

battary

市面上常见不可充电5号(AA)、7号(AAA)电池都属于上述介绍的两种电池,还有一种常见的9V电池也常常也用来和Arduino供电

battary02

当这种电池其实是内部由多组各自是1.5V的电池串联来达到对外9V供电的,这种电池往往也是不可循环充电使用。处于日益受重视的环境问题,以及消费者使用产品的经济性,我们越来越倾向于使用可充电的电池,而干电池只在功耗较低的设备上仍旧使用。
可充电电池又称二次电池(Secondary battery)、蓄电池。可充电电池按制作材料和工艺上的不同,其优点是在充电后可多次循环使用,它们可全充放电两百多次甚至达2500次,充电电池的输出电流(负荷力)要比大部分一次性电池高。常见的类型有:

battary03battary04

铅酸电池—电压约12V,能量密度较低,所以体积庞大。但可以做出大容量的、且能放出巨大电流的电池,所以仍然无法淘汰。汽车启动电机通常需要200A 左右的电流,目前只有铅酸电池能胜任。它还有一个好处:充电简单,不用放电完就可以充,而且是简单的恒压充电。过放电将导致电池性能下降,需要激活处理。体积较大的机器人可以考虑使用。

battary05battary06

battary14

镍氢电池NiMH —电压约1.2V,有极轻微的记忆效应,容量较镍镉电池及碱性电池大,可充放电循环使用数百至二千几次。虽然镍氢电池的电压时1.2V,但在大多数场合可以替代1.5V的干电池。旧镍氢电池有较大的自放电,新的低自放电镍氢电池 自放电低至与碱性电池相约,已取代了镍镉电池和绝大部份碱性电池的用途,能量密度要求不高的场景下推荐使用。

battary07

市面上常见的18650锂离子电池

battary12
锂离子电池Li-ion—电压约3.6、3.7V,锂离子电池具有重量轻(容量是同重量的镍氢电池的1.5~2倍)、容量大、无记忆效应等优点,具有很低的自放电率,因而即使价格相对较高,仍然得到了普遍应用,包括许多电子产品,而且不含有毒物质,但这类用于消费性电子产品的Li-ion电池在存放一段时期后电量会永久减少。另也有用于纯电动车(如特斯拉)及混合动力车的Li-ion电池,用于这用途的锂离子电池容量相对略低,但有较大的输出、充电电流,也有的有较长的寿命,但成本较高。

battary08

battary13

锂聚合物电池 ( lithium polymer ) 或聚合物锂电池又可简称为锂聚电池 ( Li-Po )、或聚锂电池都是一种锂离子电池升级替代品。锂聚电池通常是由数个相同的平行子电池芯 ( secondary cells ) 来增加放电电流,或由数个电池包(pack)串联来增加可用电压。锂离子电池为锂聚电池的前身,主要差异为电解质使用液态有机溶液而非胶状或固态的聚合物,这使得锂聚合物电池在过压充电和短路时只会鼓起、不会发生爆炸的危险。现在电子产品(如智能手机、平板电脑、蓝牙耳机、非廉价移动充)中已有替代锂离子电池的趋势。
电池使用的基本准则:
1、任何时刻都不允许将电池短路,购买正规厂家的电池和符合规格的充电器进行充电,不要图便宜,本书附录将介绍一些较为正规的厂家及购买途径。
2、在能量密度没有特殊要求的场合,优先考虑镍氢电池NiMH,能量密度要求较高的场合(如四轴飞行器),优先考虑锂聚合物电池( Li-Po )。因为锂离子电池Li-ion虽然能量密度大,但意外短路或者充电方式不正确(这通常是由劣质充电器造成)都可能引发爆炸,威胁人身安全。
3、认真阅读电池及充电器的说明书或规格书,依照规范使用电池,必要时做好防护措施。

battary09 battary11

18650锂电短路爆炸后                                锂电过压充电爆炸试验

Arduino的编码盘与反馈

市面上的电机质量参差不齐,便宜的电机普遍都有10%的误差,这意味着,Arduino控制器给出同样驱动信号,两个电机转过的角度和转速都会有较大差别。在机器人运行的过程中,如果左右轮电机不对称,机器人在直线驱动信号下将走弯路。这一点后续还会讲到,但是本节介绍的编码器,其主要功能就是反馈电机运动的速度与位置,能做到让电机基本指哪转哪。编码器的实现方式通常有磁式和光学两种,不过原理非常类似,只是磁式采用霍尔传感器检测磁场的脉动,而光学编码器采用光敏元件检测。下面就以光学编码器为例简要介绍其工作原理。为了检测细微运动并输出为数字脉冲信号,码盘(旋转运动)或码尺(直线运动)被细分成若干校区,每个小区透光或者反光。以透光式为例,当光源由码盘一侧向另一侧发射一束光时,另一侧的光敏元件进行检测。如果码盘角度正好位于光线能穿过的地方,光敏元件导通,输出高电平,反之则光敏元件管断,输出低电平。随着码盘的转动,传感器就能连续不断地输出脉冲信号,对该信号在特定时间内计数,则可测量其转过的角度,已经获得平均速度。

encoder01

encoder02

前面一节提到了电机的正反转驱动问题,在检测的时候也会有此困惑,上述介绍的编码盘工作方式是无法获得旋转方向的。所以有提出采用绝对编码器的方案,详情请参考附录或相关资料。在大多数情况下,许多增量编码器通过增加多一个码区,即可完成判断转向的功能。

encoder03

增量编码器给出两相方波,它们的相位差90°,通常称为A通道和B通道。其中一个通道给出与转速相关的信息,与此同时,通过两个通道信号进行顺序对比,得到旋转方向的信息。还有一个特殊信号称为Z或零通道,该通道给出编码器的绝对零位,此信号是一个方波与A通道方波的中心线重合。

encoder04

旋转编码器可通过旋转可以计数正方向和反方向转动过程中输出脉冲的次数,旋转计数不像电位计,这种转动计数是没有限制的。配合旋转编码器上的按键,可以复位到初始状态,即从0开始计数。

encoder05

encoder06

增量型编码器精度取决于机械和电气两种因素,这些因素有:光栅分度误差、光盘偏心、轴承偏心、电子读数装置引入的误差以及光学部分的不精确性。确定编码器精度的测量单位是电气上的度数,编码器精度决定了编码器产生的脉冲分度。以下用360°电气度数来表示机械轴的转动,而轴的转动必须是一个完整的周期。要知道多少机械角度相当于电气上的360度,可以用下列公式来计算:电气360 =机械360°/n°脉冲/转

encoder07

现在市面上已经有了专门的编码器模块,配合联轴器可以直接与电机相连,测量我们需要测量轴的转动情况,如右图所示,看起来很像电位器的样子,但它可以连续360°旋转,一圈脉冲数:20。

编码器(Encoder)也可以直接用现有的Arduino类库直接操作,使用起来简单方便,其代码如下,详细资料及类库下载,请访问源码作者博客或Arduino官网相关了解更多。

http://playground.arduino.cc/Main/RotaryEncoders

http://www.pjrc.com/teensy/td_libs_Encoder.html

/* 编码器示例程序
 * 源码作者相关信息
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 * 该代码位于公共域
 */

#include 

Encoder myEnc(5, 6);

void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

用Arduino检测颜色

很多机器人竞技及爱好者制作过程中都需要能辨别颜色的传感器,比如赛道中的区域和信标的识别,又或者一些爱好者希望制作一款能够自动还原实物魔方(Rubik’s Cube)的机器人。
关于颜色的基本问题,笔者经验很多初学者还混淆“光的三原色及颜料的三原色”,这可能会影响颜色传感器使用的理解,下面先做一简单介绍。
我们看到叶子是绿色的,并不是因为叶子发出绿色的光,而是因为白色阳光中混合了各种颜色的光,除了绿色被反射以外,其它颜色的光都被吸收了。

color01

光的三原色(RGB) 颜料的三原色(CMYK)
将橙红和绿的色光混合,可得到黄色光;绿和蓝紫光混合可得到青绿色光;橙红和蓝紫混合可得到红紫色光。若将三原色光混合,则会变成白光。这些色光混合后,会得到比原来色光更明亮的色光,因此色光的混合,又称为“加色混合”。
色彩有减法,是由于物体表面上的颜料,吸收了日光中一部份的光波,反射日光其他的色光,当两种或多种颜料混合的时候,有更多的色光被吸收,越少的色光被反射,因而形成暗色或黑色。色彩的减片法是运用在颜料的混合,亦广泛地运用在印刷技术之中。同时色彩的减法又称为CMYK,CMYK分别代表三原色中彩蓝C (Cyan),洋红(Magenta),黄(Yellow),以及黑(Black)。黑色虽然不属于三原色的一种,但在印刷上,要加上黑颜料才能调出真正的黑色。
由上面的三原色感应原理可知,如果知道构成各种颜色的三原色的值,就能够知道所测试物体的颜色。对于 TCS3200来说,当选定一个颜色滤波器时,它只允许某种特定的原色通过,阻止其它原色的通过。例如:当选择红色滤波器时,入射光中只有红色可以通过,蓝色和绿色都被阻止,这样就可以得到红色光的光强;同理,选择其它的滤波器,就可以得到蓝色光和绿色光的光强。通过这三个值,就可以分析投射到 TCS3200 传感器上的光的颜色。仔细观察芯片的放大照片就可以看到。在透明塑料封装的芯片中央有一个硅片,其中的电极用纯金跳线和外部引脚相连。因为此芯片需要透光工作,不同于其它黑色塑料封装的芯片,恰好能够一窥集成电路IC芯片的内部结构。这是笔者故意设此一节讲解该芯片的原因之一。
我们还可以看到硅片中央有8×8=64个颜色不同的方块,这其实是64个小光敏二极管,不过上面都有滤镜,只能分别透过红(R)、绿(G)、蓝(B)三种颜色光中的一种,以检测这三种光线分量的强度。三种颜色光的光敏二极管等量均布在64块方砖中。

color02color03

Texas Advanced Optoelectronic Solutions(TAOS)公司是全球公认的光传感技术创新厂商,其所生产的TCS3200颜色识别芯片在机器人爱好者中得到广泛的应用。许多开源硬件模块提供商利用这块芯片制成颜色模块出售。这些模块大同小异,在使用前比较重要的还是了解此款芯片的基本工作原理。在AllDataSheet网站中中查找此款芯片的资料,可以了解到以下几点:

color04color05color06

该芯片有8个引脚,其中OE用于选择此芯片是否正常工作,因为其它引脚可以和其它传感器共用Arduino引脚,在OE为有效状态时,整个芯片才工作。无效状态时,其它引脚都处于高阻状态,相当于断开连接。OE上划一横线表面,OE是在低电平时有效,而非高电平。
VDD和GND是电源正负极,如欲知道此专业名词来历请查阅晶体管工艺相关书籍,由于DataSheet中指明工作电压范围2.7V~5.5V,所以和Arduino连接时直接接5V端口即可。
OUT是唯一一个输出端口,输出固定频率的方波来传达检测所得颜色信息。
S0、S1、S2、S3此四个都是输入的设置端口,具体功能下面两表介绍

color07
根据DataSheet可知,100%的频率输出的时候,典型的方波频率是600kHz,占空比50%,但是由于一些控制器无法检测频率过高的频率,所以可以通过设置S0、S1两个输入引脚的电平,按相应比例降低输出方波的频率,以便于低速的信号捕捉电路能够侦测统计相关信号,但传感器信号的刷新速度也会随之降低。由于Arduino的速度已经足够快较准的捕捉100%频率的TCS3200信号,故S0、S1均设置为高电平(H/HIGH)。

color08
S2和S3输入引脚依照一定的组合,可以分别获得红(R)、绿(G)、蓝(B)三种颜色光的强度,所以在使用颜色传感器的过程中,只要在较短的时间内逐次扫描分别获得三种色光的分量即可初步判断物体的大致颜色了
下面给出TCS3200各控制引脚与Arduino控制器的硬件连线与程序源代码。

color09

//测试颜色识别模块TCS3200
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;
   
//定义LED端口
int pinRed = 2;
int pinGreen = 3;
int pinBlue = 4;
    
//RGB颜色色值
int red = 0;
int green = 0;
int blue = 0;
    
void setup()   
{  
  pinMode(s0, OUTPUT);  
  pinMode(s1, OUTPUT);  
  pinMode(s2, OUTPUT);  
  pinMode(s3, OUTPUT);  
  pinMode(out, INPUT);  
  pinMode(pinRed, OUTPUT);  
  pinMode(pinGreen, OUTPUT);  
  pinMode(pinBlue, OUTPUT);  
  Serial.begin(9600);  
  digitalWrite(s0, HIGH);  
  digitalWrite(s1, HIGH);  
}  
    
void loop() 
{  
  color();
  //输出RGB各色值
  Serial.print("Red:");  
  Serial.print(red, DEC);  
  Serial.print("Green:");  
  Serial.print(green, DEC);  
  Serial.print("Blue:");  
  Serial.print(blue, DEC);  
  Serial.println();  

  //检验结果是否红色 
  if (red < blue && red < green && red > 50)  
  {  
   Serial.println("Red");  
   digitalWrite(pinRed, HIGH); //点亮红色LED 
   digitalWrite(pinGreen, LOW);  
   digitalWrite(pinBlue, LOW);  
  }  

  //检验结果是否绿色
  else if (blue < red && blue < green)   
  {  
   Serial.println("Blue");  
   digitalWrite(pinRed, LOW);  
   digitalWrite(pinGreen, LOW);  
   digitalWrite(pinBlue, HIGH); //点亮绿色LED 
  }  

  //检验结果是否蓝色
  else if (green < red && green < blue)  
  {  
   Serial.println("Green");  
   digitalWrite(pinRed, LOW);  
   digitalWrite(pinGreen, HIGH); //点亮蓝色LED 
   digitalWrite(pinBlue, LOW);  
  }  
  Serial.println();  

  //延时两秒后关闭所有LED
  delay(2000);   
  digitalWrite(pinRed, LOW);  
  digitalWrite(pinGreen, LOW);  
  digitalWrite(pinBlue, LOW);  
 }  
    
void color()  
{  
  //设置好S2、S3端口,准备读取颜色值
  digitalWrite(s2, LOW);  
  digitalWrite(s3, LOW);  
  //红色光RED
  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
  digitalWrite(s3, HIGH);  
  //蓝色光BLUE  
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
  digitalWrite(s2, HIGH);  
  //绿色光GREEN  
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);  
}

Arduino控制小型直流电机

电机俗称马达(Motor),有直流驱动的有交流驱动的,还有用汽油(航模车模)、液压驱动的马达(大型工业设备)。一般所指的电机是通过电生磁原理将电路中的电能转换成机械能的装置。本节仅讨论常见的小功率直流电机,对于工业上常用的异步交流电机的控制因涉及诸多电力电子技术细节超出本书细节,请有兴趣的读者可以参考电机学相关著作或教材。

DCmotor01

图所示为一直流电机(DC Motor)工作原理示意图。一对静止的磁极N和S之间,安装了一个可以绕中心轴旋转的漆包线线圈及其包裹的层叠硅钢片。硅钢片的目的是为了增强线圈产生的磁导,减少漏磁,而硅钢片叠加在一起相互又绝缘,是为了防止硅钢片内产生较大的涡流而损耗电能在发热上。中间转动的部分通常称为电枢,而线圈两端分别接在换向器的两个半圆铜片上,铜片之间相互绝缘,但分别接直流电源正负极。其中的磁场和产生的电枢转矩如何计算,为何需要设置换向器等问题在初中物理教科书中已有论述,在此不再赘述。

DCmotor02

需要说明的是,电机是较大功率的器件,他不能直接用Arduino的端口去驱动。一般来说,Arduino的每个引脚只能扇出(source)或者灌入(sink)最大40mA的电流,而所有端口的总电流不超过200mA(0.2A),而一般小电机也往往超过100mA。因此,只能采用放大驱动的方式,以晶体管(BJT)驱动电路为例,将端口连接至基极,就可以不到几mA的电流驱动流经电机的数百mA电流。下图晶体管集电极上连接的5V视直流电机的额定电压而定。一般按照直流电机上的铭牌来选择此路供电电源的电压和带负载能力,且最好将此路供电电源与Arduino的供电电源分开,以防止电机启停时对电源的干扰影响Arduino的正常工作。
针对不同电机(或者大负载),需要使用不同型号的晶体管放大,所以读取电机铭牌上的参数就显得尤为重要。下面是一款常见电机的说明书部分截取,资料来自Sparkfun官网,电机型号为Micro Metal Gearmotor 30:1 ROB-08911,从中我们可以获得相关信息,从而达到合理选用匹配的驱动器(三极管)。

DCmotor03
然后我们从常见的晶体管目录中选择,下面的较为常用的一些小功率晶体管型号,更多常用晶体管列表目录及其关键参数,请参考附录。

S9011 S9012 S9013 S9014 S9015 S9018 A1015 C1815
A42 A92 2N5401 2N5551 A733
C945 S8050 S8550 2N3906 2N3904
譬如在型号为S9013的晶体管的DataSheet说明中,我们看到如下表格数据
DCmotor04

可见S9013放大后连续正向电压和电流分别达到20V和500mA,完全能够满足额定电压和电流分别是6V和100mA的直流电机负载且有几倍的裕量,故可以满足要求。如果你手上的电机无法找到相应的规格书,你可以通过在电机工作时测量其电压和电流来进行简单的估计。
下面我们就来接线驱动小电机,不过我们不能忽略电机内的线圈,这意味着电机在断电一瞬间将产生巨大的自感电动势,其峰值很可能会超过晶体管所能承受的最大电压,所以必须减缓自感可能带来的不利因素。根据楞次定律,带有电感负载的通路端口的一瞬间,产生的自感有保持原有电流方向的趋势,所以我们可以在电机两旁并联一个二极管来释放因自感产生的尖峰电压。二极管选用较为常用的型号1N4001即可,关于二极管的参数选择过程与之前三极管的过程类同,请读者自行查阅Datasheet练习。

DCmotor05DCmotor07

 

DCmotor06

/* -----------------------------------------------------------
 * | Arduino小电机驱动电路示例程序 |
 * | 代码出处http://ardx.org/4001 |
 * | 连线时请注意参考右图引脚位置 |
 * -----------------------------------------------------------
 */

int motorPin = 9; //定义电机连接引脚

void setup()
{
  pinMode(motorPin, OUTPUT);
}

void loop()
{
  motorOnThenOff();
  //motorOnThenOffWithSpeed();
  //motorAcceleration();
}

//关闭电机
void motorOnThenOff(){
  int onTime = 2500; //调节开关占空比,也可使用PWM模拟输出方式
  int offTime = 1000;

  digitalWrite(motorPin, HIGH);
  delay(onTime);
  digitalWrite(motorPin, LOW);
  delay(offTime);
}

//电机以特定速度启停
void motorOnThenOffWithSpeed(){

  int onSpeed = 200;
  int onTime = 2500;

  int offSpeed = 50;
  int offTime = 1000;

  analogWrite(motorPin, onSpeed);
  delay(onTime);
  analogWrite(motorPin, offSpeed);
  delay(offTime);
}

//电机变速
void motorAcceleration(){
  int delayTime = 50; //调整速度的时间间隔

  //电机加速
  for(int i = 0; i < 256; i++){
    analogWrite(motorPin, i);
    delay(delayTime);
  }

  //电机减速
  for(int i = 255; i >= 0; i--){
    analogWrite(motorPin, i);
    delay(delayTime);
  }
}

由于一个晶体管驱动的电机只能单向驱动调速,有时候往往还需要电机能够正反转。如图所示,当Q1管和Q4管导通,Q2和Q3截止时,电流从电源正极经Q1从左至右流过直流电机,然后再经Q4回到电源负极,从而驱动直流电机沿一个方向旋转。反之,当Q2和Q3导通,Q1管和Q4管截止时,电流从直流电机右边流入,从而驱动直流电机沿另外一个方向旋转。这种驱动方式的电路和字母“H”非常相似,所以就往往被称为H桥驱动电路。这样类似的H桥组合驱动电路可以自行搭建,但要注意不能让Q1和Q2或者Q3和Q4同时导通,哪怕是较短的时间也不允许,因为这会使得电源正负极直接相连,可能损坏电源或晶体管。所以在执行使用H桥驱动直流电机电路前请务必仔细检查电路和程序,以防短路。

DCmotor08意法半导体公司(STMicroelectronics)生产的L293D和L298P两款芯片是市面上常见的H桥电机驱动集成芯片,它们的外形虽然看起来很不一样,但是只要掌握其中一种的原理和使用方法,再学习使用另外一个就不会太难。这两款芯片的细节参数请读者自行查阅AllDataSheet网站,但很多机器人或电子模块提供商已经将H桥做成了Arduino的专用模块甚至是盾牌(Sheild),配合专门的Arduino类库,使用起来会大为方便。本节以美国开源硬件商Adafruit制作的一款293 Motor Sheild为例来说明如何实现电机的调速与正反转。
DCmotor10

此款Motor Sheild采用了两个L293及一个74HC595芯片,可以同时控制4路直流电机或者两路步进电机和舵机。本节仅介绍此款Motor Sheild普通直流电机的使用,关于步进电机和舵机,请参考本书后续部分或Adafruit官网:
https://learn.adafruit.com/adafruit-motor-shield/using-dc-motors
DCmotor09

此款Motor Sheild使用前有专配类库,可以到GitHub网站下载
https://github.com/adafruit/Adafruit-Motor-Shield-library
需要注意的是,电机有四个连接口,如图所示,连接其中一个即可(下面的示例程序使用的是Motor #4)。此种连接端子用于连接电流较大的场合,故使用的是螺丝刀拧紧的方式,在把电线剥开一小段距离后,松开螺丝放入电线裸露端再拧紧螺丝即可。如果在使用过程中发现电机转向与你所需的方向相反,断开电源后将两根连接线交换位置后重新连接即可。

// Adafruit Motor shield library
// 此代码位于公共域

#include <AFMotor.h>
AF_DCMotor motor(4);

void setup() {
  Serial.begin(9600);
  Serial.println("Motor test!");
  //打开电机
  motor.setSpeed(200);
  motor.run(RELEASE);
}

void loop() {
  uint8_t i;
  Serial.print("tick");
  motor.run(FORWARD);
  for (i=0; i<255; i++) {
    motor.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor.setSpeed(i);
    delay(10);
  }
  Serial.print("tock");
  motor.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor.setSpeed(i);
    delay(10);
  }
  Serial.print("tech");
  motor.run(RELEASE);
  delay(1000);
}

上述示例程序实现的是电机简单的正反转加速减速,故不再添加注释。

Arduino操作伺服电机/舵机(一)

舵机简单的说就是集成了直流电机、电机控制器和减速器等,并封装在一个便于安装的外壳里的伺服单元。能够利用简单的输入信号比较精确的转动给定角度的电机系统。
舵机安装了一个电位器(或其它角度传感器)检测输出轴转动角度,控制板根据电位器的信息能比较精确的控制和保持输出轴的角度。这样的直流电机控制方式叫闭环控制,所以舵机更准确的说是伺服马达,英文servo。
舵机的主体结构如下图所示,主要有几个部分:外壳、减速齿轮组、电机、电位器、控制电路。工作原理是控制电路接收信号源的控制信号,并驱动电机转动;齿轮组将电机的速度成大倍数缩小,并将电机的输出扭矩放大响应倍数,然后输出;电位器和齿轮组的末级一起转动,测量舵机轴转动角度;电路板检测并根据电位器判断舵机转动角度,然后控制舵机转动到目标角度或保持在目标角度。

图 舵机外观及内部主要结构示意图

舵机是一个微型的伺服控制系统,具体的控制原理可以用下图表示:

图 舵机控制原理示意图

控制电路接收信号源的控制脉冲,并驱动电机转动;齿轮组将电机的速度成大倍数缩小,并将电机的输出扭矩放大响应倍数,然后输出;电位器和齿轮组的末级一起转动,测量舵机轴转动角度;电路板检测并根据电位器判断舵机转动角度,然后控制舵机转动到目标角度或保持在目标角度。
模拟舵机需要一个外部控制器(遥控器的接收机)产生脉宽调制信号来告诉舵机转动角度,脉冲宽度是舵机控制器所需的编码信息。舵机的控制脉冲周期20ms,脉宽从0.5ms-2.5ms,分别对应-90度到+90度的位置。

模拟舵机由于使用模拟器件搭建的控制电路,电路的反馈和位置伺服是基于电位器的比例调节方式。电位器由于线性度的影响,精度的影响,个体差异性的问题,会导致控制匹配不了比例电压,比如我期望得到2.5V的电压位置,但第一次得到的是2.3V,经过1个调节周期后,电位器转过的位置已经是2.6V了,这样控制电路就会给电机一个方向脉冲调节,电机往回转,又转过头,然后有向前调节,以至于出现不停的震荡,这就是我们所看到的抖舵现象。在购买一批舵机中会发现有的很好用,有的在空载的时候也会在抖动,有的是在加一定的负载后就开始抖动。

servoAnimation


舵机除电源外,只要一根信号线即可;使用PPM(脉冲比例调制)信号控制;所谓“PPM”,是一个周期约20ms,其间有个宽度在2ms 左右的脉冲控制信号。一般是以1.5ms 为基准,此时舵机居中,小于1.5ms 舵机左转,大于1.5ms,舵机右转;至于角度和脉冲宽度关系各个产品不同,例如:0.5ms 对应左转90 度,2.5ms 对应右转90 度。
舵机内部实际上是由小电机、减速齿轮、驱动电路、位置反馈、比较电路等组成的闭环控制单元,由于其内置减速齿轮,所以输出力矩较大。最早将其改造为轮式机器人动力源的爱好者估计就看上了这些,他们将舵机的限位去除,位置反馈去除,舵机控制电路因得不到反馈,以为还未转到指定的角度,只好一直驱动电机转动,由于去除了限位,输出轴实现了连续转动,就成了一个减速直流电机。而且,利用其原来的左、右转控制逻辑,实现了正、反转控制。从本质上说,舵机和直流减速电机相同,只是利用了舵机内部的驱动和控制电路,从而简化了控制接口和电路。实际上:改造为连续转动的舵机 = 电调 + 直流减速电机电子调速器的控制信号和舵机一样,只是在小型电机中一般用不着电调,因为其功率不太大,一般在10A 以上,100A 也不足为奇,大材小用了。舵机还有一个优点是安装方便,除自身安装外,安装车轮也很方便,因为舵机一般提供丰富的轴输用舵机作为小车动力,可用MCU 直接驱动,不需要再设计、制作额外的驱动电路,这点对于DIY 者而言还是颇具吸引力的。而且控制所需的MCU 资源也有限,只要一个数字I/O口、一个定时器即可,虽说准确生成2ms 左右的脉冲有些技巧,但总的来说编程相对容易。如果用Arduino 系列控制器,其Servo 函数可让你一条语句“搞定”。
结论:使用舵机作为小车驱动一是为了便于装,二是为了便于控,三是可简化电路。其代价就是“力气”略小,可供选择的规格有限。还有就是略有些不“经济”,因为舵机的“贵贱”主要体现在其控制精度上,改为连续运转的驱动电机后,这部分功能给“废”了,是不是有些可惜?不过也不完全“浪费”,舵机的这部分控制通常采用PID 调节,其比例功能可用于调速,当输入的脉冲偏离中点(1.5ms)越远,其驱动电机的速度越快,而且其调节电路使用了电机反电势作为反馈,原设计大概是为了保证舵机在轻、重负荷下都可以按照相近的速度转到指定的角度,以实现较好的控制特性(比如说60 度/0.22 秒)。改为连续转动后正好作为调速功能,这也是使用舵机的一大优点。

图 连续舵机外观及中位点调节示意图

上图所示是较为常用的一款常用的连续旋转舵机,可以使用螺丝刀调节其中位点,以使其脉冲中点能在1.5ms附近变化。

// Controlling a servo position using a potentiometer (variable resistor) 
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott> 

#include  
 
Servo myservo;  // create servo object to control a servo 
 
int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  val = analogRead(potpin);        // reads the value of the potentiometer (value between 0 and 1023) 
  val = map(val, 0, 1023, 0, 179);   // scale it to use it with the servo (value between 0 and 180) 
  myservo.write(val);             // sets the servo position according to the scaled value 
  delay(15);                    // waits for the servo to get there 
}

// Sweep
// by BARRAGAN <http://barraganstudio.com> 
// This example code is in the public domain.


#include  
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees    {                                  // in steps of 1 degree      myservo.write(pos);              // tell servo to go to position in variable 'pos'      delay(15);                       // waits 15ms for the servo to reach the position    }    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
}

Arduino实践-超声波(ultrasonic)测距

科学家们将每秒钟振动的次数称为声音的频率,它的单位是赫兹(Hz)。我们人类耳朵能听到的声波频率为20Hz~20000Hz。当声波的振动频率小于20Hz或大于20KHz时,我们便听不见了。因此,我们把频率高于20000赫兹的声波称为“超声波”(ultrasonic)。通常的超声波频率为1兆赫兹~5兆赫兹。因其方向性好,穿透能力强,易于获得较集中的声能,在传播距离较远,故而常被被用于测距。

ultrasonic
超声波发射器向某一方向发射超声波,在发射的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340 m/ s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离S ,即:S = 340t / 2。超声波指向性强,在介质中传播的距离较远,利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此在移动机器人的研制上也得到了广泛的应用。
超声波发生器可分为两大类:一类是用电气方式产生超声波;一类是用机械方式产生超声波。电气类包括压电型、磁致伸缩型和电动型等;机械类包括加尔统笛、液哨和气流旋笛等。它们所产生的超声波的频率、功率和声波特性各不相同,因而用途也有所不同。目前常用的是压电式超声波发生器。
压电式超声波发生器实际上是利用压电晶体的谐振来工作的,其外观结构与内部结构分别如图所示.该传感器有两个压电晶片和一个共振板, 当其两极外加脉冲信号,且频率等于压电晶片的固有振荡频率时,压电晶片将会发生共振,并带动共振板振动产生超声波。反之,如果两电极间未外加电压,当共振板接收到超声波时,将迫使压电晶片振动,将机械能转换为电信号,这时它就成为超声波接收器了。

图 超声波测距模块内部结构简图

       超声波测距传感器规格很多,测试距离也从远到近都有,价格相差也较大,一般机器人爱好者使用的都是测量范围在最小几厘米到最大几米之间,典型值是2厘米到2米,精度约5毫米。超声波测距的优点在于测量范围较大,且不是使用光学信号,所以被测物体的颜色对于测量结果没有影响。但还是常常会受到外界环境的其它因素影响,依靠声速测距,所以对于一些影响声速的因素较敏感,比如温度、风等。最大允许角度较小。在不同的室温下,声速是不同的,因而会给测距带来误差,所以一般的模块测距精度都难以小于5毫米。但很自然的会想到采用温度补偿的方式,也即额外再添加一个温度传感器,根据不同温度下的声速来计算,从而可以补偿温度变化带来的误差,有估算用的近似公式

声速 = 331 + 0.6 t (攝氏温度)

根据测得的实际温度矫正环境中的真实声速,以减小测量误差。这样的模块测距精度就可以达到1~2毫米了,而且同时能当做温度传感器来使用,但价格也会稍高。
超声波测距传感器可能是机器人中运用最为广泛的传感器之一了,它不仅便宜,拥有丰富的库,而且测量结果也较为可靠。我们都知道蝙蝠夜行时躲避障碍物的原理,下面以一款市面上最为成熟和常见的超声波测距模块HC-SR04为例来说明。

该超声波模块没有自带温度补偿,以340m/s的室温下声速作为参照基准,同个扩展库捕捉脉冲宽度获得超声波来回的时间后,通过简单的运算获得距离。

#include 

#define TRIGGER_PIN  12
#define ECHO_PIN     13

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  float cmMsec, inMsec;
  long microsec = ultrasonic.timing();

  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  //下面被注释的三句以英寸显示距离,该单位较少使用,故注释掉相关语句
  //inMsec = ultrasonic.convert(microsec, Ultrasonic::IN);
  Serial.print("MS: ");
  Serial.print(microsec);
  Serial.print(", CM: ");
  Serial.print(cmMsec);
  //Serial.print(", IN: ");
  //Serial.println(inMsec);
  delay(1000);
}

       超声波测距的原理简单易懂,因为有成熟的扩展库,使用起来也很方便。所以很多机器人爱好者都会选择它来作为壁障的传感器,但是,超声波本身的性质也会导致一些问题的存在。
超声波测距其实是一种不完全感知,对于不同形状的物体它所表现的特性其实并不相同。而障碍物的形状对超声波测距的影响则是角度范围甚至是障碍物判定的正确与否。它下述两幅简图是由美国一超声波传感器制造商在用户手册中给出的关于不同形状障碍物超声波测距结果的比较,可以看出,对于不同形状的物体超声波测距的结果有很大差异,这样一来就会给壁障判断带来不利影响。

图表 1
图 超声波测距模块对圆柱障碍物的测量值分布图

图3.12 超声波测距模块对平板障碍物的测量值分布图
除上诉问题之外,国内外还有些学者还提到了超声波测距过程中可能因为幻影问题而难以穿越复杂障碍物环境并且为此提出了相应的模糊算法

图 超声波测距模块产生幻影原理示意及响应模糊算法对于复杂障碍物群的壁障轨迹