Posts Tagged ‘颜色传感器’

NXT2.0的颜色传感器

这几天尝试着把NXT2.0的颜色传感器换到萝卜头身上。因为新传感器自带光源,这样对环境光的依赖性会比较小。摸索了几天,终于实验成功了。现在在日光,灯光和昏暗条件下,基本都能读出颜色。缺点是这个传感器对颜色块的区域要求比较高,必须对准了才好用,这对于魔方的小方块来说真是有点痛苦。

再次提醒一下各位,原来的lejos API是有bug的,程序猎人同学已经帮大家编译了一个新的版本,请替换\lejos_nxj\lib目录中classed.jar文件即可:
http://www.diy-robots.com/RubikSolver/classes.jar

这个传感器共有红绿蓝三种灯,但是不能随意组合。下面的例子表示如何读取一个色块的红色分量。

ColorLightSensor color = new ColorLightSensor(SensorPort.S1, ColorLightSensor.TYPE_COLORRED);
int red = color.getRedComponent();

如果你只是想让红色的灯亮起来,可以这样:

//方法1:指定TYPE_COLORRED,然后用setFloodlight(true);
ColorLightSensor color = new ColorLightSensor(SensorPort.S1, ColorLightSensor.TYPE_COLORRED);
color.setFloodlight(true);
//方法2:直接设置灯的颜色;
color.setFloodlight(Colors.Color.RED);

蓝色和绿色的操作和红色类似。需要注意的是,我们没法任意组合两种颜色,例如你点亮了红灯,绿灯就自动关掉了。
另外,设置TYPE_COLORFULL也不能同时点亮三种灯,反而是全部灭的。那么如果我们想同时读三种颜色,可以用下面两种方法:

//方法1:readValues函数,注意arr长度为4
int[] arr = new int[4];
color.setType(ColorLightSensor.TYPE_COLORFULL);
color.readValues(arr);
LCD.clear();
LCD.drawString("r=" + arr[0], 0, 0);
LCD.drawString("g=" + arr[1], 0, 1);
LCD.drawString("b=" + arr[2], 0, 2);
LCD.drawString("n=" + arr[3], 0, 3);

//方法2:getColor函数,注意arr长度为3
arr = color.getColor();
LCD.clear();
LCD.drawString("r=" + arr[0], 0, 0);
LCD.drawString("g=" + arr[1], 0, 1);
LCD.drawString("b=" + arr[2], 0, 2);

请注意,调用readValues方法之前必须使用setType函数,否则灯不会亮。返回的数组长度是4,据我估计是在这一瞬间,传感器依次把红绿蓝三种灯依次闪了一遍,并依次记下当前的光强,最后一个参数表示COLOR.NULL,也就是不亮灯情况下的环境光强。
getColor函数的返回结果只有三个,有兴趣的同学可以参考lejos的源代码,这两个函数其实基本上是一样的,貌似只是取了数组的前三个,然后输出结果:

public int[] getColor() {
	int temp_type =  this.type;
	setType(ColorLightSensor.TYPE_COLORFULL);
	int [] all_vals = new int[4];
	readValues(all_vals);
	int [] rgb_vals = new int[3];
	System.arraycopy(all_vals, 0, rgb_vals, 0, 3);
	this.setType(temp_type);
	return rgb_vals;
}

这里用了一个临时的temp_type变量来记录传感器原来的设置,读完颜色后需要再还原,另外还额外需要一个数组复制的过程。理论上来说,这些操作的时间开销都是非常小的。但是不知道为什么,getColor函数的调用时间比readValues多很多,从我循环调用的测试来看,时间相差接近10倍,真是太邪门了。

总结一下,NXT2.0的颜色传感器貌似比原来那个更酷一点,取色的区域略小,但是功能更多一点。因为API的问题,开发起来会稍微麻烦点,不过毕竟不用再看环境光的脸色了,不错!

出手NXT2.0 8547

家里有一套lego NXT 9797,做好萝卜头以后,有时候想做点东西玩,总是不舍得把它拆了,但是再买一套又觉得有点贵。圈圈妈是属于豪放派的,严重鄙视我这种葛朗台的行径。上周末借口圈圈百天,给我买了一套NXT2.0。嘿嘿,说明书上分明写着“10岁以上适用”。好吧,十年后我一定把这套玩具还给圈圈:)

NXT 2.0

NXT 2.0

和原来的9797大体对比了一下,传感器方面少了亮度传感器(light sensor)和声音传感器(sound sensor),但是多了一个按钮(奸商们管这个叫触觉传感器touch sensor)和一个颜色传感器(color sensor)。另外9797有一个锂电,8547没有。

颗粒方面,8547没有那个大齿轮盘(48452cx1),所以想用8547做魔方机器人的朋友,只能改变设计结构或者单独买这个齿轮了。
48452cx

其实我最关注的还是那个颜色传感器,毕竟当年萝卜头就是在判断颜色的时候吃尽苦头,我很想看看新传感器效果如何。8547带的颜色传感器是乐高公司自己生产的,而我之前用的那个是HiTech公司生产的,看下面这个图,其中三角眼的是乐高公司产品,斗鸡眼的是HiTech公司的产品:

两个公司的传感器对比

两个公司的传感器对比

因为这个传感器是新产品,所以我原来的代码不能直接使用(lejos 0.6版本)。从lejos的官网上看到NXJ 0.85版本支持NXT2.0的颜色传感器,迅速找了根牙签,把固件刷新到0.85。关于这根神奇的牙签如何使用,请猛击这里并搜索“牙签”关键字。

需要注意的是,在0.85的API里,有ColorSensor和ColorLightSensor两种传感器,其中ColorSensor对应HiTech公司的那个,ColorLightSensor对应的乐高公司的。从API文档看了下,重点有下面几个函数:

构造函数:ColorLightSensor(SensorPort port, int type)
其中port是类似SensorPort.S1的端口号,type是一组Enum的值,设置的type可以在setType函数中修改。

获取颜色:int[] getColor()
返回的数组长度为4,分别是R,G,B和Null,其中RGB好理解,分别对应红黄蓝的颜色分量,最后一个分量暂时扔一边不管

设置照明:void setFloodlight(boolean floodlight)
这个函数用来开关传感器的灯光,和之前亮度传感器的类似。这个函数还有另外一个重载,参数是颜色值,我编译没有通过所以没有测试。

设置模式:void setType(int type)
这里的type和构造函数里的type是一样的,有下面几种值:

ColorLightSensor.TYPE_COLORFULL     //读取全部颜色
ColorLightSensor.TYPE_COLORRED      //只读红色
ColorLightSensor.TYPE_COLORGREEN    //只读绿色
ColorLightSensor.TYPE_COLORBLUE     //只读蓝色
ColorLightSensor.TYPE_COLORNONE     //不知道是啥,可能是不开背景灯的意思吧

让我非常恼火的是,这个版本的API默认是有问题的,读出来的颜色值都是0。根据忧郁飞花同学的提示,我在Lejos的论坛上找到了答案,有兴趣深入了解的同学请看原帖

按帖子中的方法修正了bug,传感器终于亮了而且可以读数了,效果非常好!因为有照明的缘故,在伸手不见戒指的晚上也读数。
看看很炫的效果图,分别是不同的type模式下setFloodlight(true)的照片:

lego的颜色传感器,可以当彩灯了

lego的颜色传感器,可以当彩灯了

摸黑读了一圈颜色,下面是一组数据,看上去效果很不错。
蓝:118,125,213
绿:102,196,148
红:280, 80, 79
橙:296,134,101
黄:300,237,107
白:323,318,324

试验完毕,在此感谢下假公济私的圈圈妈 :)

解魔方的机器人攻略9 – 颜色传感器电机

接下来的任务是安装驱动颜色传感器的电机。为什么我们要把这这部分安装在斜面支架上呢?因为颜色传感器是用来读魔方颜色的,按照说明书的要求,读数时必须距离2~3厘米,并垂直于目标物体的表面。所以魔方是斜的,传感器也必须是斜的。

有人给我提意见,怎么每次都只更新这么一点,一次多发点吧。

其实帖子就像姑娘的裙子,太短了盖不住主题,太长了又没有吸引力,差不多就行啦:)

之前我试过发特别长的攻略,我家娘子打开页面的时候,被不断缩短的滚动条吓的手一哆嗦。。。。又关掉了。。。

下面进入正题:

准备一个延长杆和一个直角连杆

准备一个延长杆和一个直角连杆准备好电机和一些连接件

准备好电机和一些连接件

准备好电机和一些连接件

神奇吧,电机正好连上,不过还有点晃晃悠悠的

神奇吧,电机正好连上,不过还有点晃晃悠悠的真是两个加固的小件

这步有点费解,刚才的两个小件是加到了连杆的下面,另外因为件不够了,我把上面的普通横杆换成了疙里疙瘩的连杆

这步有点费解,刚才的两个小件是加到了连杆的下面,另外因为件不够了,我把上面的普通横杆换成了疙里疙瘩的连杆

准备延长底座,一直要延伸到爪子那边

准备延长底座,一直要延伸到爪子那边

延长后的底座,正好顺路看看刚才比较费解的电机连接部分

延长后的底座,正好顺路看看刚才比较费解的电机连接部分

这一部分拍的照片有点少,不过乐高积木就是有这点好处,你想怎么蹂躏它都可以,只要接在一起就可以了,不一定非要完全按照我的接法。下一篇我们将要连上驱动爪子的电机!