Mobile  Arduino Communication BLE device

Mobile Arduino Communication BLE device © Apache-2.0

Thanks to Ionic framework we will send custom commands to an Arduino using a BLE device to light LED.

  • 5,793 views
  • 1 comment
  • 11 respects

Components and supplies

Apps and online services

About this project

Every time I need to work deep in a project I need to proceed step by step. This project is an example of the first step on the road of a more complicated project.

I hope that what I'm going to write here can be interesting for others.

I bought for me and my project a little electronics bricks to empower my project of Bluetooth Low Energy.

Arduino side is really simple, I connected the MakerStudio BLE component to Arduino in a really simple mode. It has only 4 pins: GND, 5V, RX, TX connected as you can see in the Fritzing picture.

  • GND -> GND
  • 5V -> 5V
  • RX -> PIN 11
  • TR -> PIN 10

The code is really simple. It use a library fixed and customized by me, check it out in attachment, provided by MakerStudio that is a wrap of SoftwareSerial library. My library is not really needed, you can do the same using SoftwareSerial. if you like you can connect pins directly to Arduino Serial and use Serial object, but in his way you can still use Serial for other thinks like Debug ;).

In the loop I will check data received:

  • 11 -> light on LED
  • 10 -> light off LED
#include "EB_Bluetooth_4_0.h"
#include <SoftwareSerial.h>
#include <WString.h>
#define LED 4 // Pin where Led is Connected
#define RX 11 // Pin where Receive Serial Software BLE <-> Arduino
#define TX 10 // Pin where Transmission Serial Software BLE <-> Arduino
EB_Bluetooth_4_0 myBluetooth(RX,TX);
void setup(){
 Serial.begin(9600);
 pinMode(LED,OUTPUT);
 digitalWrite(LED,LOW);
 myBluetooth.begin();
 Serial.println("Waiting to be connected");
}
void loop(){
 String command = "";
 while(myBluetooth.available()){
   // while on serial is available data I will continue to concatenate data
   command += (char)myBluetooth.read();
 }
 if (command.length()==2){
   switch(command.charAt(1)){
     case '0': // 0 means off -> LOW on Pin
       digitalWrite(LED,LOW);
     break;
     case '1': // 1 means on -> HIGH on Pin
       digitalWrite(LED,HIGH);
     break;
   }
 }
 delay(1000);
}
 

To communicate with it I use a Mobile Phone thanks to Ionic framework. Ionic is a really interesting framework to produce hybrid mobile app. Adding Cordova plugin Bluetooth Low Energy (BLE) Central Plugin we will can communicate with Arduino.

App is really simple is a tab app with 2 tab:

  • 1st: is a presentation tab, it's not useful
  • 2nd: present a list of device (if you forget to enable Bluetooth it will remember it for you), once selected one 2 buttons to light on e light off the led.

First button send 11, the second 10. The first char is not needful, but I used it for a next step.

AngularJS controllers are really simple:

  • BLECtrl is the controller that handle device list view, it checks if Bluetooth is enabled and then scan and show results
  • BLEDetailCtrl is the controller to handle action on the connected device, sending commands.
 
 
.controller('DashCtrl', function($scope) {})
 
.controller('BLECtrl', function($scope, $ionicPopup, Devices, BLE) {
 ble.isEnabled(
   function() {
     console.log("Bluetooth is enabled");
   },
   function() {
     $ionicPopup.alert({
        title: 'WARNING!',
        template: 'Bluetooth is not enabled!'
      });
   });
 
 // keep a reference since devices will be added
 $scope.devices = Devices.all();
 
 var success = function () {
   if ($scope.devices.length < 1) {
       // a better solution would be to update a status message rather than an alert
       alert("Didn't find any Bluetooth Low Energy devices.");
   }
 };
 
 var failure = function (error) {
     alert(error);
 };
 
 // pull to refresh
 $scope.onRefresh = function() {
     BLE.scan().then(
         success, failure
     ).finally(
         function() {
             $scope.$broadcast('scroll.refreshComplete');
         }
     )
 }
 
 // initial scan
 BLE.scan().then(success, failure);
 
})
 
.controller('BLEDetailCtrl', function($scope, $stateParams, $log, $ionicPopup, BLE) {
 $scope.device = null;
 
 BLE.connect($stateParams.deviceId).then(
     function(peripheral) {
         $scope.device = peripheral;
     }
 );
 
 writeToDevice = function (dest,val){
   if ($scope.device == null) return;
 
   BLE.addQueue(BLE.stringToArrayBuffer(dest+val));
 };
 
 $scope.send = function(){
   writeToDevice("1","1");
 }
 
 $scope.unSend = function(){
   writeToDevice("1","0");
 }
});

BLE AngularJS Service developer that wrap ble object exported by cordova plugin offer 2 methods to send command:

  • sendData: that write directly data on BLE communication
  • addQueue: that append command in a queue that it will be processed every 250 ms.

Services used inside application to wrap cordova plugin.

  • Devices devices is a Model Controller that handle data and list of devices.
  • BLE is a wrapper of ble cordova plug-in. 
 
 
.factory('Devices', function() {
 // Might use a resource here that returns a JSON array
 
 // Some fake testing data
 var devices = [];
 
 return {
   all: function() {
     return devices;
   },
   clean: function(){
     devices.splice(0,devices.length);
   },
   remove: function(device) {
     devices.splice(devices.indexOf(device), 1);
   },
   get: function(deviceId) {
     for (var i = 0; i < chats.length; i++) {
       if (devices[i].id === parseInt(deviceId)) {
         return devices[i];
       }
     }
     return null;
   },
   add: function(device){
     devices.push(device);
   }
 };
})
 
.factory('BLE', function($q, $interval, Devices) {
 
 var connected = null;
 var service = null;
 var characteristic = null;
 var dataQueue = [];
 
 var ret = {
   stringToArrayBuffer: function(str) {
       var ret = new Uint8Array(str.length);
       for (var i = 0; i < str.length; i++) {
           ret[i] = str.charCodeAt(i);
       }
       // TODO would it be better to return Uint8Array?
       return ret.buffer;
   },
   isConnected: function(){
     return connected!==null;
   },
   scan: function() {
       Devices.clean();
       var deferred = $q.defer();
 
       // disconnect the connected device (hack, device should disconnect when leaving detail page)
       if (connected) {
           ret.disconnect();
       }
 
       ble.startScan([],  /* scan for all services */
           function(peripheral){
               Devices.add(peripheral);
           },
           function(error){
               deferred.reject(error);
           });
 
       // stop scan after 5 seconds
       setTimeout(ble.stopScan, 5000,
           function() {
               deferred.resolve();
           },
           function() {
               console.log("stopScan failed");
               deferred.reject("Error stopping scan");
           }
       );
 
       return deferred.promise;
   },
   disconnect: function(){
     ble.disconnect(connected.id, function() {
         alert("Disconnected " + connected.id);
         console.log("Disconnected " + connected.id);
     });
     connected = null;
   },
   connect: function(deviceId) {
       var deferred = $q.defer();
 
       ble.connect(deviceId,
           function(peripheral) {
               connected = peripheral;
               deferred.resolve(peripheral);
               angular.forEach(connected.characteristics,function(c){
                 var props = c.properties;
                 var hasWrite = props.indexOf("Write")>0 || props.indexOf("WriteWithoutResponse")>0;
                 if (hasWrite) {
                   characteristic = c.characteristic;
                   service = c.service;
                 }
               });
           },
           function(reason) {
               deferred.reject(reason);
           }
       );
 
       return deferred.promise;
   }, 
   sendData: function(data){
       var deferred = $q.defer();
       ble.writeWithoutResponse(connected.id, service, characteristic, data, 
       function(response){
         deferred.resolve(response);
       }, 
       function(response){
         alert("send ko " + response);
         deferred.reject(response);
       });
       return deferred.promise;
   },
   addQueue: function(d){
     if (dataQueue.length<=3)
       dataQueue.push(d);
   }
 };
 
 $interval(function(){
   if (dataQueue.length>0 && connected!==null){
     var d = dataQueue.shift();
     ret.sendData(d);
   }
 },250);
 return ret;
});

You can find out more information in my blog. Sorry, for now is in only in Italian language, but I will translate it as soon as possible.

Code

The Code
In the repository you will find out: * Arduino Sketch * Ionic Code * Fritzing schema and custom component file
EB_Bluetooth
Arduino Library to communicate with BLE kit.

Schematics

Breadboard Schema
Arduino Connected to BLE device and to a simple LED
Arduino ble led

Comments

Similar projects you might like

Arduino To Excel Communication

by Mahamudul Karim Khondaker

  • 26,394 views
  • 14 comments
  • 57 respects

Control Home Appliances Through Web Or Mobile

Project tutorial by Team Gadget Programmers

  • 9,861 views
  • 4 comments
  • 22 respects

Morse Code Communication Using Arduino

Project tutorial by Jalal_Mansoori

  • 7,722 views
  • 17 comments
  • 30 respects

Python3 and Arduino Communication

Project tutorial by Jalal_Mansoori

  • 4,430 views
  • 4 comments
  • 12 respects

Low Power RF Beacon for Remote Sensing & Communication

Project tutorial by Shahariar

  • 3,848 views
  • 1 comment
  • 17 respects
Add projectSign up / Login