与Arduino的Andr​​oid的蓝牙通讯 [英] Android bluetooth communication with Arduino

查看:120
本文介绍了与Arduino的Andr​​oid的蓝牙通讯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究谷歌的蓝牙聊天的例子。我们的目标是获得机器人和和的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的Andr​​oid的蓝牙通讯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆