美好的一天。
我正在尝试构建一个Android应用程序,我有一个Arduino Leonardo板,通过键盘写命令发送输出。到目前为止,我能够在我的Android设备上接收Arduino输出作为键盘输入。我有一个EditText文本,只接收所有Arduino输出,当输出序列结束时,我可以轻松地解析EditText值。
但是,我现在遇到的问题是将数据从Android发送到Arduino。我完成了我的研究,Android和Arduino之间的推荐/常用通信方式是通过蓝牙,Android将数据发送到带有蓝牙屏蔽的Arduino。这是一个可行的解决方案,但是,我们的资源有限。我还看到了涉及OTG Cable的stackoverflow问题,但这些问题正在与Arduino Uno进行通信。似乎这些解决方案对莱昂纳多不起作用。我也看过博客,其中评论部分的人会询问如何在Android和Arduino Leonardo之间实现基于有线的通信系统。
有人可以帮我解决从Arduino Leonardo向Android发送数据的问题吗?看起来Arduino板上的通信接口/协议是不同的。
另外,作为附注,除了键盘写入命令之外,是否可以使用不同的命令将数据从Arduino Leonardo发送到Android?
答案 0 :(得分:1)
此示例显示如何通过USB OTG电缆将String从Android发送到Arduino Uni,在发送之前您必须了解
vendor-id="9025"
product-id="0067"
Arduino
的查看了此示例
import java.util.HashMap;
import java.util.Iterator;
import android.support.v7.app.ActionBarActivity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
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.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
TextView textInfo;
TextView textSearchedEndpoint;
TextView textDeviceName;
TextView textStatus;
private static final int targetVendorID = 9025; //Arduino Uno
private static final int targetProductID = 67; //Arduino Uno, not 0067
UsbDevice deviceFound = null;
UsbInterface usbInterfaceFound = null;
UsbEndpoint endpointIn = null;
UsbEndpoint endpointOut = null;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
PendingIntent mPermissionIntent;
UsbInterface usbInterface;
UsbDeviceConnection usbDeviceConnection;
EditText textOut;
Button buttonSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textStatus = (TextView) findViewById(R.id.textstatus);
textDeviceName = (TextView) findViewById(R.id.textdevicename);
textInfo = (TextView) findViewById(R.id.info);
textSearchedEndpoint = (TextView) findViewById(R.id.searchedendpoint);
// register the broadcast receiver
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
registerReceiver(mUsbDeviceReceiver, new IntentFilter(
UsbManager.ACTION_USB_DEVICE_ATTACHED));
registerReceiver(mUsbDeviceReceiver, new IntentFilter(
UsbManager.ACTION_USB_DEVICE_DETACHED));
connectUsb();
textOut = (EditText)findViewById(R.id.textout);
buttonSend = (Button)findViewById(R.id.send);
buttonSend.setOnClickListener(buttonSendOnClickListener);
}
OnClickListener buttonSendOnClickListener =
new OnClickListener(){
@Override
public void onClick(View v) {
if(deviceFound != null){
String tOut = textOut.getText().toString();
byte[] bytesOut = tOut.getBytes(); //convert String to byte[]
int usbResult = usbDeviceConnection.bulkTransfer(
endpointOut, bytesOut, bytesOut.length, 0);
}else{
Toast.makeText(MainActivity.this,
"deviceFound == null",
Toast.LENGTH_LONG).show();
}
}};
@Override
protected void onDestroy() {
releaseUsb();
unregisterReceiver(mUsbReceiver);
unregisterReceiver(mUsbDeviceReceiver);
super.onDestroy();
}
private void connectUsb() {
Toast.makeText(MainActivity.this, "connectUsb()", Toast.LENGTH_LONG)
.show();
textStatus.setText("connectUsb()");
searchEndPoint();
if (usbInterfaceFound != null) {
setupUsbComm();
}
}
private void releaseUsb() {
Toast.makeText(MainActivity.this, "releaseUsb()", Toast.LENGTH_LONG)
.show();
textStatus.setText("releaseUsb()");
if (usbDeviceConnection != null) {
if (usbInterface != null) {
usbDeviceConnection.releaseInterface(usbInterface);
usbInterface = null;
}
usbDeviceConnection.close();
usbDeviceConnection = null;
}
deviceFound = null;
usbInterfaceFound = null;
endpointIn = null;
endpointOut = null;
}
private void searchEndPoint() {
textInfo.setText("");
textSearchedEndpoint.setText("");
usbInterfaceFound = null;
endpointOut = null;
endpointIn = null;
// Search device for targetVendorID and targetProductID
if (deviceFound == null) {
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
if (device.getVendorId() == targetVendorID) {
if (device.getProductId() == targetProductID) {
deviceFound = device;
}
}
}
}
if (deviceFound == null) {
Toast.makeText(MainActivity.this, "device not found",
Toast.LENGTH_LONG).show();
textStatus.setText("device not found");
} else {
String s = deviceFound.toString() + "\n" + "DeviceID: "
+ deviceFound.getDeviceId() + "\n" + "DeviceName: "
+ deviceFound.getDeviceName() + "\n" + "DeviceClass: "
+ deviceFound.getDeviceClass() + "\n" + "DeviceSubClass: "
+ deviceFound.getDeviceSubclass() + "\n" + "VendorID: "
+ deviceFound.getVendorId() + "\n" + "ProductID: "
+ deviceFound.getProductId() + "\n" + "InterfaceCount: "
+ deviceFound.getInterfaceCount();
textInfo.setText(s);
// Search for UsbInterface with Endpoint of USB_ENDPOINT_XFER_BULK,
// and direction USB_DIR_OUT and USB_DIR_IN
for (int i = 0; i < deviceFound.getInterfaceCount(); i++) {
UsbInterface usbif = deviceFound.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) {
textSearchedEndpoint.setText("No suitable interface found!");
} else {
textSearchedEndpoint.setText("UsbInterface found: "
+ usbInterfaceFound.toString() + "\n\n"
+ "Endpoint OUT: " + endpointOut.toString() + "\n\n"
+ "Endpoint IN: " + endpointIn.toString());
}
}
}
private boolean setupUsbComm() {
// for more info, search SET_LINE_CODING and
// SET_CONTROL_LINE_STATE in the document:
// "Universal Serial Bus Class Definitions for Communication Devices"
final int RQSID_SET_LINE_CODING = 0x20;
final int RQSID_SET_CONTROL_LINE_STATE = 0x22;
boolean success = false;
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
Boolean permitToRead = manager.hasPermission(deviceFound);
if (permitToRead) {
usbDeviceConnection = manager.openDevice(deviceFound);
if (usbDeviceConnection != null) {
usbDeviceConnection.claimInterface(usbInterfaceFound, true);
int usbResult;
usbResult = usbDeviceConnection.controlTransfer(0x21, // requestType
RQSID_SET_CONTROL_LINE_STATE, // SET_CONTROL_LINE_STATE
0, // value
0, // index
null, // buffer
0, // length
0); // timeout
Toast.makeText(
MainActivity.this,
"controlTransfer(SET_CONTROL_LINE_STATE): " + usbResult,
Toast.LENGTH_LONG).show();
// baud rate = 9600
// 8 data bit
// 1 stop bit
byte[] encodingSetting = new byte[] { (byte) 0x80, 0x25, 0x00,
0x00, 0x00, 0x00, 0x08 };
usbResult = usbDeviceConnection.controlTransfer(0x21, // requestType
RQSID_SET_LINE_CODING, // SET_LINE_CODING
0, // value
0, // index
encodingSetting, // buffer
7, // length
0); // timeout
Toast.makeText(MainActivity.this,
"controlTransfer(RQSID_SET_LINE_CODING): " + usbResult,
Toast.LENGTH_LONG).show();
/*
byte[] bytesHello = new byte[] { (byte) 'H', 'e', 'l', 'l',
'o', ' ', 'f', 'r', 'o', 'm', ' ', 'A', 'n', 'd', 'r',
'o', 'i', 'd' };
usbResult = usbDeviceConnection.bulkTransfer(endpointOut,
bytesHello, bytesHello.length, 0);
Toast.makeText(MainActivity.this, "bulkTransfer: " + usbResult,
Toast.LENGTH_LONG).show();
*/
}
} else {
manager.requestPermission(deviceFound, mPermissionIntent);
Toast.makeText(MainActivity.this, "Permission: " + permitToRead,
Toast.LENGTH_LONG).show();
textStatus.setText("Permission: " + permitToRead);
}
return success;
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
Toast.makeText(MainActivity.this, "ACTION_USB_PERMISSION",
Toast.LENGTH_LONG).show();
textStatus.setText("ACTION_USB_PERMISSION");
synchronized (this) {
UsbDevice device = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
connectUsb();
}
} else {
Toast.makeText(MainActivity.this,
"permission denied for device " + device,
Toast.LENGTH_LONG).show();
textStatus.setText("permission denied for device "
+ device);
}
}
}
}
};
private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
deviceFound = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Toast.makeText(
MainActivity.this,
"ACTION_USB_DEVICE_ATTACHED: \n"
+ deviceFound.toString(), Toast.LENGTH_LONG)
.show();
textStatus.setText("ACTION_USB_DEVICE_ATTACHED: \n"
+ deviceFound.toString());
connectUsb();
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Toast.makeText(MainActivity.this,
"ACTION_USB_DEVICE_DETACHED: \n" + device.toString(),
Toast.LENGTH_LONG).show();
textStatus.setText("ACTION_USB_DEVICE_DETACHED: \n"
+ device.toString());
if (device != null) {
if (device == deviceFound) {
releaseUsb();
}else{
Toast.makeText(MainActivity.this,
"device == deviceFound, no call releaseUsb()\n" +
device.toString() + "\n" +
deviceFound.toString(),
Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(MainActivity.this,
"device == null, no call releaseUsb()", Toast.LENGTH_LONG).show();
}
textInfo.setText("");
}
}
};
}
创建/res/xml/device_filter.xml以指定vendor-id和product-id。
<?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>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidusbhostarduinouno"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:configChanges="keyboard|orientation"
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" />
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
</application>
</manifest>
layout,/ stl /layout / activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidusbhostarduinouno.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<EditText
android:id="@+id/textout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send"/>
<TextView
android:id="@+id/textstatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold" />
<TextView
android:id="@+id/textdevicename"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold|italic" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/searchedendpoint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
我希望它会帮助你