Android + Arduino 蓝牙数据传输
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10327506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android + Arduino Bluetooth Data Transfer
提问by Backwards_Dave
I can get my Android app to connect via Bluetooth to my Arduino. However no data can be transmitted between them. Below is my setup and code:
我可以让我的 Android 应用程序通过蓝牙连接到我的 Arduino。然而,它们之间不能传输任何数据。以下是我的设置和代码:
HTC Android v2.2, Bluetooth mate gold modem, Arduino Mega (ATmega1280)
HTC Android v2.2,蓝牙配对金调制解调器,Arduino Mega (ATmega1280)
Android Java code:
安卓Java代码:
package com.example.BluetoothExample;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class BluetoothExampleActivity extends Activity {
TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button openButton = (Button)findViewById(R.id.open);
Button sendButton = (Button)findViewById(R.id.send);
Button closeButton = (Button)findViewById(R.id.close);
myLabel = (TextView)findViewById(R.id.label);
myTextbox = (EditText)findViewById(R.id.entry);
//Open Button
openButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
findBT();
openBT();
}
catch (IOException ex) { }
}
});
//Send Button
sendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
sendData();
}
catch (IOException ex) {
showMessage("SEND FAILED");
}
}
});
//Close button
closeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
closeBT();
}
catch (IOException ex) { }
}
});
}
void findBT() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null) {
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0) {
for(BluetoothDevice device : pairedDevices) {
if(device.getName().equals("FireFly-108B")) {
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
}
void openBT() throws IOException {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard //SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
void beginListenForData() {
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while(!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++) {
byte b = packetBytes[i];
if(b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
myLabel.setText(data);
}
});
}
else {
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}
void sendData() throws IOException {
String msg = myTextbox.getText().toString();
msg += "\n";
//mmOutputStream.write(msg.getBytes());
mmOutputStream.write('A');
myLabel.setText("Data Sent");
}
void closeBT() throws IOException {
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
}
private void showMessage(String theMsg) {
Toast msg = Toast.makeText(getBaseContext(),
theMsg, (Toast.LENGTH_LONG)/160);
msg.show();
}
}
Arduino Code:
Arduino代码:
#include <SoftwareSerial.h>
int bluetoothTx = 45;
int bluetoothRx = 47;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup() {
//pinMode(45, OUTPUT);
//pinMode(47, INPUT);
pinMode(53, OUTPUT);
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,9600,N");
bluetooth.begin(9600);
}
void loop() {
//Read from bluetooth and write to usb serial
if(bluetooth.available()) {
char toSend = (char)bluetooth.read();
Serial.print(toSend);
flashLED();
}
//Read from usb serial to bluetooth
if(Serial.available()) {
char toSend = (char)Serial.read();
bluetooth.print(toSend);
flashLED();
}
}
void flashLED() {
digitalWrite(53, HIGH);
delay(500);
digitalWrite(53, LOW);
}
I've tried using 115200 and 9600 for the baud rates, and I've tried setting the bluetooth rx and tx pins as input/output and output/input. The Arduino is receiving serial data from the PC but can't send it to the Android (I can see this because of the flashLED() method).
我尝试使用 115200 和 9600 作为波特率,并且尝试将蓝牙 rx 和 tx 引脚设置为输入/输出和输出/输入。Arduino 正在从 PC 接收串行数据,但无法将其发送到 Android(由于 flashLED() 方法,我可以看到这一点)。
The Android can't send any data at all to the Arduino. However they are both connected because the green light on the modem turns on and goes off and the red led flashes when I close the connection. The sendData() method doesn't throw an exception because otherwise showMessage("SEND FAILED"); would appear.
Android 根本无法向 Arduino 发送任何数据。但是,它们都已连接,因为当我关闭连接时,调制解调器上的绿灯会亮起然后熄灭,红色 LED 指示灯闪烁。sendData() 方法不会抛出异常,否则 showMessage("SEND FAILED"); 会出现。
I also have this in my manifest .xml
我的清单 .xml 中也有这个
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
Any help would be greatly appreciated!
任何帮助将不胜感激!
Code taken from:
代码取自:
http://bellcode.wordpress.com/2012/01/02/android-and-arduino-bluetooth-communication/
http://bellcode.wordpress.com/2012/01/02/android-and-arduino-bluetooth-communication/
回答by Backwards_Dave
Just solved the problem for anyone else who came across this page.
刚刚为遇到此页面的其他人解决了问题。
Seems that my Arduino doesn't like me using digital pins for serial communication, I use TX and RX instead with this code taken from http://jondontdoit.blogspot.com.au/2011/11/bluetooth-mate-tutorial.html, also seems that 9600 is a good baud instead of 115200.
似乎我的 Arduino 不喜欢我使用数字引脚进行串行通信,我使用 TX 和 RX 代替此代码取自http://jondontdoit.blogspot.com.au/2011/11/bluetooth-mate-tutorial.html,似乎 9600 是一个很好的波特率,而不是 115200。
/***********************
Bluetooth test program
***********************/
//TODO
//TEST THIS PROGRAM WITH ANDROID,
//CHANGE PINS TO RX AND TX THO ON THE ARDUINO!
//int counter = 0;
int incomingByte;
void setup() {
pinMode(53, OUTPUT);
Serial.begin(9600);
}
void loop() {
// see if there's incoming serial data:
if (Serial.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial.read();
// if it's a capital R, reset the counter
if (incomingByte == 'g') {
digitalWrite(53, HIGH);
delay(500);
digitalWrite(53, LOW);
delay(500);
//Serial.println("RESET");
//counter=0;
}
}
//Serial.println(counter);
//counter++;
//delay(250);
}
回答by Bill Merryman
I was getting the same thing. I went into 'Settings'->'Wireless and Networks'->'Bluetooth Settings' and paired the device. When I went back and re-ran my code, it connected, no exception. I put controls in my UI for displaying the paired devices, I'm going to see if I can code to manage pairing devices from my UI.
我得到了同样的东西。我进入“设置”->“无线和网络”->“蓝牙设置”并配对设备。当我返回并重新运行我的代码时,它已连接,无一例外。我在我的 UI 中放置了用于显示配对设备的控件,我将看看我是否可以编写代码来从我的 UI 管理配对设备。
回答by dmattox10
For anyone who finds this page, but is stuck using a hardcoded mac address as above, set mac address to NULL, and insert this code into OnResume()
对于找到此页面但使用上述硬编码 mac 地址卡住的任何人,请将 mac 地址设置为 NULL,并将此代码插入 OnResume()
try{
File f = new File(Environment.getExternalStorageDirectory()+"/mac.txt");
FileInputStream fileIS = new FileInputStream(f);
buf = new BufferedReader(new InputStreamReader(fileIS));
String readString = new String();
while((readString = buf.readLine())!= null){
address = readString;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
ALSO, don't forget to allow eclipse to include necessary libraries, and place your mac address into mac.txt on the root of the SD Card, then you can simply give users a text file with their mac address while still allowing the app to be downloaded from the market without customizing every instance.
另外,不要忘记让 eclipse 包含必要的库,并将您的 mac 地址放入 SD 卡根目录的 mac.txt 中,然后您可以简单地为用户提供一个包含其 mac 地址的文本文件,同时仍然允许应用程序无需自定义每个实例即可从市场上下载。
回答by Martynas
@Backwards_Dave just for a curious, try to connect to 45 and 46 pins and use this simple code. I use it and have no problem. You will be able to send data from Arduino Serial Monitor and read it there.
@Backwards_Dave 只是出于好奇,尝试连接到 45 和 46 引脚并使用这个简单的代码。我使用它,没有问题。您将能够从 Arduino 串行监视器发送数据并在那里读取。
/*
Pinout:
45 --> BT module Tx
46 --> BT module Rx
*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(45, 46); // RX, TX
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
Serial.println("I am ready to send some stuff!");
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
}
void loop() // run over and over
{
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
}
Also, what BlueTooth shield are you using for Arduino? HC-06?
另外,您为 Arduino 使用什么蓝牙屏蔽?HC-06?
EDIT
编辑
Just tested it with Mega2560(don't have 1280) and it works with no problem.
刚刚用 Mega2560(没有 1280)测试过它,它没有问题。
I believe problem was with pinout.
我相信问题出在引脚分配上。
Waiting for your feedback
等待你的反馈
回答by UserK
If you're still looking for an answer, try changing the software serial pins. This is a well known limitation of the library you are using.
如果您仍在寻找答案,请尝试更改软件串行引脚。这是您正在使用的库的众所周知的限制。
Not all pins on the Mega support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69). Refs
Mega 上并非所有引脚都支持更改中断,因此只有以下引脚可用于 RX:10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64)、A11 (65)、A12 (66)、A13 (67)、A14 (68)、A15 (69)。参考资料
Hope this helps.
希望这可以帮助。
回答by Dan
I was able to get this to run only after replacing this section:
只有在替换此部分后,我才能使其运行:
Set<BluetoothDevice> pairedDevices = BluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
if(device.getName().startsWith("FireFly-"))
{
mmDevice = device;
Log.d("ArduinoBT", "findBT found device named " + mmDevice.getName());
Log.d("ArduinoBT", "device address is " + mmDevice.getAddress());
break;
}
}
}
with this:
有了这个:
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
mmDevice = mBluetoothAdapter.getRemoteDevice("00:06:66:46:5A:91");
if (pairedDevices.contains(mmDevice))
{
statusText.setText("Bluetooth Device Found, address: " + mmDevice.getAddress() );
Log.d("ArduinoBT", "BT is paired");
}
where I entered the address of my Bluetooth device. The original code finds the device and returns the correct address, but mmSocket.connect(); generates an exception "java.io.IOException: Service discovery failed"
在那里我输入了我的蓝牙设备的地址。原代码找到设备并返回正确地址,但是mmSocket.connect(); 生成异常“java.io.IOException:服务发现失败”
Suggestions?
建议?
回答by Bluetooth Module
I think it might be some fault in Bluetooth.. its better to re-install its drivers.. as the code given above looks correct.
我认为这可能是蓝牙的一些故障..最好重新安装它的驱动程序..因为上面给出的代码看起来是正确的。