Wi-Fi小车记录3:Windows Phone 8.1 Runtime App编程

  在前两篇中,路由器已经刷入OpenWrt系统并安装了Ser2net等相关软件,如今就能够写一个客户端与路由器进行Socket通讯。一共有三个应用,桌面应用采用WPF编写,Windows Phone应用采用Windows Phone 8.1 Runtime架构,Win8应用也是Runtime,其实直接把WinPhone代码复制过去就能够直接生成一个Win8应用。windows

    本篇记录主要记录WinPhone应用编写过程。数组

  应用功能:利用重力感应控制小车左转、右转、前进、后退,点击视频能够查看车载摄像头视频画面。服务器

  先贴图,基本界面是这样,大部分都是拖出来的,尚未进行认真布局。架构

 

 利用Visual Studio 建立一个Windows Phone 8.1空白应用程序(Runtime版本)。而后就能够把上面一大堆TextBlock和Button控件拖出来。app

左上角一堆TextBlock分别是X-axis(加速度计x值),Y-axis(加速度计y值),Z-axis(加速度计z值),X二、Y2是红线上面一点的坐标。异步

中间那个”山“,左右两个是ProcessingBar(进度条),下面一条是蓝色的线,中间红色的线以两条线的交点为原点,随着手机左右摇摆而转动。async

  • 如何进行Socket通讯

    MSDN参考:http://msdn.microsoft.com/library/windows/apps/br226882布局

       这里用的是StreamSocket Class。ui

 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.aspxthis

    主要利用的是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         }

  至此,即可以正常像小车发送数据进行重力感应控制了。

相关文章
相关标签/搜索