Wi-Fi小车记录3:Windows Phone 8.1 Runtime App编程
2014-12-10 11:29 X.Zh 阅读(92) 评论(0) 收藏 举报在前两篇中,路由器已经刷入OpenWrt系统并安装了Ser2net等相关软件,现在就可以写一个客户端与路由器进行Socket通信。一共有三个应用,桌面应用采用WPF编写,Windows Phone应用采用Windows Phone 8.1 Runtime架构,Win8应用也是Runtime,其实直接把WinPhone代码复制过去就可以直接生成一个Win8应用。
本篇记录主要记录WinPhone应用编写过程。
应用功能:利用重力感应控制小车左转、右转、前进、后退,点击视频可以查看车载摄像头视频画面。
先贴图,基本界面是这样,大部分都是拖出来的,还没有进行认真布局。


利用Visual Studio 创建一个Windows Phone 8.1空白应用程序(Runtime版本)。然后就可以把上面一大堆TextBlock和Button控件拖出来。
左上角一堆TextBlock分别是X-axis(加速度计x值),Y-axis(加速度计y值),Z-axis(加速度计z值),X2、Y2是红线上面一点的坐标。
中间那个”山“,左右两个是ProcessingBar(进度条),下面一条是蓝色的线,中间红色的线以两条线的交点为原点,随着手机左右摇摆而转动。
- 如何进行Socket通信
MSDN参考:http://msdn.microsoft.com/library/windows/apps/br226882
这里用的是StreamSocket Class。
1 try 2 { 3 StatusText.Text = "正在尝试连接。。。"; 4 //新建hostname,用服务器ip地址初始化 5 HostName serverHost = new HostName("192.168.1.1"); 6 //调用连接异步方法,2001为ser2net程序的端口号 7 await clientSocket.ConnectAsync(serverHost, "2001"); 8 connected = true; 9 StatusText.Text = "Connection established" + Environment.NewLine; 10 } 11 catch (Exception exception) 12 { 13 StatusText.Text = "Connect failed with error:" + exception.Message; 14 }
- 如何发送数据
MSDN参考http://msdn.microsoft.com/zh-cn/library/windows/apps/windows.storage.streams.datawriter.aspx
主要利用的是DataWriter Class
1 uint len = 0; 2 byte[] bytedata = new byte[10]; 3 //data是要传送的string,将其转化为Byte[]数组进行传送 4 bytedata = Encoding.UTF8.GetBytes(data); 5 try 6 { 7 StatusText.Text = "Trying to send data..."; 8 //新建DataWriter对象,用StreamSocket.OutputStream进行初始化 9 using(DataWriter writer = new DataWrite(clientSocket.OutputStream)) 10 { 11 //获取要传送的字节数组的长度 12 len = writer.MeasureString(data); 13 //向输出流写入数据 14 writer.WriteBytes(bytedata); 15 await writer.StoreAsync(); 16 await writer.FlushAsync(); 17 writer.DetachStream(); 18 19 20 } 21 22 StatusText.Text = "Data " + data + " was sent."; 23 } 24 catch (Exception) 25 { 26 StatusText.Text = "Send data or receive failed with error: "; 27 28 29 }
- 如何接收数据
MSDN参考:http://msdn.microsoft.com/zh-cn/library/windows/apps/windows.storage.streams.datareader
接收数据不像发送那样,需要发送的时候直接调用方法即可。接收数据需要单独用一个线程进行周期性的检查,不如我这里就是没100ms(delay的值)接收一次,如有数据便显示在文本框中。
1 //利用线程池对象创建一个周期性工作的计时器。 2 //调用的方法是ThreadPoolTimer.CreateTimer(TimerElapsedHandler, TimeSpan) 3 //其中第一个参数是即时结束事件处理委托,这里用Lambda表达式 处理。 4 5 ThreadPoolTimer timer = ThreadPoolTimer.CreatePeriodicTimer( 6 async (source) => 7 { 8 if (!connected) 9 { 10 StatusText.Text = "Must be connected to send!"; 11 return; 12 } 13 //创建DataReader对象,用输入流初始化 14 DataReader reader = new DataReader(clientSocket.InputStream); 15 //异步方法,载入一个字节 16 reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; 17 reader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian; 18 await reader.LoadAsync(1); 19 while (reader.UnconsumedBufferLength > 0) 20 { 21 22 s += reader.ReadString(reader.UnconsumedBufferLength); 23 if (s.Length == 50) 24 s = ""; 25 } 26 reader.DetachStream(); 27 //创建要提交到线程池的工作项来更新UI 28 //RunAsync参考:http://msdn.microsoft.com/zh-cn/library/windows/apps/windows.system.threading.threadpool.runasync.aspx 29 30 31 await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, 32 () => 33 { 34 ReceiveDataBlock.Text = s; 35 } 36 ); 37 }, delay 38 39 );
- 如何获取重力感应信息
MSDN参考:http://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/hh465272.aspx
参考文档可以直接复制过来就用。
1 private async void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e) 2 { 3 await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 4 { 5 this.reading = e.Reading; 6 //三个文本框中分别显示出当前加速度计x,y,z的值 7 txtXAxis.Text = String.Format("{0,5:0.00}", reading.AccelerationX); 8 txtYAxis.Text = String.Format("{0,5:0.00}", reading.AccelerationY); 9 txtZAxis.Text = String.Format("{0,5:0.00}", reading.AccelerationZ); 10 if (!(Math.Abs(this.PreviousY-reading.AccelerationY)<=0.02)) 11 { 12 //计算红线端点的坐标,显示在对应的文本框中 13 Pointer.X2 = (-140 * Math.Sin(Math.PI / 2 * reading.AccelerationY) + 320); 14 Pointer.Y2 = (-140 * Math.Cos(Math.PI / 2 * reading.AccelerationY) + 280); 15 X.Text =string.Format("{0,5:0.00}", Pointer.X2); 16 Y.Text =string.Format("{0,5:0.00}", Pointer.Y2); 17 int i=(int)Math.Abs(reading.AccelerationY*10); 18 string s=i.ToString(); 19 //z<0.5 向前走 20 if(reading.AccelerationZ<=0.5) 21 { 22 if (!(Math.Abs(reading.AccelerationY - previous) < 0.05)) 23 { 24 if (reading.AccelerationY > 0) 25 //发送控制数据 26 SendData("ADL" + s + "A"); 27 else if (reading.AccelerationY < 0) 28 SendData("ADR" + s + "A"); 29 sentBack = false; 30 } 31 } 32 //z>0.5 向后退 33 else if (reading.AccelerationZ > 0.5&&sentBack==false) 34 { 35 SendData("ADB0A"); 36 sentBack = true; 37 } 38 previous = reading.AccelerationY; 39 } 40 }); 41 42 43 }
至此,便可以正常像小车发送数据进行重力感应控制了。
浙公网安备 33010602011771号