Hi mahmoudadler,
I'm also using this tiny BLE modules from Amber, because they are certificated for Germany.
The HEX codes are not very complicated and you can directly start using Bluetooth Low Energy without knowledge of it's complexity. You only have to parse the Serial input.
The SoftwareSerial is limited in it's baudrate, the maximum (without errors) is about 9600. That's why I wired it through an extra Serial to USB converter (FTDI).
Arduino <-> Amb2621 Hardware Serial with 115200 baud
Arduino <-> PC (for debugging) SoftwareSerial with 9600 baud
I have written an ugly sketch for testing a automated connection and transfer.
- scan
- take scan results and connect
- transfer data
/* CENTRAL UART SCAN, CONNECT AND TRANSFER
using AMB2621 BLE module
*/
#include <SoftwareSerial.h>
bool debug = true; // debug output on SoftwareSerial 10, 11
int WAKEUP_PIN = 12; // hardware wakeup setting
SoftwareSerial SoftSerial( 10, 11 ); // RX, TX
void setup()
{
pinMode( WAKEUP_PIN, OUTPUT); // DigitalPin
digitalWrite( WAKEUP_PIN, HIGH );
SoftSerial.begin( 9600 ); // read and write commands to the MCU
Serial.begin( 115200 ); // read and write commands to the AMB2621 BLE module
// CMD_GETBTMAC(); // Show BTMAC of this device
CMD_SCANSTART(); // scan for peripherals -> module acts as central device
delay(1000); // no callback -> scan for 1s
CMD_SCANSTOP(); // first stop scanning
CMD_GETDEVICES_CONNECT(); // proceed scan results
}
void loop()
{
uint8_t DATA[ 4 ] = { 0, 255, 0x2B, 0x2D };
CMD_DATA( DATA, 4 );
delay(1000);
}
// Functions
/* SLEEP
set the module in sleep mode
disables UART -> wake up with WAKEUP_PIN
*/
void CMD_SLEEP() {
byte message[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; // CMD_SLEEP 0x02
byte response[ 6 ] = {};
SoftSerial.println("Send CMD_SLEEP...");
Serial.write( message, sizeof(message)) ; // send command
delay(10);
for ( int i = 0; i < 6; i++ ) { // 02 42 01 00 00 41
response[ i ] = Serial.read();
delay(10);
}
PRS_STATUS( response[ 4 ] ); // check response STATUS
}
/* WAKEUP
* untested
*/
void CMD_WAKEUP() {
digitalWrite( WAKEUP_PIN, LOW );
delay(5);
digitalWrite( WAKEUP_PIN, HIGH );
}
void CMD_GETBTMAC() { // get BTMAC
byte message[] = { 0x02, 0x10, 0x01, 0x00, 0x04, 0x17 };
byte response[ 12 ] = {};
Serial.write( message, sizeof(message) );
delay(10);
for ( int i = 0; i < 12; i++ ) { // 02 50 07 00 00 39 97 0A DA 18 00 33
response[ i ] = Serial.read();
delay(10);
}
PRS_STATUS( response[ 4 ] ); // check response STATUS
SoftSerial.print( "\nBTMAC = " );
for ( int i = 5; i < 11; i++ ) SoftSerial.print( response[ i ], HEX );
SoftSerial.println();
}
void CMD_SCANSTART() {
byte message[] = { 0x02, 0x09, 0x00, 0x00, 0x0B };
byte response[ 6 ] = {};
Serial.write(message, sizeof(message));
delay( 10 );
for ( int i = 0; i < 6; i++ ) { // 02 49 01 00 00 41
response[ i ] = Serial.read();
delay( 10 );
}
PRS_STATUS( response[ 4 ] );
}
void CMD_SCANSTOP() {
byte message[] = { 0x02, 0x0A, 0x00, 0x00, 0x08 };
byte response[ 6 ] = {};
Serial.write(message, sizeof(message));
delay( 10 );
for ( int i = 0; i < 6; i++ ) { // 02 49 01 00 00 41
response[ i ] = Serial.read();
delay( 10 );
}
PRS_STATUS( response[ 4 ] );
}
/* Get devices and connect to the first one
IN CONSTRUCTION
TODO: - waiting for START_SIGNAL 0x02
- check CMD_GET_CNF value 0x50
- proceed number of devices and check whose names
*/
void CMD_GETDEVICES_CONNECT() {
byte message[] = { 0x02, 0x0B, 0x00, 0x00, 0x09 }; // CMD_GETDEVICES
byte response = 0xFF;
byte BTMAC[ 6 ];
int CS = 0;
bool ok = false;
Serial.write(message, sizeof(message));
delay(10);
int i = 0;
do {
response = Serial.read();
delay(10);
if ( ( i == 4 ) && ( PRS_STATUS( response ) ) ) { // skip 4 fields (START_SIGNAL, CMD, LENGTH) and check STATUS
ok = true;
}
if ( ( i == 5 ) && ( ok ) ) {
SoftSerial.println( "Found " + String( response, HEX ) + " device(s)" );
}
if ( ( ok ) && ( i > 5 ) && ( i < 13 ) ) {
BTMAC[ i - 6 ] = response;
}
SoftSerial.write(response);
i++;
} while ( response != 0xFF );
if ( debug ) for ( int i = 0; i < 6; i++ ) SoftSerial.write( BTMAC[ i ] );
// connect message without BTMAC and CS
byte conn[ 11 ] = { 0x02, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// add BTMAC
for ( int i = 4; i < 10; i++ ) conn[ i ] = BTMAC[ i - 4 ];
if ( debug ) for ( int i = 0; i < 11; i++ ) SoftSerial.write( conn[ i ] );
// calculate a XOR checksum
for ( int i = 0; i < 10; i++ ) CS = CS ^ conn[ i ];
if ( debug ) SoftSerial.println( "CS = " + String( CS, HEX ) + "[hex]\tCS = " + String( CS, DEC ) + "[dec]\n" );
// complete message with checksum
conn[ 10 ] = CS;
if ( debug ) for ( int i = 0; i < 11; i++ ) SoftSerial.write( conn[ i ] );
// write connect message
Serial.write(conn, sizeof(conn)); // call CMD_CONNECT 0x02, 0x06, 0x06, 0x00, BTMAC, CS
delay( 10 );
while( Serial.read() != 0x02 ){}; // waiting for response
/*
* TODO check response, CHANNELOPEN
*/
}
void CMD_DATA( unsigned char* DATA, uint8_t len ) {
int CS = 0;
byte message[ 5 + len ] = { 0x02, 0x04, 0x04, 0x00 }; // DATA, CS };
// add DATA
for ( int i = 4; i < len + 4; i++ ) message[ i ] = DATA[ i - 4 ]; // reinterpret_cast<unsigned char *>(DATA[ i - 4 ]);
// calculate XOR checksum
for ( int i = 0; i < 5 + len; i ++ ) CS = CS ^ message[ i ];
// complete message with checksum
message[ 4 + len ] = CS;
Serial.write( message, sizeof( message ) );
// proceed response message
}
int PRS_STATUS( byte STATUS ) {
switch ( STATUS ) {
case 0x00 :
if ( debug ) SoftSerial.println("OK\n");
return 1;
break;
case 0x01 : // failed
if ( debug ) SoftSerial.println("Operation failed\n");
return 0;
break;
case 0xFF : // not permitted
if ( debug ) SoftSerial.println("Operation not permitted\n");
return 0;
break;
default :
return 0;
break;
}
}
I'm working on a more stable version more checks and parsers. Please let me know if you like to contribute.
Best regards
Hannes