|
发表于 2012-10-24 18:12:16
|
显示全部楼层
以前安卓手机和arduino通过蓝牙通讯,现在看来可以直接用OTG USB线通讯了,赞一个!
贴2段 andriod的代码,供各位参考。
- /*
- * Copyright (C) 2012 Mathias Jeppsson
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * [url]http://www.apache.org/licenses/LICENSE-2.0[/url]
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.primavera.arduino.listener;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import android.app.ListActivity;
- import android.app.PendingIntent;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.hardware.usb.UsbDevice;
- import android.hardware.usb.UsbManager;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- import android.widget.Toast;
- public class ArduinoCommunicatorActivity extends ListActivity {
- private static final int ARDUINO_USB_VENDOR_ID = 0x2341;
- private static final int ARDUINO_UNO_USB_PRODUCT_ID = 0x01;
- private static final int ARDUINO_MEGA_2560_USB_PRODUCT_ID = 0x10;
- private static final int ARDUINO_MEGA_2560_R3_USB_PRODUCT_ID = 0x42;
- private static final int ARDUINO_UNO_R3_USB_PRODUCT_ID = 0x43;
- private final static String TAG = "ArduinoCommunicatorActivity";
- private final static boolean DEBUG = false;
-
- private Boolean mIsReceiving;
- private ArrayList<ByteArray> mTransferedDataList = new ArrayList<ByteArray>();
- private ArrayAdapter<ByteArray> mDataAdapter;
- private void findDevice() {
- UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
- UsbDevice usbDevice = null;
- HashMap<String, UsbDevice> usbDeviceList = usbManager.getDeviceList();
- if (DEBUG) Log.d(TAG, "length: " + usbDeviceList.size());
- Iterator<UsbDevice> deviceIterator = usbDeviceList.values().iterator();
- if (deviceIterator.hasNext()) {
- UsbDevice tempUsbDevice = deviceIterator.next();
- // Print device information. If you think your device should be able
- // to communicate with this app, add it to accepted products below.
- if (DEBUG) Log.d(TAG, "VendorId: " + tempUsbDevice.getVendorId());
- if (DEBUG) Log.d(TAG, "ProductId: " + tempUsbDevice.getProductId());
- if (DEBUG) Log.d(TAG, "DeviceName: " + tempUsbDevice.getDeviceName());
- if (DEBUG) Log.d(TAG, "DeviceId: " + tempUsbDevice.getDeviceId());
- if (DEBUG) Log.d(TAG, "DeviceClass: " + tempUsbDevice.getDeviceClass());
- if (DEBUG) Log.d(TAG, "DeviceSubclass: " + tempUsbDevice.getDeviceSubclass());
- if (DEBUG) Log.d(TAG, "InterfaceCount: " + tempUsbDevice.getInterfaceCount());
- if (DEBUG) Log.d(TAG, "DeviceProtocol: " + tempUsbDevice.getDeviceProtocol());
- if (tempUsbDevice.getVendorId() == ARDUINO_USB_VENDOR_ID) {
- if (DEBUG) Log.i(TAG, "Arduino device found!");
- switch (tempUsbDevice.getProductId()) {
- case ARDUINO_UNO_USB_PRODUCT_ID:
- Toast.makeText(getBaseContext(), "Arduino Uno " + getString(R.string.found), Toast.LENGTH_SHORT).show();
- usbDevice = tempUsbDevice;
- break;
- case ARDUINO_MEGA_2560_USB_PRODUCT_ID:
- Toast.makeText(getBaseContext(), "Arduino Mega 2560 " + getString(R.string.found), Toast.LENGTH_SHORT).show();
- usbDevice = tempUsbDevice;
- break;
- case ARDUINO_MEGA_2560_R3_USB_PRODUCT_ID:
- Toast.makeText(getBaseContext(), "Arduino Mega 2560 R3 " + getString(R.string.found), Toast.LENGTH_SHORT).show();
- usbDevice = tempUsbDevice;
- break;
- case ARDUINO_UNO_R3_USB_PRODUCT_ID:
- Toast.makeText(getBaseContext(), "Arduino Uno R3 " + getString(R.string.found), Toast.LENGTH_SHORT).show();
- usbDevice = tempUsbDevice;
- break;
- }
- }
- }
- if (usbDevice == null) {
- if (DEBUG) Log.i(TAG, "No device found!");
- Toast.makeText(getBaseContext(), getString(R.string.no_device_found), Toast.LENGTH_LONG).show();
- } else {
- if (DEBUG) Log.i(TAG, "Device found!");
- Intent startIntent = new Intent(getApplicationContext(), ArduinoCommunicatorService.class);
- PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, startIntent, 0);
- usbManager.requestPermission(usbDevice, pendingIntent);
- }
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (DEBUG) Log.d(TAG, "onCreate()");
- IntentFilter filter = new IntentFilter();
- filter.addAction(ArduinoCommunicatorService.DATA_RECEIVED_INTENT);
- filter.addAction(ArduinoCommunicatorService.DATA_SENT_INTERNAL_INTENT);
- registerReceiver(mReceiver, filter);
- mDataAdapter = new ArrayAdapter<ByteArray>(this, android.R.layout.simple_list_item_1, mTransferedDataList);
- setListAdapter(mDataAdapter);
- findDevice();
- }
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
- if (DEBUG) Log.i(TAG, "onListItemClick() " + position + " " + id);
- ByteArray transferedData = mTransferedDataList.get(position);
- transferedData.toggleCoding();
- mTransferedDataList.set(position, transferedData);
- mDataAdapter.notifyDataSetChanged();
- }
- @Override
- protected void onNewIntent(Intent intent) {
- if (DEBUG) Log.d(TAG, "onNewIntent() " + intent);
- super.onNewIntent(intent);
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.contains(intent.getAction())) {
- if (DEBUG) Log.d(TAG, "onNewIntent() " + intent);
- findDevice();
- }
- }
- @Override
- protected void onDestroy() {
- if (DEBUG) Log.d(TAG, "onDestroy()");
- super.onDestroy();
- unregisterReceiver(mReceiver);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.options, menu);
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.help:
- startActivity(new Intent(this, Help.class));
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
- BroadcastReceiver mReceiver = new BroadcastReceiver() {
- private void handleTransferedData(Intent intent, boolean receiving) {
- if (mIsReceiving == null || mIsReceiving != receiving) {
- mIsReceiving = receiving;
- mTransferedDataList.add(new ByteArray());
- }
- final byte[] newTransferedData = intent.getByteArrayExtra(ArduinoCommunicatorService.DATA_EXTRA);
- if (DEBUG) Log.i(TAG, "data: " + newTransferedData.length + " "" + new String(newTransferedData) + """);
- ByteArray transferedData = mTransferedDataList.get(mTransferedDataList.size() - 1);
- transferedData.add(newTransferedData);
- mTransferedDataList.set(mTransferedDataList.size() - 1, transferedData);
- mDataAdapter.notifyDataSetChanged();
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (DEBUG) Log.d(TAG, "onReceive() " + action);
- if (ArduinoCommunicatorService.DATA_RECEIVED_INTENT.equals(action)) {
- handleTransferedData(intent, true);
- } else if (ArduinoCommunicatorService.DATA_SENT_INTERNAL_INTENT.equals(action)) {
- handleTransferedData(intent, false);
- }
- }
- };
- }
复制代码
- /*
- * Copyright (C) 2012 Mathias Jeppsson
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * [url]http://www.apache.org/licenses/LICENSE-2.0[/url]
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.primavera.arduino.listener;
- import android.app.Service;
- 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.Handler;
- import android.os.IBinder;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- import android.widget.Toast;
- public class ArduinoCommunicatorService extends Service {
- private final static String TAG = "ArduinoCommunicatorService";
- private final static boolean DEBUG = false;
- private boolean mIsRunning = false;
- private SenderThread mSenderThread;
- private volatile UsbDevice mUsbDevice = null;
- private volatile UsbDeviceConnection mUsbConnection = null;
- private volatile UsbEndpoint mInUsbEndpoint = null;
- private volatile UsbEndpoint mOutUsbEndpoint = null;
- final static String DATA_RECEIVED_INTENT = "primavera.arduino.intent.action.DATA_RECEIVED";
- final static String SEND_DATA_INTENT = "primavera.arduino.intent.action.SEND_DATA";
- final static String DATA_SENT_INTERNAL_INTENT = "primavera.arduino.internal.intent.action.DATA_SENT";
- final static String DATA_EXTRA = "primavera.arduino.intent.extra.DATA";
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
- @Override
- public void onCreate() {
- if (DEBUG) Log.d(TAG, "onCreate()");
- super.onCreate();
- IntentFilter filter = new IntentFilter();
- filter.addAction(SEND_DATA_INTENT);
- filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
- registerReceiver(mReceiver, filter);
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (DEBUG) Log.d(TAG, "onStartCommand() " + intent + " " + flags + " " + startId);
- if (mIsRunning) {
- if (DEBUG) Log.i(TAG, "Service already running.");
- return Service.START_REDELIVER_INTENT;
- }
- mIsRunning = true;
- if (!intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
- if (DEBUG) Log.i(TAG, "Permission denied");
- Toast.makeText(getBaseContext(), getString(R.string.permission_denied), Toast.LENGTH_LONG).show();
- stopSelf();
- return Service.START_REDELIVER_INTENT;
- }
- if (DEBUG) Log.d(TAG, "Permission granted");
- mUsbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
- if (!initDevice()) {
- if (DEBUG) Log.e(TAG, "Init of device failed!");
- stopSelf();
- return Service.START_REDELIVER_INTENT;
- }
- if (DEBUG) Log.i(TAG, "Receiving!");
- Toast.makeText(getBaseContext(), getString(R.string.receiving), Toast.LENGTH_SHORT).show();
- startReceiverThread();
- startSenderThread();
- return Service.START_REDELIVER_INTENT;
- }
- @Override
- public void onDestroy() {
- if (DEBUG) Log.i(TAG, "onDestroy()");
- super.onDestroy();
- unregisterReceiver(mReceiver);
- mUsbDevice = null;
- if (mUsbConnection != null) {
- mUsbConnection.close();
- }
- }
- private byte[] getLineEncoding(int baudRate) {
- final byte[] lineEncodingRequest = { (byte) 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 };
- switch (baudRate) {
- case 14400:
- lineEncodingRequest[0] = 0x40;
- lineEncodingRequest[1] = 0x38;
- break;
- case 19200:
- lineEncodingRequest[0] = 0x00;
- lineEncodingRequest[1] = 0x4B;
- break;
- }
- return lineEncodingRequest;
- }
- private boolean initDevice() {
- UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
- mUsbConnection = usbManager.openDevice(mUsbDevice);
- if (mUsbConnection == null) {
- if (DEBUG) Log.e(TAG, "Opening USB device failed!");
- Toast.makeText(getBaseContext(), getString(R.string.opening_device_failed), Toast.LENGTH_LONG).show();
- return false;
- }
- UsbInterface usbInterface = mUsbDevice.getInterface(1);
- if (!mUsbConnection.claimInterface(usbInterface, true)) {
- if (DEBUG) Log.e(TAG, "Claiming interface failed!");
- Toast.makeText(getBaseContext(), getString(R.string.claimning_interface_failed), Toast.LENGTH_LONG).show();
- mUsbConnection.close();
- return false;
- }
- // Arduino USB serial converter setup
- // Set control line state
- mUsbConnection.controlTransfer(0x21, 0x22, 0, 0, null, 0, 0);
- // Set line encoding.
- mUsbConnection.controlTransfer(0x21, 0x20, 0, 0, getLineEncoding(9600), 7, 0);
- for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
- if (usbInterface.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
- if (usbInterface.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
- mInUsbEndpoint = usbInterface.getEndpoint(i);
- } else if (usbInterface.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_OUT) {
- mOutUsbEndpoint = usbInterface.getEndpoint(i);
- }
- }
- }
- if (mInUsbEndpoint == null) {
- if (DEBUG) Log.e(TAG, "No in endpoint found!");
- Toast.makeText(getBaseContext(), getString(R.string.no_in_endpoint_found), Toast.LENGTH_LONG).show();
- mUsbConnection.close();
- return false;
- }
- if (mOutUsbEndpoint == null) {
- if (DEBUG) Log.e(TAG, "No out endpoint found!");
- Toast.makeText(getBaseContext(), getString(R.string.no_out_endpoint_found), Toast.LENGTH_LONG).show();
- mUsbConnection.close();
- return false;
- }
- return true;
- }
- BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (DEBUG) Log.d(TAG, "onReceive() " + action);
- if (SEND_DATA_INTENT.equals(action)) {
- final byte[] dataToSend = intent.getByteArrayExtra(DATA_EXTRA);
- if (dataToSend == null) {
- if (DEBUG) Log.i(TAG, "No " + DATA_EXTRA + " extra in intent!");
- String text = String.format(getResources().getString(R.string.no_extra_in_intent), DATA_EXTRA);
- Toast.makeText(context, text, Toast.LENGTH_LONG).show();
- return;
- }
- mSenderThread.mHandler.obtainMessage(10, dataToSend).sendToTarget();
- } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
- Toast.makeText(context, getString(R.string.device_detaches), Toast.LENGTH_LONG).show();
- mSenderThread.mHandler.sendEmptyMessage(11);
- stopSelf();
- }
- }
- };
- private void startReceiverThread() {
- new Thread("arduino_receiver") {
- public void run() {
- byte[] inBuffer = new byte[4096];
- while(mUsbDevice != null ) {
- if (DEBUG) Log.d(TAG, "calling bulkTransfer() in");
- final int len = mUsbConnection.bulkTransfer(mInUsbEndpoint, inBuffer, inBuffer.length, 0);
- if (len > 0) {
- Intent intent = new Intent(DATA_RECEIVED_INTENT);
- byte[] buffer = new byte[len];
- System.arraycopy(inBuffer, 0, buffer, 0, len);
- intent.putExtra(DATA_EXTRA, buffer);
- sendBroadcast(intent);
- } else {
- if (DEBUG) Log.i(TAG, "zero data read!");
- }
- }
- if (DEBUG) Log.d(TAG, "receiver thread stopped.");
- }
- }.start();
- }
- private void startSenderThread() {
- mSenderThread = new SenderThread("arduino_sender");
- mSenderThread.start();
- }
- private class SenderThread extends Thread {
- public Handler mHandler;
- public SenderThread(String string) {
- super(string);
- }
- public void run() {
- Looper.prepare();
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (DEBUG) Log.i(TAG, "handleMessage() " + msg.what);
- if (msg.what == 10) {
- final byte[] dataToSend = (byte[]) msg.obj;
- if (DEBUG) Log.d(TAG, "calling bulkTransfer() out");
- final int len = mUsbConnection.bulkTransfer(mOutUsbEndpoint, dataToSend, dataToSend.length, 0);
- if (DEBUG) Log.d(TAG, len + " of " + dataToSend.length + " sent.");
- Intent sendIntent = new Intent(DATA_SENT_INTERNAL_INTENT);
- sendIntent.putExtra(DATA_EXTRA, dataToSend);
- sendBroadcast(sendIntent);
- } else if (msg.what == 11) {
- Looper.myLooper().quit();
- }
- }
- };
- Looper.loop();
- if (DEBUG) Log.i(TAG, "sender thread stopped");
- }
- }
- }
复制代码 |
|