Thursday, March 20, 2014

Bluetooth LE connection


This feature has been added to the robot AWBB v2.0

Why using Bluetooth LE?

To export data from the robot to the internet we have chosen to link it to a mobile device using this new kind of connection: the Bluetooth LE (Low Energy). It's made for connected object (Internet of things for example) and it has the particularity to consume a few quantity of energy.

We have chosen the BLE-LINK v1.0 from DFRobot as it's easy to configure, it use a serial connection and allows 5V on RX pin.
To learn more on Bluetooth LE, go on Wikipedia

Wiring

Due to lack of available pins, we decide to connect the BLE-Link as follow: 
  • TX pin of the BLE-Link to the SPI/ICSP connector on SCK 
  • RX pin of the BLE-Link to the SPI/ICSP connector on MISO.


Powering the BLE-Link

Regarding BLE-Link power, we encountered a small problem, as it based on xBee board powered with 3.3V and having only 5V on the Robot, we decided to solder a USB female plug on the Robot to have 5V and connect it to USB port of the BLE-Link using a standard USB cable. 

Initialize and configure the BLE-Link

You will find all these information on the DFRobot Wiki page of the BLE-Link

Coding

You have to include the SoftwareSerial library to your project but with Arduino IDE 1.5.4 some core arduino header files must be patched to be able to compile.

You have to add these 4 definition (digitalPinToPCICR, digitalPinToPCICRbit, digitalPinToPCMSK, digitalPinToPCMSKbit(p) ) into the pin_arduino.h file in these following directories:
  • ...\Arduino\hardware\arduino\avr\variants\robot_control 
  • ...\Arduino\hardware\arduino\avr\variants\robot_motor
#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) 0
#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
view raw pins_arduino.h hosted with ❤ by GitHub

How to use 2 devices using SoftwareSerial library?

When you have 2 devices using SoftwareSerial library it's important to choose which one of the devices will be the main one, the one who will listening the RX pin. Once this device has received something and realized its treatment, the second one can realize a request or get its data from its RX pin.

In our case on motor board, on beginGPS() we start the serial connection to te GPS and close it:
void RobotMotorBoard::beginGps(){
// 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
GPS.begin(9600);
// Output max info
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// Refresh each 5 seconds
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
delay(1000);
gpsSerial.end();
}
And each time the GPS needs to be processed the processGPS is called:
void RobotMotorBoard::processGps(){
btSerial.end();
gpsSerial.begin(9600);
//... Processing GPS part
gpsSerial.end();
btSerial.begin(19200);
}

The rest of the time can be used to listen the RX port for the Bluetooth device:
void RobotMotorBoard::process(){
if(isPaused)return;//skip process if the mode is paused
if(mode==MODE_SIMPLE){
//do nothing? Simple mode is just about getting commands
}else if(mode==MODE_LINE_FOLLOW){
//do line following stuff here.
LineFollow::runLineFollow();
}else if(mode==MODE_ADJUST_MOTOR){
Serial.println('a');
}
if ( btSerial.available()) {
c = btSerial.read();
if ( c == '$' ) {
cpt = 0;
} else if ( c == '\n' || c == '%') {
cmd[cpt++] = 0;
cmdok = true;
btSerial.print("OK\n");
} else {
cmd[cpt++] = c;
}
}

No comments:

Post a Comment