AndroidとArduinoでBluetooth通信(Arduino側)

環境

Freaduino UNOV1.8.1 FreaduinoセンサシールドV1.2 (XBeeインタフェース付) BluetoothBee(HC-06) BluetoothV2.0(baudrate:9600) ※技適のものを使用しないと法律違反になるようです。 Android6.0.1 ArduinoJson5.0.7

概要

Android端末とBluetoothで通信し、jsonデータでやり取りを行いました その時のArduino側の手順です

ジャンパピン、スイッチの状態

Freaduino_bluetoothbe.png

ArduinoJsonライブラリの追加

・ArduinoIDEを開き、メニューの「スケッチ」>「ライブラリをインクリード」>「ライブラリの管理」を押す ・「LibraryManager」ダイアログの上部右側の「FilterYourSearch」に「json」と入れる ・リストから「ArduinoJson」を選択し、バージョンを選択して(例:Version5.0.7)、「インストール」を押す

BluetoothBeeのボーレートの確認

自分のBluetoothBeeに設定されているボーレードを確認する SoftwareSerialのbegin関数で試したいボーレードを引数に入れ、print関数で"AT"と送る "OK"と返ってきたら、その値(大体ここらへん「9600,19200,38400」) ATコマンドや引数に入れるボーレートの値は以下を参照 http://wiki.seeedstudio.com/wiki/Bluetooth_Bee_v2.0#AT_Commands

スケッチ

ArduinoJsonはjson化した時に使用したバッファを保持しているようで、何回か通信するとバッファ不足でjson化に失敗します その為にクリアをしたいのですがメソッドが無いようです

#include <SoftwareSerial.h>
#include <ArduinoJson.h>

#define RxD 2
#define TxD 3
static SoftwareSerial _blueToothSerial( RxD,TxD );
#define TIMEOUT 1000
#define BLUETOOTBUFFER_SIZE 256
#define RECVBUFFER_SIZE BLUETOOTBUFFER_SIZE
#define SENDBUFFER_SIZE BLUETOOTBUFFER_SIZE
static char _recvBuffer[ RECVBUFFER_SIZE ];

#define JSONBUFFER_SIZE 256
static StaticJsonBuffer<JSONBUFFER_SIZE> _jsonBuffer;
static char _jsonOutputBuffer[ SENDBUFFER_SIZE ];

enum CommandType
{
    Command_None,
    Command_Echo,
};


void setup()
{
    Serial.begin( 9600 );
    pinMode( RxD, INPUT );
    pinMode( TxD, OUTPUT );

    if( setupBluetooth() == false )
        exit( -1 );
    Serial.println( "Setup Complete-----" );
}

void loop()
{
    RecvCommand();
}

void RecvCommand()
{
    if( _blueToothSerial.available() <= 0 )
        return;
    if( bluetoothRecv( TIMEOUT ) < 0 )
        return;
    parseCommand();
}

void parseCommand()
{
    JsonObject& root = _jsonBuffer.parseObject( _recvBuffer );
    CommandType commandType = (CommandType)(const int)root[ "type" ];
    switch( commandType )
    {
    case Command_Echo:
        {
            const char* pMesasge = (const char*)root[ "message" ];
            Serial.print( "EchoMessage:" );
            Serial.println( pMesasge );
            root.printTo( _jsonOutputBuffer, sizeof( _jsonOutputBuffer ) );
            bluetoothSend( _jsonOutputBuffer, true );
            break;
        }
    default:
        {
            Serial.print( "NotDefineCommand:" );
            Serial.println( (int)commandType );
            break;
        }
    }

    ClearJsonBuffer( _jsonBuffer );
}

template<typename T> void ClearJsonBuffer( T& instance )
{
    instance = T();
}

bool setupBluetooth()
{
    _blueToothSerial.begin( 9600 );
    delay(100);
    bluetoothSend( "AT", false );
    return ( bluetoothRecv( TIMEOUT ) >= 0 ) ? true : false;
}

int bluetoothSend( const char* pStr, bool isLn )
{
    Serial.print( "Send:" );
    Serial.println( pStr );
    if( isLn == true )
        _blueToothSerial.println( pStr );
    else
        _blueToothSerial.print( pStr );
    return 0;
}

int bluetoothRecv( int timeOut )
{
    int t = timeOut;
    int sleepTime = 50;
    while( t > 0 )
    {
        delay( sleepTime );//todo なぜかここにないとメッセージを一度に取得できない
        if( _blueToothSerial.available() > 0 )
            break;
        t -= sleepTime;
    }
    if( t <= 0 )
    {
        Serial.println( "Receive Timeout" );
        return -1;
    }
    int i = 0;
    do
    {
        if( i > RECVBUFFER_SIZE )
        {
            Serial.println( "Receive BufferOver" );
            return -2;
        }
        _recvBuffer[ i ] = char( _blueToothSerial.read() );
        i++;
    }while( _blueToothSerial.available() > 0 );
    _recvBuffer[ i ] = '\0';
    Serial.print( "Receive:" );
    Serial.println( _recvBuffer );
    return 0;       
}