nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.36k stars 711 forks source link

Some problem with bytes & integers #317

Closed iotlearner0level closed 6 years ago

iotlearner0level commented 6 years ago

i am trying to follow fake polar sensor example from andreas spiess video#174 (swiss accent engineer: https://www.youtube.com/watch?v=osneajf7Xkg ) specifically this example based on the esp32 ble server example: https://github.com/SensorsIot/Bluetooth-BLE-on-Arduino-IDE/blob/master/Polar_H7_Sensor/Polar_H7_Sensor.ino . on the android side, nrfconnect works ok but i am trying to use app inventor 2 heart rate monitor example (http://appinventor.mit.edu/explore/blogs/karen/2016/08/heart.html )

while the android app reads the byte values, there is some trouble with bytes to number conversion and i get string like 14HeartRate0Calories0000 BPM if i remove the round function (which causes error)

i am new to this BLE concept and i came here from that youtube video. i am using appinventor example just to understand the idea, so any comments will certainly be helpful.

My ultimate goal is to display android caller id number on esp32 connected oled via BLE. don't know if that is possible directly, so my idea is to make an app run on android which can read notifications and send this data via ble service to the esp32 oled.

Another thing i want to try is to send bicycle speed via lora to another esp32 lora and send it via ble to "standard" fitness trackers.

it is only wishful thinking at this stage, but this ble+wifi+lora has blown my mind :)

chegewara commented 6 years ago

Can you paste the part of code you are preparing data to send? Its tricky.

PS ive been testing heart rate monitor app on my esp32 with inventor 2 heart rate monitor or similar from google play and i can read values.

iotlearner0level commented 6 years ago

sorry don't understand it properly, pls find the whole code:

// Based on Neil Kolban's example file: https://github.com/nkolban/ESP32_BLE_Arduino

include

include

include

include

byte flags = 0b00111110; byte bpm; byte heart[8] = { 0b00001110, 60, 0, 0, 0 , 0, 0, 0}; byte hrmPos[1] = {2};

bool _BLEClientConnected = false;

//#define heartRateService BLEUUID((uint16_t)0x180D)

define heartRateService BLEUUID((uint16_t)0x180D)

BLECharacteristic heartRateMeasurementCharacteristics(BLEUUID((uint16_t)0x2A37), BLECharacteristic::PROPERTY_NOTIFY); BLECharacteristic sensorPositionCharacteristic(BLEUUID((uint16_t)0x2A38), BLECharacteristic::PROPERTY_READ); BLEDescriptor heartRateDescriptor(BLEUUID((uint16_t)0x2901)); BLEDescriptor sensorPositionDescriptor(BLEUUID((uint16_t)0x2901));

class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer* pServer) { _BLEClientConnected = true; };

void onDisconnect(BLEServer* pServer) {
  _BLEClientConnected = false;
}

};

void InitBLE() { BLEDevice::init("FT7"); // Create the BLE Server BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks());

// Create the BLE Service BLEService *pHeart = pServer->createService(heartRateService);

pHeart->addCharacteristic(&heartRateMeasurementCharacteristics); heartRateDescriptor.setValue("Rate from 0 to 200"); heartRateMeasurementCharacteristics.addDescriptor(&heartRateDescriptor); heartRateMeasurementCharacteristics.addDescriptor(new BLE2902());

pHeart->addCharacteristic(&sensorPositionCharacteristic); sensorPositionDescriptor.setValue("Position 0 - 6"); sensorPositionCharacteristic.addDescriptor(&sensorPositionDescriptor);

pServer->getAdvertising()->addServiceUUID(heartRateService);

pHeart->start(); // Start advertising pServer->getAdvertising()->start(); }

void setup() { Serial.begin(115200); Serial.println("Start"); InitBLE(); bpm = 1; }

void loop() { // put your main code here, to run repeatedly:

heart[1] = (byte)bpm; int energyUsed = 3000;

heart[3] = (byte)(bpm 256 / 256); heart[2] = (byte)(bpm 256 - (heart[2] * 256)); Serial.println(bpm);

heartRateMeasurementCharacteristics.setValue(heart, 8); heartRateMeasurementCharacteristics.notify();

sensorPositionCharacteristic.setValue(hrmPos, 1); bpm++;

delay(2000); }

iotlearner0level commented 6 years ago

in the app inventor example relevant code block is:

http://appinventor.mit.edu/explore/sites/explore.appinventor.mit.edu/files/blog/hrm4.png

from this project: http://appinventor.mit.edu/explore/blogs/karen/2016/08/heart.html

chegewara commented 6 years ago

Im guessing now, but i think this app (app inventor) is expecting only BPM value and you are sending much more. Try to change: byte flags = 0b00111110; to 0b00000000 byte heart[8] = { 0b00001110, 60, 0, 0, 0 , 0, 0, 0}; to byte heart[3] = { 0b00000000, 60, 0}; heart[3] = (byte)(bpm256 / 256); to //heart[3] = (byte)(bpm256 / 256);

iotlearner0level commented 6 years ago

Now i am getting this format: 14HeartRate-1-163-770 BPM without the round block because that doesn't work. i am clueless because i have some difficulty working with numbers..

chegewara commented 6 years ago

In my opinion, and i didnt study this app well, its not best app to work with ble. As far as i can see they are using readValue() in loop, but you can and you are using notifications on esp32. Their way is very inefficient and may be not best solution in your other apps.

chegewara commented 6 years ago

Try this app with your esp32 code without my changes suggestions:

https://play.google.com/store/apps/details?id=net.hustons.bluetoothlecardiomonitor

iotlearner0level commented 6 years ago

ok, i get it. so looks like i am stuck now because that seems to be the only ble library for appinventor (http://iot.appinventor.mit.edu/#/bluetoothle/bluetoothleintro ) according to page it says developed by a university grant by Intel ( http://appinventor.mit.edu/extensions/ )

i was looking for an easy solution to write a program on android, looks like there isn't any. i will try to send data from android to esp32 and try again in a few days.

chegewara commented 6 years ago

I have to apologize. App inventor has everything you need to build bluetooth heart rate app, with Reagister for notifications. Your arduino app seems to be good, at least works with nRF and with heart rate monitor android application. Now you have to figure out how to receive data and what to do with it in app inventor. Thanks for sharing with us app inventor, i think im gona like it and use to build few test and example apps.

chegewara commented 6 years ago

@iotlearner0level This is not only way you can do it, but ist how i do it: appinventor

iotlearner0level commented 6 years ago

looks like that hr monitor project above (https://drive.google.com/open?id=0B0k5c5YtPa8EZWRfZWFIbkY3MG8) has old version ble extension. i updated it (from http://iot.appinventor.mit.edu/assets/resources/edu.mit.appinventor.ble.aix ) , and some blocks have changed. right now it hangs at 90% will update the results when i overcome that problem.

chegewara commented 6 years ago

Just change name and add to your app inventor library (remove zip extension from name): Heart_rate_monitor_simple.aia.zip

iotlearner0level commented 6 years ago

Thanks for sharing code. works perfect! although, previous code fails....but that is mainly because i don't understand how connection is established in ble in appinventor.

in the Heart_rate_monitor_simple.aia.zip i removed the select list item and i see (14 heartrate 0 255 255 63 179 0) so to get the other data i need select list item list index 1-8?

Also, what is the .RegisterForBytes block? it is not even mentioned in the help. I am confused between registerfor bytes, integer, float and string blocks...

by the way, that 90% hang problem was because my phone was not in the same wifi network as my webbrowser where i was working with the code. that original hr code still doesn't work with updated ble extension module, will have to look a little further..

.... also, this one is hosted on amazon cloud http://code.appinventor.mit.edu/login/ just in case ai2.mit.edu doesn't work....

Now, back to my original problem, how to send call notifications (and caller id) via ble from android->esp32 ? is this possible? Although i have found a good intro to the topic (https://arduinoplusplus.wordpress.com/2017/05/23/reliable-bluetooth-le-comms-between-arduino-and-mit-app-inventor-ai2/ ) but it is still beyond my comprehension :)

chegewara commented 6 years ago

We have few questions here: 1) what is RegisterForBytes and how it differs from e.g. RegisterForString? if you are familiar with ntifications and register for notification in BLE library for esp32 then it is almost the same, just here you have returned value by type; in heart rate monitor we have packed data in array of uint8 values, but if we will use esp32 with BLE_notify example, then we can registerForString because we are sending string

2) yes, to get other data you can use index 1-8, but not exactly; you have to study how data packet is build, e.g. beat rate value is uint16 which mean its placed in bits 0-1 (index 1-2), so knowledge about meaning of each byte is important

3) you have to study BLEesp32 library and learn a lot, i think about myself i am aprentice in mather of BLE and i have a loooot to study; check this links: https://www.bluetooth.com/specifications/gatt - read HRS https://www.bluetooth.com/specifications/gatt/legacy-profiles https://www.bluetooth.com/specifications/profiles-overview

iotlearner0level commented 6 years ago

thanks for responding. but i was more interested in working example, because by the time i will understand it, i will be old and they will move to something else like 5.5G or 6G, lora....

In addition to what was previously asked, i have some difficulty in 16-bit vs 128bit uuid in esp32ble library. in the code pasted above, BLECharacteristic heartRateMeasurementCharacteristics(BLEUUID((uint16_t)0x2A37), however in the original example #define uuid is used. how does that work in the esp32 library?

while nrfconnect is a great app, if i can create packet out of my own, i understand it better...here is where appinventor part comes in handy.

i found a few links on appinventor ble, and they mostly revolve around arduino 101 ble, but i think, esp32ble should be easy to adapt. i will get back once i read these:

http://ai2inventor.blogspot.in/2017/06/controlling-bluetooth-low-energy.html http://www.limifrog.io/2017/05/ble-transfers-using-mit-app-inventor-for-android/ https://github.com/LimiFrog/LimiFrog-SW/tree/master/firmwares_and_utilities/MIT_AppInventor2 http://www.appinventor.tw/ble_lesson1_blink https://www.hackster.io/daquilnp/bluetooth-hr-monitor-android-app-with-mit-app-inventor-27229c https://create.arduino.cc/projecthub/45349/control-rgb-led-by-dragging-arduino-101-app-inventor-98ab0b

chegewara commented 6 years ago

That heart rate monitor you have pasted here is working example, also you have BLE_notify example in arduino. Here you can find 16bit UUID that are assigned by bluetooth SIG: https://www.bluetooth.com/specifications/gatt/services https://www.bluetooth.com/specifications/gatt/characteristics https://www.bluetooth.com/specifications/gatt/descriptors

Those are standard UUIDs. If you want to build custom application then you should have to generate and use 128 bit UUID, although its not required. If we speak about app inventor, it does not matter it is communicate with arduino or esp32, ble is a standard and app inventor will works with both the same way, so you will create and build app exactly the same. Just part on arduino and esp32 will differ a little.

iotlearner0level commented 6 years ago

thank you very much. at least i can now start!