蓝牙手机变身小车遥控器 (3)
由 动力老男孩 发表于 2010/03/26 00:13:16发现已经一星期没有更新博客了,真是非常抱歉。上周做完手机遥控器以后,一直没有其他进展,也没来得及发攻略。接下来的时间可能会更忙,只能先跟大家说声抱歉了。在此严重羡慕一下大苹果同学,这个家伙周末带mm飞去武汉大学看樱花了,眼红啊。。。
今天跟大家分享一下在Windows Mobile环境里,如何配置和调用Web Service(就是上次说的四个程序中的第二个)。
一、首先配置开发环境,需要安装下面的几个东东:
1,VS2008 及其 SP1
2,Windows Mobile 6 Professional SDK Refresh.msi
3,Windows Mobile 6.5 Professional Developer Tool Kit (CHS).msi
安装之后,在“新建工程”菜单里,就可以看到智能手机的选项:
新建智能手机项目只有一个选项,输入项目名称后,单击进入下一步,选择平台版本:
单击确定,一个新的手机项目就建好了。
二、控件,编译和部署
试着拖两个按钮到手机界面上去,你可以发现跟普通的windows应用程序开发是类似的。我添加了三个按钮,分别是“启动”,“停止”和“退出”。双击“退出”按钮,对按钮添加相应的事件,其他两个按钮稍后再说:
private void ExitButton_Click(object sender, EventArgs e) { this.Dispose(); this.Close(); }
选择菜单中的“编译->编译项目”,然后到这个项目的文件夹目录里面翻一翻,在 \PhoneRemoteControl\bin\Debug目录下,可以发现多了个exe文件。
先别激动,这个文件在电脑上双击是不能运行的。必须要复制到手机上,用你的手指头单击它,然后发现……还是不能运行。
嗯,这是因为你的人品不够好,弥补办法是去微软网站上下载一个叫“NET Compact Framework”的东西并安装上。
好了,再用一阳指点一下,这次可以看到软件的界面了,再点一下“退出”按钮,程序就退出了(好像是废话)
三、调用Web Service
首先要在工程中引用WebService:在工程名字上用右键,弹出的菜单中选择“add web reference”。我这个是英文版,不知道中文版里叫什么,参考一下吧:
在接下来的设置窗口里,输入上一步中做好的web service地址,另外给它起个名字叫“PingService”:
添加了service之后,咱们看看怎么调用,非常简单,用一个函数就可以了:
private void WCFRequestCall(string data) { PingService.Ping client = new PhoneRemoteControl.PingService.Ping(); client.Url = "http://chenwu03/service/ping.asmx"; client.SetData(data); }
这里有一句 client.Url=”…”; 这个为部署修改用的,例如你开发的时候用chenwu03,将来可能换到另一台电脑上,那么在这里改成chenwu04就可以了。建议把这个参数放到配置文件里,这样如果需要修改的话,不需要改代码重新编译,直接用写字板改一下配置文件即可。
四、在手机上画方向盘
其实想要遥控小车,用前进后退,左转右转几个按钮就可以了。但是为了捍卫Dev的尊严,我决定做的花哨一点,于是很骚包的画了一个方向盘。在Form中绘图,可以在一个叫Form1_Paint的函数中添加程序,不说废话,看代码吧:
private void Form1_Paint(object sender, PaintEventArgs e) { int windowWidth = 480; int borderOffset = 40; int topStart = 160; int lineOffset = 25; int r = windowWidth / 2 - borderOffset; Graphics g = this.CreateGraphics(); Pen pen = new Pen(Color.Red); pen.Width = 3; pen.DashStyle = DashStyle.Dash; g.DrawLine(pen, borderOffset-lineOffset, topStart + r, windowWidth - borderOffset+lineOffset, topStart + r); g.DrawLine(pen, windowWidth / 2, topStart - lineOffset, windowWidth / 2, topStart + 2 * r + lineOffset); pen.Color = Color.Blue; pen.DashStyle = DashStyle.Solid; pen.Width = 8; g.DrawEllipse(pen, borderOffset, topStart, 2 * r, 2 * r); steeringWheel.CenterX = windowWidth / 2; steeringWheel.CenterY = topStart + r; steeringWheel.R = r; }
画出来的效果如下:
五,计算小车的速度
因为Arduino中,直流电机的控制是通过PWM管脚输出的,值范围是0~1023;所以我让手机发出的数据就是简单的“VLeft,VRight”,值的范围都是从0到1023,用正负号表示前进还是后退。
设计的思路是,点击圆圈的正上方时,两个轮子都向前走,离圆心越近速度越慢,最远的地方发送的数据是“1023,1023”;
类似的,点击最下面时,发送的数据是“-1023,-1023”;
当点击圆圈的左边时,我会把右侧的速度变大,左侧的速度变小,这样小车就向左转了;
当点击到圆圈外面时,直接忽略掉。
需要注意的是,在实际操作中,当输出速度低于300时,电机其实已经带不动了,所以我把低于300的值全都重置成0。这部分代码就不贴了,反正大家可以按照自己的喜好编写控制代码。需要的同学可以下载代码回去参考下。
至于上面提到的“启动”和“停止”按钮,我们就发送“600,600”,“0,0”两组数据即可
六、发送数据
当你的咸猪手在手机上乱摸时,我是用Form1_MouseMove来响应事件的。事实证明,这个数据发送的频率太高了,每秒钟会发送几百组速度。为了回避这个问题,我们设置一个定时器,每隔150毫秒执行一次,中间MouseMove的事件全部扔掉。
private string currentCommand = ""; private string lastCommand = ""; private void SendTimer_Tick(object sender, EventArgs e) { if (!string.IsNullOrEmpty(lastCommand)) { currentCommand = lastCommand; lastCommand = ""; } if (!string.IsNullOrEmpty(currentCommand)) { WCFRequestCall(currentCommand); currentCommand = ""; } }
好了,接下来是检查工作成果。用手指头在屏幕上一阵乱摸,可以从端口监视器里看到不断跳出来的数组:
有经验的同学可能有两个问题:
1,为什么不直接用WebRequest发起请求呢?
这个我试过,手机容易死机,原因还不清楚
2,为什么不直接用TCP/IP发送数据到PC端口呢,绕这么大一圈?
这个我也试过,程序不会出错,但是电脑上也没有接到数据,原因依然不清楚
不管怎么说,反正试出来一个可行的方法。这篇博客中提到的源代码在这里下载,其他部分下回继续:
http://www.diy-robots.com/Resources/XiaoI/PhoneRemoteControl.zip