问题描述
我目前正在研究谷歌的蓝牙聊天的例子。我们的目标是获得机器人和和的Arduino之间的通信工作的根据本实施例
I am currently looking at Google's Bluetooth Chat example. The goal is to get communication between android and and Arduino working based on this example.
虽然从智能手机到Arduino通信是伟大的工作,其他的方向不会:
当从阿尔杜伊诺发送字节到智能电话,以下code为用于接收
While communication from the smartphone to the Arduino is working great, the other direction does not:When sending bytes from the Arduino to the smartphone, the following code is used for receiving:
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
这具有以下问题:
- 在我的主要活动中,我得到一个递给字节数组总是1024字节长。不管是什么输入字节长度。这将是非常好的,如果我有一个idication多少字节收到。
- 的字节数似乎并没有得到一次全部读取。例如。在code以上的被称为多次,但从来没有缓冲区包含了所有我从阿尔杜伊诺发送的字节数。有时,只有第一字节,那么以后只有最后一个字节。
- 虽然这code是卡列斯多次,我的主要活动,仅得到通知一次。怎么会是这样?
什么是做正确的方式。每个人都应该实施收集和并置字节的机制?还是我用这个code走错了路?
What is the right way to do this. Should one implement a mechanism that collects and concatenates the bytes? Or am I using this code the wrong way?
推荐答案
我一直有麻烦每次读一个字节的缓冲区大于一。这是因为没有办法保证正确接收到的所有字节。我的工作就是四处打电话,每次重复一个字节读取并如实填写本人的缓冲区。如果这样,我的任何字节不读生病抓在我connectedThread的I / O脚部分,并可以选择处理它,但是我想要的。
I always had trouble reading a byte buffer greater than one at a time. This is because there is no way to guarantee that you received all the bytes correctly. My work around was to call read repeatedly one byte at a time and fill out my buffer. That way if any of my bytes aren't read ill catch that in the I/O catch part of my connectedThread and can choose to deal with it however I want.
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
// You can define this buffer to be 1024 or anything you like
buffer = new byte[3];
mmOutStream.write(253);
bytes = mmInStream.read(buffer,0,1);
mmOutStream.write(254);
bytes = mmInStream.read(buffer,1,1);
mmOutStream.write(255);
bytes = mmInStream.read(buffer,2,1);
mHandler.obtainMessage(MESSAGE_READ, buffer).sendToTarget();
}
catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
}
在这种情况下,我用了一个无符号字节数组从0-255重新present整数。此外,我使用的值255-253的命令来告诉我的Arduino送我某些类型的信息。您没有设置任何值命令重新present到Arduino的,相反,你可以告诉过值,它需要每一个接收信息的请求时发送的Arduino循环。我发现这是唯一的方式,可以确认你接收的字节量的一种(即大小的字节[]缓冲
),尽管在这种情况下,我做了没有放任何东西在我的catch语句为connectedThread,你可以在那里把一个读命令确认收到一个字节。
In this case I used a unsigned byte array to represent integers from 0-255. Furthermore I used values 255-253 as commands to tell my Arduino to send me certain types of information. You do not have to set any value to represent a command to arduino, instead you can just tell the arduino to loop through values it needs to send each time it receives a request for information. I found out this is one of the only ways to can confirm the amounts of bytes you received(i.e the size of your byte[] buffer
).Although in this case I did not put anything in my catch statement for the connectedThread you could put a read command in there to confirm you receive a byte.
下面是我如何处理的readBuffer ...
Here is how I dealt with the readBuffer...
/*
* Bluetooth Handler Method
*/
ConnectedThread connectedThread;
Handler mHandler = new Handler(){
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// Do Something;
Toast.makeText(getActivity(),"CONNECTED",Toast.LENGTH_SHORT).show();
connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
listView.setVisibility(View.GONE);
connectedThread.start();
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
int tempInt = byteToInt(readBuf[0]);
int speedInt = byteToInt(readBuf[1]);
int cadenceInt = byteToInt(readBuf[2]);
EditText temperatureData = (EditText)getActivity().findViewById(R.id.temperatureData);
temperatureData.setText(Integer.toString(tempInt) + " C" );
EditText cadenceData = (EditText)getActivity().findViewById(R.id.cadence);
cadenceData.setText(Integer.toString(cadenceInt) + " rpm");
EditText speedData = (EditText)getActivity().findViewById(R.id.speed_data);
speedData.setText(Integer.toString(speedInt) + " kph");
}
}
};
在这种情况下,我在我的手机上显示实时传感器数据。但是你可以做任何事情。
In this case I was displaying live sensor data on my phone. But you can do anything really.
希望这有助于。
这篇关于与Arduino的Android的蓝牙通讯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!