Category Archives: Arduino小组

Lightbox II 三轴加速度传感器与RGBLED

时隔半年,本学渣终于把lightbox二代憋出来了。

先看看lightbox II是个什么东西吧!

 

Lightbox II以Arduino Nano为核心,通过三轴加速度传感器ADXL345收集数据,用以选择功能和控制20只共阳级雾状RGBled。不可拆卸,但可以通过无线充电的方式进行充电。

其功能如下:1、在X轴方向摇动   --白光模式

                         2、在Y轴方向摇动    --自变色

                         3、在Z轴方向摇动    --随姿态变色

 

由于器件在内部的姿态问题,这里的XYZ跟程序的XYZ是不同的,但无关痛痒。
由于器件在内部的摆放姿态问题,整体的XYZ跟程序的XYZ方向可能是不同的,但这无关痛痒。

现在进入正题!

工具:1、电烙铁;2、热熔胶枪;3、裁剪万用板的工具。

材料:

Arduino Nano                           x 1

ADXL345                                   x 1

无线充电模块                           x 1

DC-DC 5V升压模块                x 1

3.7V锂离子电池952240        x 2

共阳极雾状RGBled               x 20

电阻5欧姆、100欧姆各1个

NPN型晶体管8050                x 3

杜邦线、针线、维修用飞线若干

5.5mmDC电源接口(圆口)x 1

12VDC电源适配器                 x 1

 

 

一、电路连接

总体原理图

R1的值取决于RGBLED的数量和型号,R2为100欧姆。
R1的值取决于RGBLED的数量和型号,这里R1为5欧姆,R2为100欧姆。
ADXL345模块,也有可能不是这个样子的。
ADXL345模块,也有可能不是这个样子的。
锂电池,并联起来。
锂电池,并联起来。某宝中顺电池【这不是广告!】
RGBled这里使用10mm高的。
RGBled这里使用10mm高的。
直径0.1mm飞线,每根只能允许流通47mA以下的电流。
直径0.1mm飞线,每根只能允许流通47mA以下的电流。
Arduino Nano
Arduino Nano
无线充电模块,某宝有售。链接http://item.taobao.com/item.htm?spm=a1z09.2.9.28.ZOivgQ&id=38592014875&_u=91jgd807a278 【不是广告啊!】
无线充电模块,某宝有售。链接http://item.taobao.com/item.htm?spm=a1z09.2.9.28.ZOivgQ&id=38592014875&_u=91jgd807a278 【真的不是广告啊!】
DC-DC升压模块,某宝育松有售。
DC-DC升压模块,某宝育松有售。

按照原理图连接或者焊接各个部分

一开始我用两组三极管,后来改为一组。
一开始我用两组三极管,后来改为一组。
测试中。别急,程序后面给。
测试中。别急,程序后面给。                 Arduino Nano的表面覆盖一层热熔胶,用来防止模块间接触造成以外的短路,其他器件也要这样做!
然后简单粗暴地用热熔胶将它们捆起来。捆起来之前可以剪掉器件上的一些针脚,以减小体积,比如arduino Nano的ICSP针脚。一旦作品完成这块Nano是不可能再拿出来用的了,所以,对于没用的i/o口针脚,该剪就剪。
然后简单粗暴地用热熔胶将它们捆起来。捆起来之前可以剪掉器件上的一些针脚,以减小体积,比如arduino Nano的ICSP针脚。一旦作品完成,这块Nano是不可能再拿出来用的了,所以,对于没用的i/o口针脚,该剪就剪。
IMG_20140910_181537
请无视我的脚吧QAQ

烧录好程序,测试功能,测试充电效果。做完以上工作之后,这块东西就可以先放在一边了。

 

 

二、亚克力和RGBled部分

【点击此处下载lightbox II的CAD图(dwg格式)】如果没有加工设备,可以直接发图给淘宝的店家加工,这里默认亚克力板的厚度为1.7mm。

下载本文的附件,在淘宝搜索“亚克力加工 激光”搜索到相关店家,联系客服,选好合适的亚克力板材(标称2mm,实际1.7mm),名称为《lightbox II(外)》的文件要切双面透明磨砂的亚克力,另外两个文件切不透明的材料,颜色自选,发送dwg文件给客服,确认无误后下单即可。

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

 

拿到亚克力后,找到5块有洞的亚克力片,仔细对比尺寸确认他们的位置关系,然后把RGBled装上去。

 

20个LED是并联的,安装的时候元件引脚穿过亚克力板上面的孔,注意引脚极性,不要接错。
20个LED是并联的,安装的时候元件引脚穿过亚克力板上面的孔,注意引脚极性,不要接错。

 

焊接细节。建议不要使用图中彩色的线,其实就是杜邦线剪成一段一段,这样的话焊点容易脱落。 柔软的维修用飞线是很好的选择,能够适应将亚克力围成长方体的过程。但是要注意,单根线的电流只允许在47mA以下,所以更靠近电源的地方要更多的线来连接,阳极引脚间的飞线也要比阴极引脚的多。焊接的时候要注意确认飞线不容易脱落,以及使用万用表确认是否导通。
焊接细节。建议不要使用图中彩色的线,其实就是杜邦线剪成一段一段,这样的话焊点容易脱落。
柔软的维修用飞线是很好的选择,能够适应将亚克力围成长方体的过程。但是要注意,单根线的电流只允许在47mA以下,所以更靠近电源的地方要更多的线来连接,阳极引脚间的飞线也要比阴极引脚的多。焊接的时候要注意确认飞线不容易脱落,以及使用万用表确认是否导通。

没错,这一步非常麻烦。

正面的效果
正面的效果
接上主要电路,也就是本文上一部分教大家做的电路。然后就围成长方体。
接上主要电路,也就是本文上一部分教大家做的电路。然后就围成长方体。
板间用可靠的胶水封好。
板间用可靠的胶水封好。内部部分就做好了。
底部再装上一块白色的亚克力,充电接收线圈粘在内部正中心,自锁开关的位置如图,要反复比较确认自锁开关的位置。
底部再装上一块白色的亚克力,充电接收线圈粘在内部正中心,自锁开关的位置如图,要反复比较确认自锁开关的位置。

mark透明磨砂的亚克力围成正方体外壳

透明磨砂的亚克力围成正方体外壳,装上内部部分,胶水固定。 作者发现502胶水会挥发,在接触面附近再凝结成雾状,有些影响外观。不知道大家有没有好的胶水推荐?
装上内部部分,胶水固定。
作者发现502胶水会挥发,在接触面附近再凝结成雾状,有些影响外观。不知道大家有没有好的胶水推荐?

 

·
最后的尺寸应该是96*96*96mm

三、充电座

充电座非常简单,就是几块亚克力把DC电源接头和无线充电模块的发射模块包在里面而已。

DC接口和无线充电模块的正负极接好就可以了。 大家还可以加上自锁开关和指示灯,加自锁开关记得改CAD图开孔。
DC接口和无线充电模块的正负极接好就可以了。
大家还可以加上自锁开关和指示灯,加自锁开关记得改CAD图开孔。
插好电,把lightbox II放上去,两个线圈对准就可以充电了。
插好电,把lightbox II放上去,两个线圈对准就可以充电了。

 

四、程序

在这里要先感谢极客工坊的弘毅,Lightbox II的ADXL345程序改自该贴http://www.geek-workshop.com/thread-80-1-1.html

还要感谢arduino.cn的各位大大,论坛里的大神@奈何col 编写的《Arduino程序设计基础》让我快速地入门了Arduino。

I2C库的使用方法参见 宜昌城老张 的博客http://www.eefocus.com/zhang700309/blog/12-01/236815_59f78.html

定时器2库的使用方法参见http://www.arduino.cn/forum.php?mod=viewthread&tid=2890

Continue reading Lightbox II 三轴加速度传感器与RGBLED

步进电机基础知识与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链接

最后,代码来了。

Continue reading 【教程】Arduino控制的机械臂

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);
}

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

Eagle全套中文视频教程上传优酷共享

从Arduino入门学习趣味电子,当做到一个程度想自己刻蚀电路板时该用何工具?每次都拿一块洞洞板在上面插件,拉线,焊接,调试?还是用面包板接一个不稳定的电路藏在互动装置里面?当你开始思考这些问题时,你已经需要更好的软件工具与知识进行更专业一点的点子设计了。
一般来说,当你的demo所需的电路在面包板上实验完成之后,可以将电路绘制在纸上,或是用相机拍照起来以免忘记当初怎样接,可是这种方式很不方便,未来也难以送交PCB电路板印刷厂商制作。

因此更好的方式是用专用的电路图绘制软体来制作,但是选择好用又免费的软件不太容易,我们以前最早使用的PCB绘制软体是protel 99se,这套软体在业界应该都还是广泛使用,因为它教学很多元件库也丰富,但一直没有新版本,原因是后来的Altium将之取代了protel 99...

除了Altium Designer(不是免费的),其实还有很多类似的软件,如PADs,OrCAD ...等。免费的PCB123,FreeBcb,Eagle PCB...等,免费之中好用的不多,稳定度高的也不多,经过以上各类型PCB绘制软件的试用,有些软件我们认为对于做Arduino起家的爱好者来说太难,简单的又太不稳定,因此我们推荐使用最广泛且最好用的Eagle PCB (Easily Applicable Graphical Layout Editor)!!

首先来下载:http://www.cadsoftusa.com/

跨平台同时支持windows, mac, linux三种版本的PCB设计软件真的少之又少啊,特别是可以在MAC电脑上面使用,真是超级亲切(因为我用MacBook,相信很多用Arduino的设计师也是如此)。

下载适合你操作系统类型的Eagle PCB安装包,下载好之后就一直安装安装到底,安装完成后,第一次开启会询问你是否有序号,请选择Freeware就好啦(据闻现在还要去官网注册一个账号用邮箱激活才能以免费软件来使用Eagle,不过也不算太麻烦啦。),免费版本的Eagle PCB可以画10 X 8 CM大小的电路板,初学者设计的电路基本上不会超过这个尺寸,如果超过了,你也该检讨什么会塞这么多东西在上面,是不是太多不必要的元件还是超出电子电路特性?其实Eagle免费版的这个特性,也是在迫使大家例行节约啊,O(∩_∩)O哈哈哈~

一切都安装好之后,打开软件是否感到一阵头晕目眩?似乎又是另一个世界一样,好在Eagle PCB的操作与介面真的很简单上手,只需一段时间的习惯你就会感到它真的很人性化。在开始使用之前,你可以上Arduino.cc网站下载一份Arduino 的原厂电路图打开来看看,什么? 原来Arduino电路图就是用Eagle设计的?没有错,当初Arduino团队为了让电路设计的分享更为简便,初期就使用了这套Eagle PCB电路软体设计了Arduino,一直到现在最新版本的Arduino DUE也是一样采用Eagle软体,各位不仿都下载来看看Arduino的电路设计有多精美,仿佛都像是一幅精心设计的迷宫般。

Arduino的原始设计图档(Ealge版):

http://arduino.cc/en/uploads/Main/arduino_Uno_Rev3-02-TH.zip

Eagle PCB在开源电子社区地位如此高的原因除了其简单易用跨平台之外,更重要的是其免费版本已经远远足够普通电子设计初学者使用。正因为如此,国内外许多知名的开源社区爱好者们都以这种格式的PCB来到论坛、维基还有各种各样的博客上互发PCB设计文件,分享自己的设计,改进他人的设计以方便自己学习和使用。诸如Seeed Studio、Sparkfun、Adafruit这些开源电子爱好者群聚的地方亦是如此。听到这里是否有些小激动呢?

创元素的小伙伴们发现网上中文Eagle资料目前还不是太多,加之很多Youtube上的视频需要翻墙,也不是中文的。创元素偶得一套Eagle零入门视频,不敢独享,故上传Youku供国内爱好者们共同学习分享使用。

1.
CadSoft公司的电路设计软件
EN Title: Introduction to Cadsoft EAGLE PCB Design Software
CN Title: 第1课:EAGLE软件介绍
Description:EAGLE软件概述,安装以及界面
tag:EAGLE EDA Cadsoft schematic PCB 电子设计软件 原理图设计 电路板图设计
EAGLE EDA Cadsoft schematic PCB Layout 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
EAGLE软件概述,安装以及界面
本视频由element14全球技术中心团队制作

2.1
EN Title: EAGLE Schematic Editor
CN Title: 第2课:EAGLE原理图编辑器介绍
Description:主要介绍原理图编辑器界面,及常见菜单设置、和常用命令用法
tag:EAGLE EDA Cadsoft schematic PCB 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
主要介绍原理图编辑器界面,及常见菜单设置、和常用命令用法
本视频由element14全球技术中心团队制作

3.1
EN Title: EAGLE PCB Layout Editor
CN Title: 第3课:EAGLE PCB编辑器介绍
Description:主要介绍PCB编辑器界面,及常见菜单设置、和常用命令用法
tag:EAGLE EDA Cadsoft schematic PCB Layout 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
主要介绍PCB编辑器界面,及常见菜单设置、和常用命令用法
本视频由element14全球技术中心团队制作

4.1
EN Title: EAGLE Library Editor
CN Title: 第4课第1节:EAGLE元件库编辑器界面
Description:主要介绍元件库编辑器界面,及常见菜单设置、和常用命令用法
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
主要介绍元件库编辑器界面,及常见菜单设置、和常用命令用法
本视频由element14全球技术中心团队制作

4.2
EN Title: How to Create a Simple Library
CN Title: 第4课第2节:实例介绍如何创建一个简单的库元件
Description:通过简单的电阻符号讲述如何创建一个简单的库元件
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
通过简单的电阻符号讲述如何创建一个简单的库元件
本视频由element14全球技术中心团队制作

4.3
EN Title: How to Create a Multi Gates Library
CN Title: 第4课第3节:实例介绍如何创建一个复杂的,具有多个Gate的库元件
Description:实例介绍如何创建一个复杂的,具有多个Gate的库元件
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
实例介绍如何创建一个复杂的,具有多个Gate的库元件
本视频由element14全球技术中心团队制作

4.4
EN Title: Library Management
CN Title: 第4课第4节:元件库管理
Description:介绍如何进行库的复制,修改,删除及更新
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
介绍如何进行库的复制,修改,删除及更新
本视频由element14全球技术中心团队制作

 

5.1
EN Title: Example of Schematic Design
CN Title: 第5课第1节:实例介绍原理图设计流程
Description:介绍电路设计流程和设计技巧,以及PCB设计流程,规则和技巧
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
介绍电路设计流程和设计技巧,以及PCB设计流程,规则和技巧
本视频由element14全球技术中心团队制作

5.2
EN Title: Example of PCB Layout
CN Title: 第5课第2节:实例介绍PCB设计流程
Description:介绍电路设计流程和设计技巧,以及PCB设计流程,规则和技巧
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
介绍电路设计流程和设计技巧,以及PCB设计流程,规则和技巧
本视频由element14全球技术中心团队制作

6.1
EN Title: CAM Setting
CN Title: 第6课第1节:CAM处理程序设置
Description:介绍CAM处理程序如何设置2层、4层电路板
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device Gerber 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
介绍CAM处理程序如何设置2层、4层电路板
本视频由element14全球技术中心团队制作

6.2
EN Title: Example of CAM Output
CN Title: 第6课第2节:实例介绍如何输出2层、4层电路板的Gerber文件
Description:通过具体的实例讲述如何修改CAM Job文件来实现输出2层、4层电路板的Gerber文件
tag:EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device Gerber 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
通过具体的实例讲述如何修改CAM Job文件来实现输出2层、4层电路板的Gerber文件
本视频由element14全球技术中心团队制作

7
EN Title: ULP
CN Title: 第7课:ULP介绍
Description:ULP语法介绍,以及常用ULP介绍
tag:ULP EAGLE EDA Cadsoft schematic PCB Library Symbol  Package  Footprint  Device 电子设计软件 原理图设计 电路板图设计
CadSoft公司的电路设计软件
ULP语法介绍,以及常用ULP介绍
本视频由element14全球技术中心团队制作

本文部分引用Arduino台湾使用者社群的文章和图片

文章出处:http://arduino.tw/index.php/course/getting-started-eagle/%E5%AE%A2%E8%A3%BD%E5%8C%96arduino%E9%9B%BB%E8%B7%AF%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AD%A5.html

 

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 
  } 
}

Ardublock图形化编程插件

上海新车间是国内第一家创客空间,由新车间创始人李大维先生带领研发的ArduBlock插件受到了广泛的好评,如果你很想尝试用Arduino做些简单的控制,但实在不能接受编写代码,ArduBlock就是个不错的选择。依照本书第一篇搭建好Arduino的基础环境后,到 ArduBlock官方网站http://blog.ardublock.com/zh/下载。
ArduBlock软件是Arduino官方编程环境的第三方软件,须依附于Arduino软件下运行,但ArduBlock是以图形化积木搭建的方式编程的,这样的编程方式使编程门槛降低,没有写代码经验的人也可以尝试给 Arduino控制器编写程序。
下面本节将简要介绍这一开发环境的搭建方法:
ArduBlock软件的ardublock-all.jar下载后,把ardublock-all.jar拷贝到 “Sketchbook location”所在目录底下的 tools\ArduBlockTool\tool\里。在Arduino的IDE下,打开菜单“File” -> “Preferences”。

上图“篮圈”标注的“d:\My Documents\Arduino”是 “Sketchbook location”所在位置,然后一级一级地在这个目录下建“子子目录”,如:d:\My Documents\Arduino\tools\ArduBlockTool\tool\,如图:

ArduBlock软件安装完,在Arduino IDE的菜单”Tools“下找到ArduBlock,启动ArduBlock。
开始编写我的第一个ArduBlock程序了,任务很简单:按下按钮,Arduino控制器检测到与按钮连接的9号数字端口为低电平,于是它向13号数字端口发出命令,点亮LED灯,松下按钮,则熄灭LED灯。
ArduBlock程序:

观察程序编写,真是如搭积木那么简单,还可以对程序进行批注。”批注“窗口可以拖动和缩放,不要让它挡住了程序。程序中的各个模块 都是从左侧的模块库里“拖进”编程界面的,然后用这些模块积木进行拼接,拼接对了,会发出一声“咔”的清脆响声。如果您要删去模块,也很有创意,把不需要 的模块“拖出”编程界面即可。
程序中“loop”循环结构模块和“ifelse"条件判断模块都是从”Control“ 模块中提取的,”not“取反模块来自于”Operators“模块库,而”digital pin“数字量输入模块和”set digtial pin“数字量输出模块都是从”Pin“模块库拖进来的。
该软件还在不断地出新版本,而且目前已经支持中文,你只要在IDE环境下面选择“File->Preferences->Editor language”将它更改为“简体中文(Chinese Simplified)”,点击“OK”,关闭IDE后重启,就会发现菜单和打开的ArduBlock都变成中文的啦!

现在的ArduBlock是依附在Arduino官方软件的第三方图形化编程环境,两者需同时运行,点击 ArduBlock编程环境上方的“下载到Arduino”按钮,你会发现Arduino编程环境的”上传“按钮图标也开始工作了,而且在Arduino编程环境里自动生成对应的代码,通过图形程序与文本程序的对照,来学习ArduBlock编程了。唯一美中不足的是,这些由图像界面转换而来的代码都没有缩进的层次可言,不利于阅读,希望后续版本能有所改进。

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

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