你说神睡觉吗?

By , May 27, 2008 4:37 pm

昨天晚上九点,早早的将清扬婉兮洗白白,放到她的小床上,关了灯又关了房门。没过多久,那边屋子便没了动静,我想她大概是已经睡着了吧,于是开始看《挪威的森林》。大概十点多的时候,小人突然轻声的叫爸爸,我想她可能想要喝水,于是到她的屋子去看看。结果,人家一点睡意都没有,一双眼睛瞪着蚊帐骨碌碌的转。看见我进来,小人轻声的问:“爸爸,你说神睡觉吗?”

这个问题我还真的没有想过,只好据实回答说:“这个我也不知道,可能也睡觉吧。你看宙斯不也要睡觉吗?”

小人还不满足,又问:“那不想长大的神是不是就不睡觉了呢?象Artemis?”

Artemis小时候是否睡觉,我可是一点头绪头没有。不过,Aremis后来肯定是长大了,这一点是毫无疑问的。于是我回答说:“Artemis后来都长大了嘛,我想她可能也睡觉的。”

小人引经据典打算拒绝睡觉的计划被我打败,说:“就是说我也应该睡觉咯?”

“对啊对啊。好好睡觉才能够……”

“够着高高杠子,才能够翻跟头。”

“对。好好睡吧。”

“爸爸,我爱你。我睡了。”

“我们也爱你。好好睡吧。”

我很庆幸小人没有问Eros是否睡觉 -- 这个问题回答起来要更难些。

[实验] 访问Sun SPOT上的传感器

By , May 26, 2008 5:47 pm

一、加速度计

图一、Sun SPOT的XYZ坐标图


图二、Sun SPOT的XY坐标方向

加速度是一个矢量。在使用Sun SPOT的加速度计之前,我们需要了解该矢量所使用的坐标系统。上面两个图形介绍了Sun SPOT的坐标系统,当Sun SPOT如图一所示水平放置时,Z 轴的方向为垂直向下,其加速度值为1G。

在应用程序的开头部分,您需要import与加速度计相关的类库:

import com.sun.spot.sensorboard.peripheral.IAccelerometer3D;

在应用程序中,声明一个IAccelerometer3D对象:

private IAccelerometer3D accel = EDemoBoard.getInstance().getAccelerometer();

获得X, Y, Z三轴上的加速度值:

double accelX = accel.getAccelX();
double accelY = accel.getAccelY();
double accelZ = accel.getAccelZ();

获得X, Y, Z三轴上的倾斜度:

double tiltX = accel.getTiltX();
double tiltY = accel.getTiltY();
double tiltZ = accel.getTiltZ();

在Sun SPOT自带的传感器上,自带的加速度计型号为LIS3L02AQ。该加速度计的测量范围可以设定为2G或者是6G,在测量范围不同的时候,其测量精度也 是不同的。如果我们需要在应用程序当中得到关于加速度计的更多信息,建议您直接使用类库LIS3L02AQAccelerometer。同样,在应用程序 的开头部分,您需要import与该加速度及相关的类库:

import com.sun.spot.sensorboard.peripheral.LIS3L02AQAccelerometer;

在应用程序中访问该加速度计:

private LIS3L02AQAccelerometer acc = (LIS3L02AQAccelerometer)EDemoBoard.getInstance().getAccelerometer();

LIS3L02AQAccelerometer是IAccelerometer3D的一个子类,所以上面所介绍的获得三轴加速度和倾斜度的方法仍然可以使用。

获得加速度计的当前测量范围。如果加速度计工作在2G状态,该方法返回SCALE_2G;如果加速度计工作在6G状态,该方法范围SCALE_6G。

public int scale = acc.getCurrentScale();

设定加速度计的测量范围为2G:

acc.setScale(acc.SCALE_2G);

设定加速度计的测量范围为6G:

acc.setScale(acc.SCALE_6G);

二、光照传感器

在应用程序的开头部分,您需要import与光照传感器相关的类库:

import com.sun.spot.sensorboard.peripheral.ILightSensor;

在应用程序中,声明一个ILightSensor对象:

private ILightSensor lightSensor = EDemoBoard.getInstance().getLightSensor();

读取光照强度,其数值范围在0 到740 之间。

int lightIndication = lightSensor.getValue();

三、温度传感器

在应用程序的开头部分,您需要import与温度传感器相关的类库:

import com.sun.spot.sensorboard.io.ITemperatureInput;

在应用程序中,声明一个ITemperatureInput对象:

private ITemperatureInput tempSensor = EDemoBoard.getInstance().getADCTemperature();

读取温度数据,用华氏度表示:

double tempF = tempSensor.getFahrenheit();

读取温度数据,用摄氏度表示:

double tempC = tempSensor.getCelsius();

四、使用控制按钮

在应用程序的开头部分,您需要import与控制按钮相关的类库:

import com.sun.spot.sensorboard.peripheral.ISwitch;

在应用程序中,声明两个ISwitch对象,其中sw1为左边的控制按钮,sw2为右边的控制按钮:

private ISwitch sw1 = EDemoBoard.getInstance().getSwitches()[0];
private ISwitch sw2 = EDemoBoard.getInstance().getSwitches()[1];

控制按钮实际上是一个数字开关,它可以被设置为开启和关闭两种状态。

检查sw1是否为开启状态:

boolean status = sw1.isOpen();

检查sw2是否为关闭状态:

boolean status = sw2.isClose();

您也可以让程序等待某个控制按钮的状态发生改变,例如:

sw1.waitForChange();

waitForChange()是一个阻塞方法。也就是说,它会停止当前线程的执行,一直到该控制按钮的状态发生改变为止。

在 更多的情况下,我们可能需要知道的是某个控制按钮是否曾经被按下(作为改变系统状态的某种信号),而并不关心其当前状态是开启还是关闭。一个简单的办法是 读取该控制按钮的当前状态并且与上一次的状态进行比较,如果结果不一样则判断该按钮的状态曾经被按下(因为其状态发生了改变)。

五、综合编程练习

编 写一个Sun SPOT应用程序,用LED模拟一个在水中作单向运动的小球。该小球可以是一个密度大于水的铁球,也可以是一个密度小于水的气球,使用左边的控制按钮改变 其密度状态。该小球的颜色可以使用温度或者是亮度来控制,当温度(亮度)较高的时候,小球的颜色为红色;当温度(亮度)较低的时候,小球的颜色为绿色;过 渡颜色为蓝色。

在完成这个编程练习的时候,可以参考Demo\CodeSamples这个目录里面的例程。

[实验] 第一个Sun SPOT应用

By , May 24, 2008 4:58 am

一、预备内容

首先,您需要安装JDKApache AntNetBeans以及Sun SPOT Manager。JDK 和Apache Ant都是使用Java语言进行应用开发的必备工具。你需要确保JDK和Ant的bin目录都在您的PATH环境变量里面。正确的安装JDK和Ant之后,您打开一个命令行窗口,应该 可以正确运行java、javac、ant命令。

更详细的安装和配置过程,请参考这个英语版的教程:http://www.sunstudentcourses.com/course/view.php?id=12

二、第一个Sun SPOT应用

下载源代码:SunSpotApplicationTemplate.zip 并解压缩。进入解压缩之后的文件夹。

(1) 检查连接到主机上的SPOT情况,可以使用如下命令:

ant info
ant slots

(2) 编译应用程序

ant jar-app

(3) 将应用程序部署到SPOT上

ant jar-deploy

(4) 运行部署到SPOT上的应用程序

ant run

我们看到,启动应用程序之后,左边第一个LED每3 秒左右闪烁一次红光。在主机屏幕上还能够找到“Hello, world!”这个字符串 — 这是SPOT向主机发送的一个信息。

三、理解这个SPOT应用程序

package org.sunspotworld.demo;

import com.sun.spot.peripheral.Spot;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.peripheral.radio.IRadioPolicyManager;
import com.sun.spot.io.j2me.radiostream.*;
import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.*;

import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class SunSpotApplication extends MIDlet {

/*
* SPOT中的虚拟机通过调用starApp方法来启动一个SPOT应用。
*/
protected void startApp() throws MIDletStateChangeException {

/*
* 标准输出为主机端
*/
System.out.println(“Hello, world”);

/*
* 监控SPOT是否通过USB连接到主机。如果是,获得从主机发送的命令。
*/
new BootloaderListener().start();

/*
* 获得自身的IEEE Mac地址
*/
IEEEAddress ourAddr = new IEEEAddress(Spot.getInstance().getRadioPolicyManager().getIEEEAddress());
System.out.println(“Our radio address = ” + ourAddr.asDottedHex());

/*
* 找到传感器板上的所有LED指示灯,用数组leds来表示
*/
ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();

/*
* 将第一个LED指示灯设置为亮度为100的红色
* 通常我们利用RGB来表示颜色,每个参数的数值范围在0到255之间。
*/
leds[0].setRGB(100,0,0);

/*
* 进入一个无限循环
*/
while (true) {

/*
* 点亮第一个LED指示灯(之前我们已经将其设置为亮度为100的红色)
*/
leds[0].setOn();

/*
* 等待1/4秒
*/
Utils.sleep(250);

/*
* 熄灭第一个LED指示灯
*/
leds[0].setOff();

/*
* 等待3 秒钟
*/
Utils.sleep(3000);
}
}

protected void pauseApp() {
// This will never be called by the Squawk VM
}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// Only called if startApp throws any exception other than MIDletStateChangeException
}
}

四、改进这个SPOT应用程序

现在,我们对这个应用程序进行一点改进。我们的目的是让第一、第二和第三个LED指示灯轮流点亮1/4秒,其颜色分别是全红,全绿和全蓝。完成一个循环过程之后,三个LED指示灯全部熄灭,等待3 秒钟,重新开始下一个循环。

修改过的应用程序片断如下:

ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
leds[0].setRGB(255,0,0);
leds[1].setRGB(0,255,0);
leds[2].setRGB(0,0,255);

while (true) {
leds[0].setOn();
Utils.sleep(250);
leds[0].setOff();
leds[1].setOn();
Utils.sleep(250);
leds[1].setOff();
leds[2].setOn();
Utils.sleep(250);
leds[2].setOff();
Utils.sleep(3000);
}
我们重新编译、部署和运行这个应用程序:

ant jar-app
ant jar-deploy
ant run

你的第一个SPOT应用程序,就这么简单。我建议各位充分发挥想象力,看看能够用8 只LED做什么事情。

[讲义]无线传感器网络技术 -- 介绍

By , May 22, 2008 5:52 pm

这是昨天晚上在北京交通大学软件学院做的一场关于无线传感器网络技术的介绍性讲座。 这个讲座简单介绍无线传感器网络的基本概念以及发展历史,包括传感器、传感器网络、无线传感器网络。通过一些实际的或者是实验性的案例,说明传感器网络和无线传感器 网络目前的应用状况和将来的应用前景。 在讲座的后半部分,将介绍PC-104, UCB Mote和Sun SPOT等现有的无线传感器网络平台,并且利用Sun SPOT做一些演示。讲座的目的,是让学生了解这个新兴技术,培养对这个技术方向的兴趣。愿意在这个方向发展的学生,可以加入我们的无线传感器网络项目小 组,在Sun SPOT上面自己做一些项目。

演讲文稿:

OpenOffice格式:01_WSN_Introduction.odp
Microsoft Office格式:01_WSN_Introduction.ppt

由于原始的演示文稿是利用OpenOffice(其实是Mac OS上的NeoOffice)制作的,所以OpenOffice格式的文稿格式会好一点,建议各位使用这个版本。

演示录像:

无人驾驶飞行器一:气球
无人驾驶飞行器二:直升飞机

探索者

By , May 21, 2008 6:31 pm

这是一个模拟无线游戏操纵杆的演示。在PC机端连接一个Sun SPOT作为接收机,一个移动的Sun SPOT作为操纵杆。本演示包括两个Java项目,一个运行在Host端(主机),另外一个运行在远程端(远程移动SPOT)。

主机应用程序:CarDemo
远程应用程序:TrackbotEnhancedRemote

将如上压缩包解压缩之后,在主机端的源代码文件夹(src)里面找到TrackbotJoystickReceiver.java文件,寻找字符串“0014”,就可以找到类似于下面这行的一段代码:

String joystickAddress = “0014.4F01.0000.0FC9″;

字符串joystickAddress代表的是远程SPOT的MAC地址,请将其修改成您的远程SPOT的MAC地址。该地址可以在您的SPOT的天线上找到。

同样,在远程端的resources\META-INF文件夹里面找到manifest文件,里面有类似于下面这行的一段代码:

trackbotAddress: 0014.4F01.0000.1301

字符串trackbotAddress代表主机SPOT的MAC地址,请将其修改成您的主机SPOT的MAC地址。该地址可以在您的SPOT的天线上找到。

我们首先编译和部署远程SPOT的应用程序。将远程SPOT通过USB电缆连接到主机上,在命令提示符下进入TrackbotEnhancedRemote目录,执行如下命令:

ant
ant deploy
ant run

这时候远程SPOT就已经部署好了。将其从主机上移走,并将主机SPOT连接到主机上。在命令提示符下进入CarDemo目录,执行如下命令:

ant

好啦。现在你应该能够看到本文所附图片的场景了。转动、倾斜、或者是摇摆你的远程SPOT,看看会发生什么事情。另外,你还可以按一按SPOT上面的两个控制按钮,也许会发生一些意想不到的事情呢。

Panorama Theme by Themocracy