Receive data from BLE (HM10 module/Arduino)

Ask, and ye shall receive.
avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Receive data from BLE (HM10 module/Arduino)

Postby avip » 14:04, 30 May 2015

I am trying to read a string that the BLE module is sending as a result of read command.
The examples I found are related to notifications and they are not applicable to HM10.
How can I receive a String after such read command?
Is there any JavaScript function that is "waiting" for such answer from the BLE serial channel?

DonPancoe
Posts: 25
Joined: 06:53, 20 Nov 2014
Location: Philadelphia, PA, USA
Contact:

Re: Receive data from BLE (HM10 module/Arduino)

Postby DonPancoe » 22:12, 01 Jun 2015

Sharing with the group a private response I had prepared for avip...

I looked at the HM10 using a pretty powerful BLE tool from Cypress called CySmart. Here is what I found...

Code: Select all

UUID        UUID Description                         Value
0xFFE1      has 'Write w/o Response' and 'Read'      uint8 array of read/write chars
0x2902      Client Characteristic Configuration      write "01:00" here for notifications
0x2901      Characteristic User Description          48:4D:53:6F:66:74 ("HMSoft")

Since CySmart can also read and write characteristics, I tried a little experiment. I connected the HM10 UART through a USB-UART adapter to a simple terminal program called Termite. Once I enabled notifications, sending a character or group of characters from Termite would cause those characters to appear as hex values in UUID 0xFFE1. However, reading UUID 0xFFE1 again after that only returned a value of 0x00, so my idea that the last UART value received might be buffered was proved false.

Writing a group of characters from CySmart to UUID 0xFFE1 would cause those characters to appear in Termite, so I did verify true two-way serial communication.

Regarding how to receive notifications in Evothings (having now shown that using the read command with the HM10 is not useful), the "arduino-led-onoff-ble" is not the example project to use. It states in the source code of arduinoble.js for that project that "This is a very simple library that has only write capability, read and notification functions should be added."

A better bet would be to start with "arduino-ble" (originally based on the RedBearLab BLE Shield), modifying app.js from that project for the HM10 as follows.

Starting from line 214 of app.js, which changes highlighted by comments...

Code: Select all

getServices: function(deviceHandle)
{
   console.log('Reading services...');

   evothings.ble.readAllServiceData(deviceHandle, function(services)
   {
      // Find handles for characteristics and descriptor needed.
      for (var si in services)
      {
         var service = services[si];

         for (var ci in service.characteristics)
         {
            var characteristic = service.characteristics[ci];

            if (characteristic.uuid == '0000FFE1-0000-1000-8000-00805f9b34fb')  // This line changed for HM10
            {
               app.characteristicRead = characteristic.handle;
            }
            else if (characteristic.uuid == '0000FFE1-0000-1000-8000-00805f9b34fb')  // This line changed for HM10
            {
               app.characteristicWrite = characteristic.handle;
            }

            for (var di in characteristic.descriptors)
            {
               var descriptor = characteristic.descriptors[di];

               if (characteristic.uuid == '0000FFE1-0000-1000-8000-00805f9b34fb' &&  // This line changed for HM10
                  descriptor.uuid == '00002902-0000-1000-8000-00805f9b34fb')
               {
                  app.descriptorNotification = descriptor.handle;
               }
            }
         }
      }

      if (app.characteristicRead && app.characteristicWrite && app.descriptorNotification)
      {
         console.log('RX/TX services found.');
         app.startReading(deviceHandle);
      }
      else
      {
         console.log('ERROR: RX/TX services not found!');
      }
   },
   function(errorCode)
   {
      console.log('readAllServiceData error: ' + errorCode);
   });
},

Lastly, the lines that pertain to actually turning on and receiving notifications start on line 151 as follows. Every time the HM10 sends a new notification, this code calls the function app.drawLines and sends it the new value(s) from the HM10. Note that this example is getting uint16 numerical values for a graphing function, but you could get uint8 values (or arrays) for ASCII chars, too. Having said all that, I'm not sure I ever got around to actually doing this with the HM10, but I have with other BLE devices, like the RFDuino.

Code: Select all

startReading: function(deviceHandle)
{
   console.log('Enabling notifications');

   // Turn notifications on.
   app.write(
      'writeDescriptor',
      deviceHandle,
      app.descriptorNotification,
      new Uint8Array([1,0]));

   // Start reading notifications.
   evothings.ble.enableNotification(
      deviceHandle,
      app.characteristicRead,
      function(data)
      {
         app.drawLines([new DataView(data).getUint16(0, true)]);
      },
      function(errorCode)
      {
         console.log('enableNotification error: ' + errorCode);
      });
},

avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Re: Receive data from BLE (HM10 module/Arduino)

Postby avip » 04:53, 02 Jun 2015

Thanks, Don.
Probably something else is missing in the arduino ble example for HM10 since it cannot even connect.
I assume that there is a need to change something in the area of lines 69...
startScan: function()
{
console.log('Scanning...');
evothings.ble.startScan(
function(deviceInfo)
{
if (app.knownDevices[deviceInfo.address])
{
return;
}

avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Re: Receive data from BLE (HM10 module/Arduino)

Postby avip » 05:36, 02 Jun 2015

on the other end, the easy ble maybe better example.
With few modifications it can connect and communicate

DonPancoe
Posts: 25
Joined: 06:53, 20 Nov 2014
Location: Philadelphia, PA, USA
Contact:

Re: Receive data from BLE (HM10 module/Arduino)

Postby DonPancoe » 06:03, 02 Jun 2015

You are right, there is one other thing I forgot that is keeping you from connecting to the HM10. I had changed the device name of my HM10 to "HMSoft531" to indicate I had upgraded the firmware to v5.31 on my device, but I believe the default device name is simply "HMSoft". You can confirm this by using the ble-discovery Evothings example app.

Here is the code you need to change, staring with line 68 of app.js, changed lines indicated by comments as before.

Code: Select all

startScan: function()
{
   console.log('Scanning...');
   evothings.ble.startScan(
      function(deviceInfo)
      {
         if (app.knownDevices[deviceInfo.address])
         {
            return;
         }
         console.log('found device: ' + deviceInfo.name);
         app.knownDevices[deviceInfo.address] = deviceInfo;
         if (deviceInfo.name == 'HMSoft' && !app.connectee)      // line changed for HM10
         {
            console.log('Found HMSoft');                         // line changed for HM10
            connectee = deviceInfo;
            app.connect(deviceInfo.address);
         }
      },
      function(errorCode)
      {
         console.log('startScan error: ' + errorCode);
      });
},

avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Re: Receive data from BLE (HM10 module/Arduino)

Postby avip » 20:06, 02 Jun 2015

It doesn't seem to work.
Looks like there is no connection to HM10 with this example
The other example "Easy BLE" is able to connect and write to BLE.
Is it possible to modify it for getting HM10 notifications?

DonPancoe
Posts: 25
Joined: 06:53, 20 Nov 2014
Location: Philadelphia, PA, USA
Contact:

Re: Receive data from BLE (HM10 module/Arduino)

Postby DonPancoe » 14:16, 03 Jun 2015

I tried it here and, according to both the Evothings terminal and an LED on the Microduino-BT, the Evothings client app is connecting to the HM10. But the Evothings terminal then says "ERROR: RX/TX services not found!"

I also tried to connect to the HM10 with a generic Nordic app I have (nRF Master Control Panel) and was able to both send and receive characters between a terminal and the tablet running the app, so it's not a problem with the tablet or with the HM10.

I believe it is an issue with app.js (and perhaps even evothings.js underneath) being written to have separate handles for characteristicRead and characteristicWrite, but the HM10 does both through a single characteristic, 0xFFE1.

As far as modifying this or any other example app to work with the HM10 and its unusual single characteristic for both RX and TX, I'm afraid that's beyond my current understanding. Perhaps someone from Evothings could chime in.

Fredrik
Site Admin
Posts: 196
Joined: 15:00, 18 Nov 2013

Re: Receive data from BLE (HM10 module/Arduino)

Postby Fredrik » 15:27, 03 Jun 2015

When you mentioned "Nordic", I thought of a small module we have, nordic-nRF51822-ble.js (usage example), which seems to do what you need.

It currently has different UUIDs for read and write, but it should be a simple matter to change that to match your hardware.

avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Re: Receive data from BLE (HM10 module/Arduino)

Postby avip » 19:49, 03 Jun 2015

I am trying now another evothings example: arduino-scriptable-ble (or as it s seen "Arduino Input BLE")
I was able to connect to HM10 with the usual UUID modifications and also to operate the write commands.
I am focusing on the following code:

internal.enableNotifications = function(win, fail)
{
console.log('Enabling notifications');

if (internal.notificationsEnabled) { return }

internal.notificationsEnabled = true;

var success = true;

// Turn notifications on.
internal.device.writeDescriptor(
'0000ffe1-0000-1000-8000-00805f9b34fb',
'00002902-0000-1000-8000-00805f9b34fb',
new Uint8Array([1,0]),
function()
{
console.log('writeDescriptor success');
},
function(errorCode)
{
success = false;
console.log('writeDescriptor error: ' + errorCode);
fail && fail('writeDescriptor error: ' + errorCode);
});

// Start reading notifications.
internal.device.enableNotification(
'0000ffe1-0000-1000-8000-00805f9b34fb',
function(data)
{
internal.notificationCallback(data);
},
function(errorCode)
{
success = false;
console.log('enableNotification error: ' + errorCode);
fail && fail('enableNotification error: ' + errorCode);
});

success && win && win();
};

internal.notificationCallback = function(data)
{
// Pre define value
data = 60;

var value = data;
// Read input value.
/* var value = new Uint8Array(data);
var buf = new Uint8Array(data);
var type = buf[2];
var pin = buf[3];
var value = buf[4] | (buf[5] << 8);

// Type 'R' (digital read).
if (82 == type)
{
var callback = internal.digitalPinCallbacks[pin];
callback && callback(value)
}
// Type 'A' (analog read).
else if (65 == type)
{
var callback = internal.analogPinCallbacks[pin];
callback && callback(value)
}
*/
var callback = internal.analogPinCallbacks[0];
callback && callback(value)


};


After connection, If I instruct the HM10 to send something, I can get the number 60 on screen together with the analog line chart.
The number 60 was predefined in the code.
Which means that the evothings gets that interrupt of receiving BLE data.
I am trying to understand how to get the REAL data from the HM10. The "data" value doesn't seem to hold anything...
Where is the REAL data stored???

avip
Posts: 12
Joined: 17:48, 06 Apr 2015

Re: Receive data from BLE (HM10 module/Arduino)

Postby avip » 21:26, 03 Jun 2015

I found how to receive a single char:
inside arduinoble.js need to change the original structure to:

internal.notificationCallback = function(data)
{

// Read input value.
var value = new Uint8Array(data);
var buf = new Uint8Array(data);
var value = buf[0];
$('#ArduinoStatus').html('Analog value of pin is: ' + value)
var callback = internal.analogPinCallbacks[0];
callback && callback(value)


};

Now, how can I get a string from the HM10 instead of only one char...?


Return to “Questions and answers”

Who is online

Users browsing this forum: No registered users and 13 guests