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);
});
},