Arduino和Android通过OTG 通信

Posted B612灯夫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino和Android通过OTG 通信相关的知识,希望对你有一定的参考价值。

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

一直想做一款智能机器人,会看路、会走、会说话、能聊天的机器人。硬件控制采用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);
  




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

点击打开链接

下面是我写好的工程

点击打开链接

以上是关于Arduino和Android通过OTG 通信的主要内容,如果未能解决你的问题,请参考以下文章

LabVIEW控制Arduino采集电位器电压(基础篇—4)

LabVIEW控制Arduino采集电位器电压(基础篇—4)

LabVIEW控制Arduino采集电位器电压(基础篇—4)

Android通过蓝牙HC06与Arduino通信实例

使用 RTL-SDR 加密狗和 OTG 适配器在 Android 上收听广播对话

arduino电位器调整led灯颜色