NXT2.0的颜色传感器
由 动力老男孩 发表于 2010/09/29 20:56:30这几天尝试着把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的问题,开发起来会稍微麻烦点,不过毕竟不用再看环境光的脸色了,不错!