gpt4 book ai didi

Android 到 Arduino Leonardo 通信 - 通过 OTG 电缆发送和接收命令

转载 作者:行者123 更新时间:2023-11-30 02:04:35 27 4
gpt4 key购买 nike

我正在尝试构建一个 Android 应用程序,我有一个 Arduino Leonardo 板,它通过键盘写入命令发送输出。到目前为止,我能够在我的 Android 设备上接收 Arduino 输出作为键盘输入。我有一个 EditText 文本,它只接收所有 Arduino 输出,当输出序列结束时,我可以轻松解析 EditText 值。

但是,我现在遇到的问题是从 Android 向 Arduino 发送数据。我已经完成了我的研究,Android 和 Arduino 之间推荐/常用的通信方式是通过蓝牙,Android 将通过蓝牙屏蔽将数据发送到 Arduino。这是一个可行的解决方案,但是,我们的资源有限。我还看到了涉及 OTG 电缆的 stackoverflow 问题,但这些问题是与 Arduino Uno 通信的。似乎那些解决方案对莱昂纳多不起作用。我还看过博客,其中评论部分的人会询问如何在 Android 和 Arduino Leonardo 之间实现基于电缆的通信系统。

我该如何解决这个问题?似乎 Arduino 板上的通信接口(interface)/协议(protocol)不同。

此外,作为旁注,除了键盘写入命令之外,是否可以使用不同的命令将数据从 Arduino Leonardo 发送到 Android?

最佳答案

这个例子展示了如何通过USB OTG线将字符串从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>

安卓 list .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>

布局,/res/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>

希望对你有帮助

关于Android 到 Arduino Leonardo 通信 - 通过 OTG 电缆发送和接收命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30898570/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com