C# 蓝牙编程

1. 蓝牙配对

正所谓千里姻缘一线牵,首先我们要给NXT和PC安排一个相亲大会。NXT已经内置了蓝牙模块,要把它设置成打开并且可见的状态。设置方法请看Lejos的中文教程“蓝牙菜单”。现在很多笔记本也自带了蓝牙模块,如果没有的话,必须买一个蓝牙适配器。注意WinXP开始就都已经自带蓝牙驱动了,如果你的电脑安装了第三方的蓝牙驱动,最好先删除。

蓝牙适配器

蓝牙适配器

准备好定情信物以后,就该安排PC和NXT见面了。PC比较主动,由他开负责寻找:

控制面板中旋转“添加新的蓝牙设备”,可以找到当前可见的NXT

控制面板中旋转“添加新的蓝牙设备”,可以找到当前可见的NXT

找到NXT后,两人会羞答答的先来个握手协议,接下来是交换电话号码。Lejos设置的蓝牙连接密码是1234

输入蓝牙连接密码

输入蓝牙连接密码

你看他们一个是能力超强,名车豪宅,另一个能歌善舞,秀色可餐。简直就是一拍即合啊。到此牵线完毕,以后他们就可以直接通讯了。我们查看一下电脑上的NXT属性,可以看到有个带“DevB”的端口,这个相当于是他们之间的私人电话,记下来后面会用到。

注意看端口号

注意看端口号

2. C#中使用蓝牙通讯

其实配对以后,蓝牙就被模拟成了一个端口,我们可以用最简单的端口通讯来收发信息。首先,在每次启动时,需要连接端口:

  1. BluetoothConnection = new SerialPort();  
  2. ConnectButton.Enabled = false;  
  3. BluetoothConnection.PortName = PortList.SelectedItem.ToString();  
  4. BluetoothConnection.Open();  
  5. BluetoothConnection.ReadTimeout = 10000;  
  6. BluetoothConnection.DataReceived += new SerialDataReceivedEventHandler(BlueToothDataReceived);  

然后可以通过这个端口来发送信息。需要注意的是,在发送的原始数据之前,需要添加两个表示长度的字节,Byte[0]+Byte[1]*255=length。所以发送数据的函数如下:

  1. private void BlueToothDataSend(byte[] data)  
  2. {  
  3.     int length = data.Length;  
  4.     byte[] readData = new byte[length + 2];  
  5.     readData[0] = (byte)(length % 255);  
  6.     readData[1] = (byte)(length / 255);  
  7.     for (int i = 0; i < length; i++)  
  8.     {  
  9.         readData[i + 2] = data[i];  
  10.     }  
  11.     BluetoothConnection.Write(readData, 0, length + 2);  
  12.     Status = "发送数据字节数:" + length;  
  13. }  

收到数据的时候,也是类似的情况,头两个字节表示了数据的长度,然后才是真正的数据内容:

  1. private void BlueToothDataReceived(object o, SerialDataReceivedEventArgs e)  
  2. {  
  3.     int length = BluetoothConnection.ReadByte();  
  4.     length += BluetoothConnection.ReadByte() * 256;  
  5.   
  6.     byte[] data = new byte[length];  
  7.     BluetoothConnection.Read(data, 0, length);  
  8.     for (int i = 0; i < length; i++)  
  9.     {  
  10.         BlueToothReceivedData += string.Format("data[{0}] = {1}\r\n", i, data[i]);  
  11.     }  
  12. }  

断开蓝牙连接的命令如下:

  1. BluetoothConnection.Close();  
  2. BluetoothConnection.Dispose();  
  3. BluetoothConnection = null;  

3. Lejos中使用蓝牙通讯

在Lejos中使用蓝牙有几点区别:首先,Lejos中不支持收到消息的事件触发(我怀疑用多线程可以实现,不过对Java不太熟悉,没有调试成功)所以在需要接受PC信息时,只能挂起等候消息传来;其次,虽然PC发来的信息头两个字节表示长度,但是Lejos接收时,是从第三个字节开始显示的;另外,Lejos发送蓝牙信息时,不需要添加那两个字节的长度信息。

下面是建立蓝牙连接的方式:

  1. public static void Connect() throws Exception  
  2. {  
  3.     LCD.clear();  
  4.     LCD.drawString("Waiting BTC...",0,0);  
  5.     btc = Bluetooth.waitForConnection();  
  6.     LCD.drawString("Connected",0,2);  
  7.     LCD.refresh();  
  8.     dis = btc.openDataInputStream();  
  9.     dos = btc.openDataOutputStream();  
  10. }  

接受蓝牙信息:

  1. public static byte[] ReadBytes() throws Exception  
  2. {  
  3.   byte[] buffer = new byte[255];  
  4.   int length = btc.read(buffer, buffer.length);  
  5.   if(length==-2)  
  6.   {  
  7.    //lost data, re-sync  
  8.    btc.read(null, 255);  
  9.    return new byte[0];  
  10.   }  
  11.   else  
  12.   {  
  13.    byte[] data = new byte[length];  
  14.    for(int i=0;i<length;i++)  
  15.    {  
  16.     data[i] = buffer[i];  
  17.    }  
  18.    return data;  
  19.   }  
  20. }  

发送蓝牙信息

  1. public static void WriteBytes(byte[] data) throws Exception  
  2. {  
  3.  for(int i=0;i<data.length;i++)  
  4.  {  
  5.   dos.writeByte(data[i]);  
  6.  }  
  7.  dos.flush();  
  8. }  

关闭蓝牙连接

  1. public static void Disconnect() throws Exception  
  2. {  
  3.    if(btc!=null)  
  4.    {  
  5.     WriteBytes(new byte[]{(byte)255,(byte)255,(byte)255});  
  6.     Thread.sleep(100);  
  7.     dos.close();  
  8.     dis.close();  
  9.     btc.close();  
  10.    }  
  11. }  

4. 蓝牙通讯小实验

下面进行一个小实验,在PC上运行一个程序。
当发送1时,NXT初始化魔方底盘位置;
当发送2时,NXT初始化颜色传感器位置;
当发送3时,NXT读取颜色信息,并回传给电脑;
当发送其他数字时,NXT断开蓝牙连接,并退出程序

 

蓝牙连接通讯实验

蓝牙连接通讯实验

 

大部分函数在前面都介绍过了,只需要在main函数中指定操作即可:

  1. BlueTooth.Connect();  
  2. byte[] colorData = new byte[6];  
  3.   
  4. while(true)  
  5. {  
  6.  byte[] readData = BlueTooth.ReadBytes();  
  7.  if(readData.length > 0)  
  8.  {  
  9.   int action = readData[0];  
  10.    switch(action)  
  11.   {  
  12.   case 1:  
  13.    Robot.FixBasePosition();  
  14.    break;  
  15.   case 2:  
  16.    Robot.FixColorSensorPosition();  
  17.    break;  
  18.   case 3:  
  19.       colorData[0] = (byte) color.getRed();  
  20.       colorData[1] = (byte) color.getGreen();  
  21.       colorData[2] = (byte) color.getBlue();  
  22.       colorData[3] = (byte) (color.getRawRed() / 3);  
  23.       colorData[4] = (byte) (color.getRawGreen() / 3);  
  24.       colorData[5] = (byte) (color.getRawBlue() / 3);  
  25.       BlueTooth.WriteBytes(colorData);  
  26.       break;  
  27.   default:  
  28.    BlueTooth.Disconnect();  
  29.    return;  
  30.   }  
  31.  }  
  32.  Thread.sleep(1000);  
  33. }  

好了,其余部分自己看代码吧,搭车赠送一个生成三维魔方图形的小程序。点此查看运行在NXT中Java源代码代码;点此下载运行在电脑上的C#程序源代码。

posted @ 2016-11-17 10:16  未来,已来  阅读(1649)  评论(0编辑  收藏  举报