智慧城市让生活更美好!
物联网  >   传感器  >  正文

自己制作传感器教具第4篇 Flash动画与Arduino的互动

        在前两周我们用图文的形式学习了自制传感器教具的代码编程部分,今天我们继续学习自制传感器教具的核心代码编程:Flash动画与Arduino的互动。

  在上一篇,学习了利用代码来驱动动画,在这篇,我们就用Arduino的数据来驱动Flash动画,做到虚实结合(其实类似与互动媒体,像跳舞游戏机啊之类的,传感器与动画的互动)。

  首先要找出之前的位移传感器(有线无线都可以),我们那时写的程序如下:

  

 

  电脑接收到得数据分为两部分,逗号前的是测量时刻,逗号后得是距离值。

  Flash与Arduino的互动——数据中转站:serproxy

  下面正式开始Flash与Arduino的互动。Flash当初出现的目的是为了让网页的呈现更丰富,所以它实际上是针对网络的。这就导致Flash动画和本地文件的交互很麻烦,它无法读取本地计算机上的一些数据。为了解决这个问题,有人做了一个小软件,这个软件相当于一个小小的服务器,它会把本地计算机串口读到的数据以socket的方式发送出去(socket是网络上数据传输的一种方式)Flash可以读取来自socket服务器的数据,这样就间接的完成了Flash读取本地串口数据。说了那么多,我们来实践一下吧:

  首先要下载这个小软件,它的名字叫serproxy,它总共有两个文件,一个serproxy.exe可执行文件,还有一个serproxy.cfg配置文件。具体下载连接:

  https://pan.baidu.com/s/1rOe3s8Wy5ezTPnQsO0AwcQ

  下载后先用记事本打开serproxy.cfg文件,打开后如下:

  ********以下为文件内容*******

  # Config file for serproxy

  # See serproxy's README file for documentation

  # Comm ports used

  comm_ports=5

  # Default settings

  comm_baud=9600

  comm_databits=8

  comm_stopbits=1

  comm_parity=none

  # Idle time out in seconds

  timeout=300

  # Port 1 settings (ttyS0)

  net_port1=5333

  # Port 2 settings (ttyS1)

  net_port2=5333

  # Port 3 settings (ttyS2)

  net_port3=5333

  # Port 4 settings (ttyS3)

  net_port4=5333

  # Port 5 settings (ttyS4)

  net_port5=5333

  # Port 6 settings (ttyS5)

  net_port6=5333

  # Port 7 settings (ttyS6)

  net_port7=5333

  # Port 8 settings (ttyS7)

  net_port8=5333

  # Port 9 settings (ttyS8)

  net_port9=5333

  # Port 10 settings (ttyS9)

  net_port10=5333

  *******以上为文件内容*******

  我们需要配置的地方为

  # Comm ports used

  comm_ports=5

  这个comm_ports=5指的是串口的号码,还记得开篇中讲过的么,当Arduino插入计算机后,我们可以在设备管理器的端口栏内找到Arduino对应的COM号,我们要记住这个COM号,然后把comm_ports=5改成你的COM号,例如你的Arduino对应的COM号是7,那么就要改成comm_ports=7。

  还有需要配置的是

  # Default settings

  comm_baud=9600

  comm_databits=8

  comm_stopbits=1

  comm_parity=none

  这里的配置需要和你Arduino上对串口的配置相同,一般我们默认使用9600波特率,这样就不需要改这里的配置了。

  最后要配置的是

  # Idle time out in seconds

  timeout=300

  超时时间设置,这里300指的是300秒,也就是5分钟,当Flash连接上serproxy超过5分钟就会自动断开,当然如果你想连接久一点可以把这个数值改的大一些。

  剩下的就不用动了,我把所有的net_port全部设成了5333,这样不管arduino的COM号怎么变,Flash不用动了(待会讲到Flash端编程的时候会讲到这个net_port的用处)。

  好了,设置完serproxy后,就可以运行serproxy.exe文件了(之前先要连接好Arduino),运行后会出现一个界面

  

 

  让这个界面留着,也可以最小化,但是别关掉,这就是一个小型的服务器。

  Flash与Arduino的互动:Flash动画端的制作

  说完了“数据中转软件”,下面就开始进入Flash的制作。

  首先打开上一篇做好的Flash:

  

 

  打开动作,点击场景,将动作里的代码删除,加入下面的代码:

  ***********下面为动作里的代码*******

  var _proxyAddress:String = "127.0.0.1";

  //socket服务器地址,如果在本机上操作为127.0.0.1,如果作为服务器,则对应的服务器电脑的ip地址

  var _proxyPort:uint = 5333;

  //与socket代理服务器定义对应,这里使用serproxy作为串口转socket,需在serproxy中将所有串口的端口全定义成5333,这样这里就可以固定了

  var _socket:Socket;

  _socket = new Socket();//建立一个socket连接

  _socket.addEventListener( Event.CONNECT, onConnect );

  //侦听程序,当socket连接上时执行onConnect函数

  _socket.addEventListener( Event.CLOSE, onClose );

  //侦听程序,当socket关闭时执行onClose函数

  _socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );

  //侦听有无来自端口的数据,如果有数据执行onSocketData函数

  _socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError );

  //侦听有无出错,出错时执行onIOError函数

  _socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );

  //侦听有无安全性错误,如果有执行onSecurityError函数

  _socket.endian = Endian.LITTLE_ENDIAN;

  _socket.connect(_proxyAddress, _proxyPort);

  //socket连接,本机的地址是“127.0.0.1”,端口号是5333,与serproxy中设置的相同

  function onSocketData(event:ProgressEvent):void

  {

  var data:String = _socket.readUTFBytes(_socket.bytesAvailable);

  //读取来自socket的数据

  trace(data);

  //将读取到的数据显示出来,不过只有在制作的时候看的到,正式Flash运行时看不见的

  }

  //下面程序时处理通信建立时的

  function onConnect(event:Event):void

  {

  trace("Socket Connected");

  //连接上就输出一个消息“Socket Connected”,只在开发时观察用

  _socket.writeUTF('a');

  //发送一个字符a给Arduino,因为我们设计的位移传感器只有在接收到字符a之后才会发送数据

  _socket.flush();//发送

  }

  //下面的程序是处理通信关闭时的

  function onClose(event:Event):void

  {

  trace("Socket Closed"); //关闭时输出”Socket Closed"

  }

  //下面是出错时显示的消息的

  function onIOError(event:IOErrorEvent):void

  {

  trace("IOErrorEvent : " + event.text);

  }

  //下面也是出错时的

  function onSecurityError(event:SecurityErrorEvent):void

  {

  trace("SecurityErrorEvent : " + event.text);

  }

  ********上面为动作里的代码*********

  将上面的代码复制到你的Flash动画的动作里,代码中//后面的文字是注释语句,不是程序,不会执行。具体代码的含义注释里已经写明了,大家自己看吧。

  上述代码最主要的是接收到数据后的函数,也就是

  function onSocketData(event:ProgressEvent):void

  {

  ......

  }

  大括号中的程序是我们需要编写的,这里只做了最简单的处理,只是把它显示出来了而已,而且是显示在flash制作时的输出栏内,单独运行时是不会显示的。

  看大括号里的程序:

  var data:String = _socket.readUTFBytes(_socket.bytesAvailable);

  这句是关键,它读取来自socket的数据(也就是来自arduino的),然后数据赋值给一个变量data,这个变量它是字符串类型的,也就是说虽然arduino发出的是数字,但是flash接收后一律把他们当成了字符(关于字符和数字,同样是1,如果是数字就可以进行数学运算,1+1=2,但是如果是字符就好像一个人的名字为1,这个1是个代号,并不能进行运算的)。所以我们在接收到数据后还必须对这个数据进行处理,找出时刻的数据和位移的数据。

  下面开始对数据进行处理,首先需要先定义一些变量,这些定义加在所有代码的最前面:

  *****下面的代码加在动作程序的最前面***

  var buffer:String = "";

  var nowtime:String;

  var nt:Number=0;

  var displacement:String;

  var dis:Number=0;

  var endmsg:String="\n";

  var minmsg:String=",";

  ****上面的代码加在动作程序的最前面***

  然后开始改写下面函数大括号内的程序。

  *****下面是要改写的程序*****

  function onSocketData(event:ProgressEvent):void

  {

  var data:String = _socket.readUTFBytes(_socket.bytesAvailable);

  //读取来自socket的数据

  buffer += data; //读取串口的数据,并合并到buffer字符串中

  var index:int;

  var min:int;

  while((index = buffer.indexOf(endmsg)) > -1)

  //接收到endmsg时开始执行下面括号内的程序,endmsg字符即"\n"换行符,我们在Arduino每次输出数据结束时加了一个换行符,index变量记录了这个换行符在字符串中的位置

  {

  min=buffer.indexOf(minmsg);//min变量记录接收到数据中的“,”的位置

  displacement=buffer.substring(min+1,index);

  //将数据拆开,displacement变量等于数据中逗号后的数据,也就是距离值

  trace(displacement);//把这个值输出

  buffer=buffer.substring(index+1);

  //把buffer这个变量清空,以便重新开始装入新的数据

  }

  }

  *****上面是要改写的程序*****

  改好程序后按ctrl+Enter运行,可以看到Flash中输出栏内有数据输出了:

  

 

  此时如果打开刚才最小化的serproxy软件,可以看到也有输出:

  

 

  这样的显示说明连接成功了。

  好了,到此我们已经可以让Flash成功的接收到数据了,下面就让这个数据来驱动动画。我们的Flash里应该还保留着上次添加的名字为box的影片剪辑,下面开始用数据来控制它。在上一篇中,每次box开始移动都是在画面加载时开始计算box的位置并移动的,但是在由数据驱动的动画中,其实并没有必要每次画面加载时就去计算,只要每次数据接收到时进行计算就可以了,所以我们移动box的程序还是写在刚才接收到数据的函数中,下面继续来修改onSocketData内的程序(要修改的程序中已经标注了):

  *****下面是要改写的程序*****

  function onSocketData(event:ProgressEvent):void

  {

  var data:String = _socket.readUTFBytes(_socket.bytesAvailable);

  //读取来自socket的数据

  buffer += data; //读取串口的数据,并合并到buffer字符串中

  var index:int;

  var min:int;

  while((index = buffer.indexOf(endmsg)) > -1)

  //接收到endmsg时开始执行下面括号内的程序,endmsg字符即"\n"换行符,我们在Arduino每次输出数据结束时加了一个换行符,index变量记录了这个换行符在字符串中的位置

  {

  min=buffer.indexOf(minmsg);//min变量记录接收到数据中的“,”的位置

  displacement=buffer.substring(min+1,index);

  //将数据拆开,displacement变量等于数据中逗号后的数据,也就是距离值

  dis=Number(displacement);//将displacement字符串变量转换成数字

  box.x=dis;

  //让box(也就是画面上的方块)的x坐标等于dis的值,这样,box的x位置就是由来自位移传感器的数据来控制的了

  buffer=buffer.substring(index+1);

  //把buffer这个变量清空,以便重新开始装入新的数据

  }

  }

  *****上面是要改写的程序*****

  改写的程序只有两句

  dis=Number(displacement);//将displacement字符串变量转换成数字

  box.x=dis;

  //让box(也就是画面上的方块)的x坐标等于dis的值,这样,box的x位置就是由来自位移传感器的数据来控制的了

  然后再次按下ctrl+enter运行flash,可以看到画面上的方块会随着超声波测距仪测得的数据的变化而移动。怎么样,真实的传感器数据驱动了虚拟的flash动画,虚实结合的DIS实验是不是很有意思呢?

  最后,你可能会问,难道每次要运行flash还得打开flash制作软件么,当然不是,当你每次按下ctrl+enter后,在你保存flash制作文件的同一个文件夹内,就能找到一个后缀是swf的flash动画文件,下次直接运行这个文件就可以了。不过在直接运行这个文件之前,需要进行一些设置,首先用flashplayer打开flash动画文件

  

 

  然后再上面点击鼠标右键,选择全局设置

  

 

  再选择高级栏

  

 

  之后点击受信任位置设置

  

 

  点击添加

  

 

  再点击添加文件或者文件夹,把你做的flash动画包含进去

  

 

  然后点击确定,这样flashplayer就设置完毕了,下次打开的方式如下:

  将Arduino连接上电脑,打开serproxy软件并保留再后台,然后用flashplayer打开你制作的flash动画软件,就可以运行了。

  以上就是flash与arduino互动的最基本内容了,我们接下去就可以用Flash动画来代替DIS实验的软件了。

  下篇预告

  在下一篇中,我们将会一起来制作一个用无线位移传感器来研究简谐运动的Flash动画软件,我们不仅会用数据驱动动画,还会将数据显示出来,并且绘制图像等等......

上一篇:Cleco AHTE展会邀请函

下一篇:基于9轴惯性运动传感器的三阶卡尔曼滤波器算法