Arduino和Android通过OTG 通信

来源:互联网 发布:linux java开发 编辑:程序博客网 时间:2024/05/17 08:41

马上就跨年了,写点最近做的东西也算是给自己一个交代。

一直想做一款智能机器人,会看路、会走、会说话、能聊天的机器人。硬件控制采用Arduino软件处理器使用Android Mini Pc俗称安卓盒子或者安卓棒,图像识别采用高通结合OpenCV(这个还在考虑,毕竟自己不太会写算法)、显示器采用车载屏幕。硬件都采购好了,Arduino也基本差不多了,现在就是要做通信以及凸显识别这一块了。

本来打算采用Arduino的蓝牙模块和Android进行通信的,并且通信测试也已经通过了,可以控制小车前进后退操作。但是后来有考虑Arduino本身带有USB接口,为什么弃之不用呢,所以就花了两天时间墙内墙外的找(像我这种编程能力不是特别强的,还是希望找到容易看懂的代码,在修改。。)

找到一国外哥们的,下面给大家简单翻译一下,附带源码

这个例子实现双向通信在USB主机模式下,Android和Arduino Uno之间。Android上的一个按钮,用于开/关Arduino Uno板子上自带的led灯,和Arduino一侧电位计,用于控制 Android的SeekBar

AndroidManifest.xml 

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.androidusbhostarduino"    android:versionCode="1"    android:versionName="1.0" >    <uses-feature android:name="android.hardware.usb.host" />    <uses-sdk        android:minSdkVersion="12"        android:targetSdkVersion="19" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>            <intent-filter>                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />            </intent-filter>            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"                android:resource="@xml/device_filter" />        </activity>    </application></manifest>

res/xml/device_filter.xml, for Arduino Uno. (这个文件夹感觉用处不大,因为在我的测试中,Android直接检测那个usb口是可以双线通信的,如果有,就默认为Arduino的)

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- idVendor=2341, idProduct=0043 for Arduino Uno R3 -->    <usb-device         vendor-id="9025"         product-id="0067" /></resources>

/res/layout/activity_main.xml 

package com.example.androidusbhostarduino;import java.nio.ByteBuffer;import android.support.v7.app.ActionBarActivity;import android.content.Context;import android.content.Intent;import android.hardware.usb.UsbConstants;import android.hardware.usb.UsbDevice;import android.hardware.usb.UsbDeviceConnection;import android.hardware.usb.UsbEndpoint;import android.hardware.usb.UsbInterface;import android.hardware.usb.UsbManager;import android.hardware.usb.UsbRequest;import android.os.Bundle;import android.widget.CompoundButton;import android.widget.SeekBar;import android.widget.ToggleButton;import android.widget.CompoundButton.OnCheckedChangeListener;public class MainActivity extends ActionBarActivity implements Runnable{ private static final int CMD_LED_OFF = 2; private static final int CMD_LED_ON = 1; SeekBar bar; ToggleButton buttonLed;  private UsbManager usbManager;    private UsbDevice deviceFound;    private UsbDeviceConnection usbDeviceConnection;    private UsbInterface usbInterfaceFound = null; private UsbEndpoint endpointOut = null; private UsbEndpoint endpointIn = null; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);    bar = (SeekBar)findViewById(R.id.seekbar);  buttonLed = (ToggleButton)findViewById(R.id.arduinoled);  buttonLed.setOnCheckedChangeListener(new OnCheckedChangeListener(){   @Override   public void onCheckedChanged(CompoundButton buttonView,     boolean isChecked) {    if(isChecked){     sendCommand(CMD_LED_ON);    }else{     sendCommand(CMD_LED_OFF);    }   }});    usbManager = (UsbManager)getSystemService(Context.USB_SERVICE); } @Override    public void onResume() {        super.onResume();        Intent intent = getIntent();        String action = intent.getAction();        UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {            setDevice(device);        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {            if (deviceFound != null && deviceFound.equals(device)) {                setDevice(null);            }        }    }  private void setDevice(UsbDevice device) {        usbInterfaceFound = null;     endpointOut = null;     endpointIn = null;        for (int i = 0; i < device.getInterfaceCount(); i++) {            UsbInterface usbif = device.getInterface(i);   UsbEndpoint tOut = null;   UsbEndpoint tIn = null;   int tEndpointCnt = usbif.getEndpointCount();   if (tEndpointCnt >= 2) {    for (int j = 0; j < tEndpointCnt; j++) {     if (usbif.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {      if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT) {       tOut = usbif.getEndpoint(j);      } else if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN) {       tIn = usbif.getEndpoint(j);      }     }    }    if (tOut != null && tIn != null) {     // This interface have both USB_DIR_OUT     // and USB_DIR_IN of USB_ENDPOINT_XFER_BULK     usbInterfaceFound = usbif;     endpointOut = tOut;     endpointIn = tIn;    }   }  }                if (usbInterfaceFound == null) {            return;        }        deviceFound = device;                if (device != null) {            UsbDeviceConnection connection =              usbManager.openDevice(device);            if (connection != null &&              connection.claimInterface(usbInterfaceFound, true)) {                usbDeviceConnection = connection;                Thread thread = new Thread(this);                thread.start();            } else {                usbDeviceConnection = null;            }         }    }  private void sendCommand(int control) {        synchronized (this) {            if (usbDeviceConnection != null) {                byte[] message = new byte[1];                message[0] = (byte)control;                usbDeviceConnection.bulkTransfer(endpointOut,                  message, message.length, 0);            }        }    } @Override public void run() {  ByteBuffer buffer = ByteBuffer.allocate(1);        UsbRequest request = new UsbRequest();        request.initialize(usbDeviceConnection, endpointIn);        while (true) {            request.queue(buffer, 1);            if (usbDeviceConnection.requestWait() == request) {                byte rxCmd = buffer.get(0);                if(rxCmd!=0){                 bar.setProgress((int)rxCmd);                }                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                }            } else {                break;            }        }   }}
上面就是Android端的程序,这个有些安卓基础的应该看起来不难。下面是Arduino的代码

int prvValue;void setup() {  Serial.begin(9600);  pinMode(13, OUTPUT);    prvValue = 0;}void loop() {  if(Serial.available()){    byte cmd = Serial.read();    if(cmd == 0x02){      digitalWrite(13, LOW);    }else if(cmd == 0x01){      digitalWrite(13, HIGH);    }  }    int sensorValue = analogRead(A0) >> 4;  byte dataToSent;  if(prvValue != sensorValue){    prvValue = sensorValue;        if (prvValue==0x00){      dataToSent = (byte)0x01;    }else{      dataToSent = (byte)prvValue;    }        Serial.write(dataToSent);    delay(100);  }}



无耻的把作者的演示视频也下下来了

点击打开链接

下面是我写好的工程

点击打开链接

0 0
原创粉丝点击