Posts Tagged ‘传感器’

四轴飞行器攻略2:器件介绍(下)

首先说下现在的进度:目前已经测试了用Arduino读取陀螺仪传感器,加速度传感器,电子罗盘的读数;并且可以用Android手机通过蓝牙向Arduino发送指令;焊了一个小小的扩展板,并完成了初步的组装。接下来的主要工作是传感器读数的分析和姿态平衡算法的研究。发个近照:

组装完毕,等待编写程序的四轴飞行器

组装完毕,等待编写程序的四轴飞行器

圈妈学过一点心理学,忧心忡忡的对我说“据说提前说出目标的事情就不容易成功”,所以她不建议我还没做好就发攻略。但是攻略这种东西,想写的时候没写下来,过几天就忘了。我只好用男生追mm的例子做了解释:闷骚型的男生如果被人知道了暗恋对象,有的人变得更紧张,见到mm就躲;有的人则是硬着头皮展开攻势,最终满载而归。所以公布目标没啥问题,关键是看你把它当成动力还是压力。

言归正传,下面继续介绍四轴飞行器的器件们。

陀螺仪传感器
陀螺仪传感器又称角速度传感器,它的作用是测量物体运动的角速度(废话啊)。从测量维度分,陀螺仪传感器有单轴的,双轴的和三轴的;以传输方式分,又有数字型的和模拟型的。
对于四轴飞行器,最好使用三轴传感器。因为水平方向上就已经需要测量x,y两个维度的角速度,z轴方向上的自转如果有电子指南针的话,倒是也可以省略。所以很流行的另一种方案是用两个垂直安装的单轴传感器(ENC-03MB 村田角速度传感器),价格会便宜好多。
至于数字型的还是模拟型的,初学者开始会觉得模拟型的好用,它会引出3条线,分别输出0~5V之间的电压,表示xyz三轴的加速度值。
看上去似乎相当简单,用analogRead一下就好了。
从我的实践经验看来,它的问题在于线太多!陀螺仪需要3根线,加速度又3根线,指南针再3根线….随着器件的增加,Arduino的模拟输入口完全不够用。
而数字型则简单了很多,以I2C总线为例,数据通信只需要2根线,而且很多个设备(最多支持256个设备)都是公用这两条线。反正看你愿意花力气在焊板子上还是写代码上了。对于我这样的IT民工来说,显然觉得敲代码比焊板子舒服很多,所以我最终选择的是L3G4200D三轴数字式陀螺仪传感器。

加速度传感器
加速度传感器又称重力感应器,它可以感知物体受到的重力。例如水平静止放置的重力感应器,xy方向上重力加速度都是0,z轴方向上的读数则是9.8;而倾斜放置的传感器,在xy分量上就可以读出所受的重力。和陀螺仪相比,加速度传感器测量的是绝对的“倾角”,而陀螺仪测量的是“倾角的变化速度”。
这些传感器的最终目标,就是让四轴飞行器保持平稳。有人可能觉得用重力感应器就足够了,因为它可以测量绝对角度。但是请注意的是,这个倾角必须是在物体静止或者匀速的情况下测量的,飞行器在运动过程中是测不准的。就好比闭眼蹦极的人,在失重的时候是不知道上下左右的。所以一般需要两个传感器配合,一个用来测变化量,一个用来修正误差。
加速度传感器同样分为数字型的和模拟型的,我看上的是ADXL345数字型三轴加速度传感器。

电子指南针
电子指南针也叫电子罗盘,也有人叫磁通传感器。它的原理跟指南针类似,通过测量某个截面内的磁通量大小来判断方向。它也可以是三轴的,其中垂直于南北极磁力线的那个截面会有最大的读数。这个指南针不是四轴飞行器必须的,因为平稳飞行靠前面两个传感器就够了。
但是试想一下这样的情况,我们遥控一个直升机的时候,可以看到机头的朝向,所以我们可以让他“前进/后退/左移/右移”。
而四轴飞行器是对称的,当你发出“前进”指令的时候,它并不知道你期望的是哪个方向的“前进”。
网上一种流行的方案是,给四轴飞行器的某条腿涂上鲜艳的颜色,作为“机头”,前进后退的参照系都是以它为准。但是这样就需要对遥控者有一定要求,需要能够迅速分辨方向。
我加上这个电子指南针,是希望它能和手机遥控器上的指南针对应起来,永远以遥控者的面向方向作为“前方”。当然这样会给算法带来更多的工作量,大家祝我好运吧 :)
我最终选择的芯片是HMC5883L三轴数字型电子指南针

其他还有一些零七八碎的东西,包括:
超声波测距传感器,用来测量离地高度;
蓝牙适配器,用来和手机通信;
洞洞板,用来组合这些传感器;
各种插针、排母、导线、开关;
机架,这个也可以自己做,现成的比较好看;

最后是某些网友非常关心的价格问题,下面的价格表仅供参考,最终还是请大家自己擦亮眼睛,货比三家。
必须提到的是一个小插曲,很多芯片的价格分为散件价格和模块价格。例如L3G4200D芯片,单买芯片据说30元就可以搞定;如果买现成的小电路板+所有电容电阻等配件,那么需要70元左右;如果这些小配件都帮你焊好的成品,大概需要160元左右。
看到这些价格之后,勤劳勇敢的圈妈大骂奸商,说要帮我焊上,省下这100块钱!结果散件回来以后我们都傻眼了,这是一种叫LGA的封装方式,花椒一样大的小芯片,肚子下面有十几根脚。而且这些脚是在芯片肚子下面,不是伸出来的!

新手焊不了的小芯片

新手焊不了的小芯片

圈妈硬着头皮焊了几下,发现基本所有的脚都连在一起了,最后弄掉了焊盘,彻底报废。所以建议新手们,如果没有专业焊接工具的话,就不要尝试省这100块钱了。

价格表(仅供参考!)
格氏11.1V2200mA25C锂电   128
B6充电器     160
郎宇A2212电机   62×4
天行者20A电调  48×4
四轴机架     88
三轴陀螺仪模块L3G4200D       160
三轴加速度ADXL345模块     50
三轴磁阻HMC5883L模块      70
蓝牙模块JY-MCU          40
超声波测距            16

盗梦陀螺攻略2- 线圈和传感器

相信很多人看过原理图之后,和我一样信心满满,这个东西太容易做了,不就是照图焊器件嘛,一星期就可以搞定了!

真正动起手来,才知道没那么容易。第一件事就郁闷了:去哪里找线圈?在淘宝搜了一大圈也没找到合适的。铜丝直径?线圈直径?线圈高度?绕多少匝?线圈之间距离?乱七八糟的好多事情,who tama knows!

最后只能去电子城买了一公斤的铜丝回来自己绕。那时候我还不知道有“线圈骨架”这么个名词,没找到合适的东西,就自己做了几个轴。于是出现了下面这么多奇形怪状的线圈:

奇形怪状的线圈们

奇形怪状的线圈们

更奇形怪状的线圈们

更奇形怪状的线圈们

细心的同学可能会发现,其中有些是带铁芯的(我分别用大螺丝和一毛钱的硬币柱当过铁芯),有些是没有铁芯的。事实证明,磁悬浮的线圈不能有铁芯!这点和我最初的直觉有点不符,因为觉得加了铁芯后磁场会更强。事实上因为我们的浮子是钕铁硼强磁,铁芯对它的吸力远大于线圈产生的磁力。也就是说,带铁芯的线圈只能产生“很大的吸力”和“更大的吸力”,没法产生“较小的吸力”和“较小的斥力”

绕线圈是一个非常痛苦的差事,我数过一个线圈平均大概是800匝左右,绕的我头昏眼花。所以后来做了一个绕线用的小东西,这就是我喜欢乐高的原因,很简单的一堆颗粒,可以拼出很多你想要的东西:

乐高制作的绕线器

乐高制作的绕线器

用绕线器绕出的线圈们

用绕线器绕出的线圈们

后来买了线圈骨架,这下绕的就好看多了。对于下推式磁悬浮,一共需要4个线圈。霍尔传感器尽量放在4个线圈的中心位置,这样的好处是线圈通电时,感应的磁场在中心处几乎都互相抵消了,只有浮子的移动才会影响到传感器的读数。

霍尔传感器安装在中心位置

霍尔传感器安装在中心位置

事实上,传感器的位置并不需要太严格。因为霍尔测量的是垂直它表面的磁通量。只要传感器的高度在线圈的高度中心,这里的磁通量都是平行与传感器的,也不会产生影响。

高度尽量居中

高度尽量居中

我的第一个版本的悬浮,传感器就是用胶布贴在侧面的中心,一样可以悬浮。缺点是浮子移动时,磁场的变化不是线性的,容易产生振动。

高度居中时,水平位置要求并不高

高度居中时,水平位置要求并不高

接线方面,互相对面的一组线圈之间反相连接。也就是说当在一对线圈两端通电时,一个会对浮子产生斥力,另一个会产生引力,正好是相反的,连推带拉才給力!

下面这个是背面的接线图,其中中心位置的是两个传感器,我把它们引出到两个杜邦头插针上,这样可以方便插拔。对面的线圈分别把相同极性的抽头焊在一起:

接线图,希望你能看懂

接线图,希望你能看懂

最后发一个关于线圈的经验小贴士,省的大家再重做无用功了:
1,产生相同的磁力,铜丝越细需要的电压越高,因为电阻比较大。我用的是0.27的铜丝,20V的电源。(用20V的原因是我有个坏掉的笔记本,利用下电源)
2,磁力的大小跟匝数关系不大,因为匝数增大的时候,电阻也增大,电流减小,产生的磁场差不多。但是匝数越多越省电。
3,四个线圈之间距离要稍大一点,浮子会更稳定,当然也别大的离谱,我的经验是线圈中心的直径和浮子直径差不多。
4,传感器的位置尽量在线圈中间,高度上也尽量放在中心的高度。
5,不要装铁芯。
6,给线头留长点,当你辛苦装上几个线圈,突然发现线头不够长的时候,会有看破红尘的感觉。

解魔方的机器人攻略20 – 修正电机误差

在上一篇攻略中,我们使用了一些角度的配置信息,例如:

//the motor angle for paw to hold the cube
static int PawHoldPosition = 56;
//the motor angle for paw to rotate the cube
static int PawTurnOverPosition = 110;

这些用于Motor.rotate(n)的角度,都是相对于电机的原始位置而言的。在我的代码里,初始位置是这样定义的:

颜色传感器和魔方底座的初始位置

颜色传感器和魔方底座的初始位置

爪子的初始位置

爪子的初始位置

在最初的版本里,我是在断电状态下,手动把电机拧到指定的初始位置。(程序一旦开始运行,角度信息就已经开始记录了,而且拧电机会有很大的阻力)
随后问题就来了,如果初始位置不准确的话,那么必然会导致旋转之后的位置不准确。其中最省心的是爪子的初始化位置,因为它是贴在后支架上,这个参照物非常稳定。

颜色传感器的杆很长,目测很难判断是否已经平行。魔方底座更是转十几次以后,误差越来越大。所以我们需要一段程序,把稍有偏差的初始位置纠正回来。

首先看一下如何修正魔方底座的误差。我们曾经介绍过,在魔方底座的下方安装了一个亮度传感器,当底座在某些位置的时候,会挡在亮度传感器的上面,再转过一定角度,就又把它露出来。亮度传感器有一个红色的小灯,可以通过light.setFloodlight(bool);来点亮或者关闭它。通过对比点亮和关闭前后的读数差,就可以判断出底座什么时候被挡住(在底座的下方需要贴一圈白纸,增强反光)。读数的曲线图是这样的:

读数的示意图

读数的示意图

也就是说,随着传感器被慢慢的挡住,这个亮度差值会越来越大,理论上最大值就是被挡住的中心位置。考虑到传感器的读数是有误差的,所以不能只取一个最大值点来计算,需要设置一个阀值,把最大的N个点都找到,那么它的中心位置就比较准确了。

//Fix the position of cube base
public static void FixBasePosition() throws Exception
{
int step = 3;
int tolerance = 4;
light.setFloodlight(false);
bottom.rotate(-50);
int angle = 0, minLight = 10000;
int realtimeLight = ReadLightDifference();
while(realtimeLight < minLight + tolerance)
{
bottom.rotate(step);
realtimeLight = ReadLightDifference();
if(realtimeLight < minLight)
{
minLight = realtimeLight;
angle = 0;
}
else
{
angle += step;
}
}
bottom.rotate(- angle/2 - FixBasePositionOffset);
}

//Read the light difference between light on and light off
private static int ReadLightDifference() throws Exception
{
int l1 = 0, l2 = 0;
l1 = light.readValue();
light.setFloodlight(true);
Thread.sleep(20);
l2 = light.readValue();
light.setFloodlight(false);
return l1-l2;
}

可以测试一下,把魔方底座手动拧歪一个小角度(正负十几度^_^),运行这段代码之后,底座会还原到和爪子平行的位置。

颜色传感器的位置修正比较简单:让它慢慢的靠近魔方,在传感器下方遇到魔方之前,它的读数都是0。所以一旦发现有读数,我们让它返回32度,就回到了爪子平行的位置,这个度数通过几次实验就可以试出来。

//Fix color sensor position
  public static void FixColorSensorPosition() throws Exception
  {
   int tolerance = 5;
   ColorMotorBaseAngle = -25;
   monitor.rotateTo(ColorMotorBaseAngle);
   Thread.sleep(100);
   monitor.setSpeed(50);
   int r = color.getRawRed();
   int g = color.getRawGreen();
   int b = color.getRawBlue();
   int baseColor = r + g + b;
   int TargetExists = 0;
   while(TargetExists < baseColor + tolerance && ColorMotorBaseAngle > -50)
   {
    monitor.rotateTo(ColorMotorBaseAngle--);
    r = color.getRawRed();
    g = color.getRawGreen();
    b = color.getRawBlue();
    TargetExists = r + g + b;
   }
   monitor.rotateTo(ColorMotorBaseAngle + 32);
  }

下面也做一个实验,把颜色传感器的位置拧歪,它也能回复到指定的位置。点此下载这个例子的全部代码。实验方法为:按Left键修正魔方底座位置,按Right键修正颜色传感器位置,按Escape键退出

时间仓促,每次贴的功能都不多,下一次介绍如何把魔方的颜色读取到数组中。

解魔方的机器人攻略12 – 安装传感器

这一节要介绍搭建结构的最后一个部分–安装各种传感器。之后我会继续发布软件部分的攻略。
正好今天有位小朋友留言问道,能不能分享源代码。我在这里统一回答一下:在这系列的攻略里,会讲到制作萝卜头所有需要的知识点和注意事项,也会逐步贴出所有源代码。但是在攻略写完之前暂时不会提供下载,因为我希望大家最终自己动手实现,这也正是DIY机器人的乐趣所在!在我制作的过程中,遇到了许多困难,你们已经不需要走太多弯路了(谁敢说我小气,我跟他急^_^)。

引用一段和菜头的话:上网以后,我们把信息当做了知识,把收藏当做了学习,把阅读当做了思考,把储存当做了掌握。像个花栗鼠在秋天收藏坚果一样,把自己的阅读器和硬盘塞满,却依旧觉得饥渴难耐。

言归正传了:

颜色传感器需要的颗粒

颜色传感器需要的颗粒

把颜色传感器安装到电机上

把颜色传感器安装到电机上

非常重要的一步!因为传感器的杆很长,需要一根橡皮筋来避免晃动。

非常重要的一步!因为传感器的杆很长,需要一根橡皮筋来避免晃动。知足吧,这一根皮筋是我被折磨了一星期之后才想到的...

 

超声波测距传感器

超声波测距传感器

安装在最高点,它的作用是判断转台上有没有魔方

安装在最高点,它的作用是判断转台上有没有魔方

亮度传感器

亮度传感器

组装成一个奇怪的样子

组装成一个奇怪的样子

安装的目标是这里

安装的目标是这里

安装之后的效果,注意看上面的底盘,贴了一圈白纸,原因在软件部分会介绍

安装之后的效果,注意看上面的底盘,贴了一圈白纸,原因在软件部分会介绍

距离上需要留一个2到3毫米的间隙

距离上需要留一个2到3毫米的间隙

固定NXT主体

固定NXT主体

从另一个角度看看怎么固定

从另一个角度看看怎么固定

最后的一些工作:接线,贴提示的彩条,把剩余的散件用来加固,还有就是化化妆

最后的一些工作:接线,贴提示的彩条,把剩余的散件用来加固,还有就是化化妆

接线方式说明:

电机A:爪子
电机B:魔方的旋转底盘
电机C:颜色传感器电机

传感器1:超声波测距传感器
传感器2:亮度传感器
传感器3:颜色传感器
传感器4:按钮(这个是我调试的时候用来中断的)