一、引言

    大家都知道Google公司2011年推出了命名为 "ADK"的开发工具,可以与Arduino硬件进行有线联机,但是Arduino硬件必须具备ADK功能,一般用的型号为Arduino Mega ADK,价格较贵。能否用一种经济的方法让安卓智能设备与任意一种Arduino控制板联机呢?这篇文章就介绍一种利用OTG线来使两者联机的方法。

    前段时间我们团队成员做了这样的实验,实验任务是:安卓手机APP界面上方布置一个弧形仪表盘显示电机的实时转速,图1所示可见当前电机转速为67rpm,下方有一个水平滚动条,滑块从左到右拖动时,控制电机转速从0到96rpm。该电机后端带有光栅编码器,且额定转速为96rpm。这个实验并不是通过蓝牙无线的方式来完成,而是通过图1中白色OTG线使安卓智能设备与Arduino UNO控制板联机来完成的。

    安卓智能手机与Arduino UNO控制板联机可参见博客文章《基于processing编程的安卓手机蓝牙通信方法》,网址:

http://www.eefocus.com/zhang700309/blog/15-02/310447_be430.html

电机实验.JPG

图1 电机转速测控实验

    图1中所展示的电机转速测控实验视频请看:

 

二、创建编程环境

    要创建“安卓手机与Arduino有线OTG联机”的编程环境,首先应具备以下条件:

1、智能手机的安卓版本必须大于3.1, 且支持OTG功能。

2、电脑必须安装JDK和Andriod SDK。可参加博客文章《在安卓手机上运行Processing程序的方法》网址:

http://www.eefocus.com/zhang700309/blog/14-12/307377_88e74.html

3、下载安装新版Processing 3.0a4软件

 下载网址:https://www.processing.org/download/?processingHLv

4、一块Arduino控制板

5、OTG 数据线和普通USB数据线

6、下载安装AndroidSerial库文件,

网址:http://sourceforge.net/projects/procandser/。

    与《在安卓手机上运行Processing程序的方法》所介绍Processing的Andriod编程环境有所增加项是如何正确安装AndroidSerial库文件。从以上网址下载后解压生成AndroidSerial库文件,这个文件放入到Processing软件的libraries文件夹里的具体方法如下图所示。

    打开Processing 3.0a4软件,在菜单栏上点击“文件”→“偏好设置…”,出现图2所示窗口。在这个窗口中可以设置Processing编程环境的显示字体为“中文”,还可以设置程序语句的字体大小。图2中更重要的信息是Processing软件libraries文件夹的位置在红圈已标识出来了,我的电脑显示它在D:\My Documents\Processing的文件夹下。

Processing库文件地址1.jpg

图2 Processing软件的libraries文件夹位置

根据图2的提示,我找到了文件夹D:\我的文档\Processing\libraries\,如图3所示。于是把AndroidSerial库文件顺势放入其内。

Processing库文件2地址.jpg

图3 AndroidSerial库文件放入libraries文件夹

AndroidSerial库文件也可以从下面介绍的实例文件夹中找到,请下载:OTG联机Processing编程.rar

另外OTG 数据线和普通USB数据线都可以在淘宝中买到。如下图所示,那根白色线就是OTG线,而是黑色的物件是USB转接头,这个转接头的方口USB公头正好插在Arduino UNO的母座上,而它另一端的扁平USB公头将连接到OTG线的USB母头中。这样一个黑色USB转接头与一根USB线的效果一样,但它却很小巧。

OTG线.JPG

图4  OTG 数据线和USB转接头

 

三、Processing编程和下载

    这篇文章详细说明的实例不是图1所示的电机转速测控实验,而是一个简单的例子,目的是为了突出本文介绍的主体内容“基于Processing的安卓手机与Arduino有线OTG联机方法”。

实验全景.JPG

图5 安卓平板与Arduino有线OTG联机实验

    图5中展示了这个实例的全套装备,中间那个白色平板是台电品牌,型号为P89smini的7.9英寸安卓平板电脑,Android版本为Android4.2。然后它通过OTG线与Arduino UNO控制板连接。Arduino UNO控制板的数字端口又连接着一个电位计和一个RGB灯,就是这样两个小东西连接起这个实例中人和虚拟Processing画布之间的交互。

    Processing程序任务:Processing上位机接受Arduino控制板上传的电位计实时值,该值决定画布中圆形图形的直径大小,同时手指每按动一次Processing画布,颜色标志字节加1,圆形图形的填充色随之改变,该字节再下达给Arduino控制板,又同步改变RGB灯的颜色。

    Processing程序编辑好,然后按下Processing编程环境中的“播放”按钮,程序就利用USB线下载到安卓平板电脑中了。下载完后,平板会显示如下提示。这是正常的,不用管它,刚才的程序已经正确安装到了安卓平板里。

停止运行.JPG

图6  Processing程序下载安装后的提示

    接着,从安卓平板中拔下USB线,换上OTG线,如图5所示把安卓平板与Arduino控制板有线OTG联机,同时保证安卓平板与Arduino控制板都已下载安装了各自的程序。这时,你会发现在平板上显示如下图所示窗口,选择刚刚下载到平板中的Processing程序名称,再点击“仅此一次”,哈哈,互动实验就这样开始了,Enjoy!

仅此一次.JPG

图7 运行Processing程序

Processing程序:(注意与串口通信相关的程序段,我用红色字体标注出来。)

//引入AndroidSerial库文件

import com.yourinventit.processing.android.serial.*;

Serial SerialPort;//定义SerialPortSerial串口对象

byte color_flag=0;//颜色标志字节

float diameter;//圆形图形的直径

int val_read;  //读取Arduino控制板上传的字节

//初始化

void setup()   

{

  //设置串口地址和波特率

  SerialPort = new Serial(this, Serial.list(this)[0], 9600);

  //定义画布大小

  size(600,800); //绘制一个宽度为600像素,高度为800像素的画布

  noStroke();//不绘制图形的轮廓线

  smooth();//开启抗锯齿功能,使线条轮廓光滑

  color_flag=0;  //初始化

  diameter=20;

}

//切换画布中圆型图形填充色的函数

void color_fill(int flag){

  if(flag==0)

    fill(255,0,0);

  if(flag==1)

    fill(0,255,0);

  if(flag==2)

    fill(0,0,255);

}

//主程序

void draw()

{

   background(126);//刷背景色

   //读取Arduino控制板上传的字节

   if(SerialPort.available()>0)

   {

      val_read=SerialPort.read();

      //把上传的数据范围为0到127的值转换为圆形图形的直径

      diameter = map(val_read, 0, 127, 20, 500);

   }

   //给圆形图形填充颜色

   color_fill(color_flag);

   ellipse(300,300,diameter,diameter); //画圆

}

/*当发生“手指按下”事件时,颜色标志字节加1

color_flag为0时,Arduino控制板上的RGB灯为红色

color_flag为1时,Arduino控制板上的RGB灯为绿色

color_flag为2时,Arduino控制板上的RGB灯为蓝色*/

void mousePressed() {     

    color_flag +=1;

    if(color_flag==3)

      color_flag=0; 

   //向Arduino下达颜色标志字节  

   SerialPort.write(color_flag); 

}

 

四、Arduino编程

  Arduino程序任务:接受上位机Processing程序下达的RGB灯显示何种颜色的标志字节,并驱动RGB灯显示相应颜色。同时,Arduino控制板把电位计值读出来,并转换为0到127的数值上传给上位机Processing程序,以使Processing画面中圆形图形的直径产生相应的变化。

Arduino程序:(注意与串口通信相关的程序段,我用红色字体标注出来。)

int led_R = 11;//定义RGB灯红色引脚,一定要能发PWM信号的数字端口

int led_G = 9;//定义RGB灯绿色引脚

int led_B = 10;//定义RGB灯蓝色色引脚

byte val_read=0;//接收串口发来的颜色标志字节数据

int pot_val;    //读取电位计的数据

long old_time=0;

long new_time=0;

//初始化

void setup() {               

  pinMode(led_R, OUTPUT);//将RGB红色引脚设置为输出模式

  digitalWrite(led_R, LOW);//关闭RGB红灯

  pinMode(led_G, OUTPUT);//将RGB绿色引脚设置为输出模式

  digitalWrite(led_G, LOW);//关闭RGB绿灯

  pinMode(led_B, OUTPUT);//将RGB蓝色引脚设置为输出模式

  digitalWrite(led_B, LOW);//关闭RGB蓝灯

  Serial.begin(9600);//设置通讯波特率,启动串行通信

}

//主程序

void loop() {

    //当读取到标志字节数据为0,则RGB灯显示为红色 

    if(val_read == 0){

      analogWrite(led_R, 10);  //点亮RGB红灯 

      digitalWrite(led_G, LOW);//关闭RGB绿灯

      digitalWrite(led_B, LOW);//关闭RGB蓝灯

    }

    //当读取到标志字节数据为1,则RGB灯显示为绿色

    else if(val_read ==1){

      digitalWrite(led_R, LOW);//关闭RGB红灯 

      analogWrite(led_G, 10);//点亮RGB绿灯

      digitalWrite(led_B, LOW);//关闭RGB蓝灯

    }

     //当读取到标志字节数据为2,则RGB灯显示为蓝色

    else if(val_read ==2){

      digitalWrite(led_R, LOW);//关闭RGB红灯 

      digitalWrite(led_G, LOW);//关闭RGB绿灯

      analogWrite(led_B, 10);//点亮RGB蓝灯

    }

    //当读取到标志字节数据为其它数据,则RGB灯熄灭

    else{

      digitalWrite(led_R, LOW);//RGB红灯 

      digitalWrite(led_G, LOW);//关闭RGB绿灯

      digitalWrite(led_B, LOW);//关闭RGB蓝灯

    }  

  //每20ms把电位计值上传给上位机Processing程序

  new_time= millis();

  if(abs(new_time-old_time)>20 ){

    pot_val=analogRead(A0); //读取电位计的模拟量值

    pot_val=map(pot_val,0,1023,0,127);//把电位计模拟量值转换为0到127的值

    Serial.write(pot_val);//通过串口上传到Processing

    old_time=new_time;

  }

}

//当Arduino控制板串口接受到数据,即刻引发串口事件

void serialEvent() {

// 读取串口发来的值

  while (Serial.available()) {

    val_read = Serial.read();

  }

}

 

五、结束语

    过去人们都是在探讨和体察物理空间的人物、事件和物体,用眼睛、耳朵和手去接触它们和创造它们,但是自从有了计算机和互联网,人类又开辟了虚拟空间,希望还能用先前人们对待物理空间的手段在虚拟世界中开疆破土,甚至希望把两个空间自然地联络起来,于是研究人机交互技术成为热点,比如键盘鼠标、kinect还是Processing数据可视化都是人们为沟通两个空间所做的努力。

    当国内网络上充斥着台式或笔记本电脑与传感器和电机,在基于Processing平台上相互交互的案例时,自然想到如今已人手一部的安卓智能手机能否与物理装置互动?为了满足人们对虚实两个空间随时交流的好奇,于是我们团队把国外网络上的有关技术手段不断消化整理,并及时以中文简体的文档呈现在网络上,以期待与友人分享。分享是未来人们的价值所在,而不是那些权势和金钱。