![](/media/cache/profiles/eric_duckman_mpreg_by_mpregediter-db5d0t8.png.50x50_q85.png)
Template for the workshop 'Ontwerp je eigen Bluetooth LE device' for the NIOC Congress 2018
Ontwikkel je eigen Bluetooth LE device
Welkom bij de workshop, tijdens deze workshop ga je aan de gang met het ontwikkelen van een Bluetooth LE device met behulp van MBED. Tijdens de workshop heb je het volgende nodig:
- Het bluetooth LE ontwikkel bord, dat door ons beschikbaar is gesteld
- Een laptop met internet toegang. Voor het ontwikkelen van de software gebruik je de online mbed ontwikkel omgeving
- Een redelijke kennis van C++ programmeren, de software voor het device wordt ontwikkeld met C++.
De handleiding en presentatie zijn hier te vinden:
Presentatie
Handleiding
Opzetten van de ontwikkel omgeving
Stap 1: Registreer je op de MBED website.
Ga naar de MBED OS website en registreer je op de website om toegang te krijgen tot de online IDE:
os.mbed.com
Stap 2: Voeg het NRF52-DK ontwikkelbord toe aan je ontwikkelomgeving.
Het ontwikkelbord wat beschikbaar is gesteld is het NRF52-DK ontwikkelbord, informatie over dit bord is te vinden via de volgende pagina:
https://os.mbed.com/platforms/Nordic-nRF52-DK/
Bekijk deze pagina, op deze pagina is ook een knop aanwezig om het platform toe te voegen aan je online ontwikkelomgeving. Gebruik de knop om het platform toe te voegen aan de compiler.
Selecteer het NRF52-Dk platform in de IDE rechtsboven in het browser scherm.
Stap 3: Installeer de NRF-Connect app op je smartphone.
Installeer de NRF-Connect app van Nordic op je smartphone. Deze app gaan we gebruiken om via bluetooth verbinding te maken met het ontwikkelbord. Deze app is beschikbaar voor zowel Android als IOS.
De ontwikkelomgeving is nu juist geconfigureerd om te gaan beginnen.
Het ontwikkelen van je eigen Bluetooth LE device
In een aantal stappen gaan we nu een eigen Bluetooth LE device ontwikkelen die aangestuurd kan worden m.b.v. je smartphone met de Nordic NRFConnect LE app.
Stap 1: Opzetten van een basis applicatie.
We beginnen vanaf een basis applicatie die reeds voor geprogrammeerd is. Hiervoor moet je een bestaand project importeren / clonen in de online ontwikkel omgeving. Hiervoor gebruiken we je import van de MBED omgeving:
- Klik op de knop import
- Selecteer het tabblad ‘Programs’
- Gebruik de link om een programma te importeren vanaf een URL
Importeer het programma vanaf de volgende url: https://os.mbed.com/users/wkleunen/code/saxion_nioc/
Stap 2: Compileer het programma en laad het op het ontwikkelbord.
Nadat je de basis applicatie hebt geimporteerd kun je hem compileren m.b.v. de ‘Compile’ button. Druk op compile, het project wordt nu gecompileerd op de server van mbed. Als de compilatie klaar en succesvol is, wordt de gecompileerde firmware automatisch gedownload in de vorm van een ‘hex’ bestand.
Sluit het ontwikkelbord aan op je laptop via de USB kabel. Na installatie van de noodzakelijke drivers, verschijnt er een nieuwe drive ‘JLINK’. Sleep het ‘hex’ bestand naar de JLINK drive om de applicatie te schrijven naar het ontwikkelbord. De applicatie wordt op het bord geprogrammeerd en wordt nu gestart.
Start nu de NRF-Connect app op je smartphone. Zodra je op ‘Scan’ drukt wordt het bord gedetecteerd met de naam ‘Nioc_BLE’. Aangezien er meer mogelijk meerdere borden worden gedetecteerd met dezelfde naam weet je dus niet of dit specifiek jouw bord is. Ga daarvoor verder naar de volgende stap.
Stap 3: Aanpassen van de device naam.
Pak de code van het basis programma er bij en pas nu de naam van het device aan in de code, succes!
Na het aanpassen van de code kun je het programma opnieuw compileren en op het device programmeren door de hex file naar de USB drive te slepen. Je hoeft niet eerst de oude applicatie weg te halen, de nieuwe hex file wordt over de oude applicatie heen gezet en automatisch gestart.
Stap 4: Stuur de LEDS aan m.b.v. een Gatt Characteristic.
In de voorbeeld code is reeds een Gatt Characteristic gedefinieerd genaamd ‘Alert Level’. M.b.v. de NRF Connect app kan na het connecten met het BLE device een waarde (byte) naar dit characteristic worden geschreven.
Connect met je BLE device m.b.v. NRF Connect en stuur een waarde naar de ‘Alert Level’ characteristic:
- Druk op ‘Write value’ knop (pijltje omhoog) in NRF connect om een waarde te gaan schrijven. (N.B. Als je de knop niet ziet, dan ben je niet verbonden met het BLE bord, druk op connect om te verbinden).
- Kies een waarde / alert level die naar de characteristic moet worden gestuurd
- Druk op send om de waarde naar het device te schrijven
In de code wordt de callback functie ‘onDataWrittenCallback’ aangeroepen als een waarde geschreven wordt naar de characteristic. Pas deze functie aan, dat de waarde gebruikt wordt om de LEDS op het bord aan te sturen. Er zijn 4 leds op het bord die aangestuurd kunnen worden, m.b.v. de ‘EnableLed’ en ‘DisableLed’ functies kunnen deze aan en uit worden gezet.
Stap 5: Pas de LEDS aan m.b.v. de knoppen op het bord.
Op het bord zijn ook 4 knoppen aanwezig. In de code is er reeds voor gezorgd dat op het moment dat één van de knoppen wordt ingedrukt, de functie ‘ButtonPressed’ wordt aangeroepen.
Pas de code aan dat de LEDs worden aangepast zodra op één van de knoppen wordt gedrukt. Maak het ook zo dat de ‘alert_characteristic’ wordt aangepast zodra één van de knoppen wordt ingedrukt. De waarde van de characteristic kan als volgt worden aangepast:
Code voor aanpassen van waarde van characteristic in mbed
uint8_t alert_value = 3; BLE::Instance().gattServer().write(alert_characteristic.getValueHandle(), &alert_value, sizeof(uint8_t));
Aangezien je de waarde van de ‘alert_characteristic’ aanpast, is het mogelijk om de nieuwe waarde via Bluetooth draadloos op te vragen aan het device.
- Connect weer met je device en druk op de ‘lezen’ knop (1) van de ‘Alert Level’ characteristic. De huidige waarde van het characteristic wordt nu getoond (2).
- Het is ook mogelijk om notifications aan te zetten, doe dit met behulp van de notifications knop (3). Als notifications aan staan is het niet meer nodig om de waarde van de characteristic handmatig op te vragen. Zodra de waarde van de characteristic wordt aangepast (door op een knop te drukken), wordt de nieuwe waarde gepushed naar je smartphone en wordt de waarde getoond (2).
Nawoord
Bedankt voor het bijwonen van de workshop ‘Ontwikkel je eigen Bluetooth LE device’. Wij zijn erg enthousiast over het MBED platform en de beschikbare hardware. Je hebt nu ervaren hoe eenvoudig het is om aan de gang te gaan met embedded software ontwikkeling onderwijs door gebruik te maken van het MBED online platform. Daarnaast biedt Bluetooth LE veel interessante mogelijkheden om (Embedded) software onderwerpen te behandelen en wordt het in de praktijk steeds meer gebruikt.
Naast het online platform biedt MBED de mogelijkheid om offline de tools te gebruiken. Dit is eenvoudig te installeren m.b.v. een installer: https://os.mbed.com/docs/latest/tools/installing-with-the-windows-installer.html
Hoewel dit prettig is als het druk is op de MBED cloud server, is onze ervaring dat studenten toch eigenlijk altijd met de online omgeving blijven werken. Binnen ons onderwijs wordt het MBED platform gebruikt voor microcontroller programmeren en draadloze communicatie.
Naast het ontwikkelen van een Bluetooth LE device met MBED is het ook mogelijk om Bluetooth LE te gebruiken voor Android en IOS software ontwikkeling en web software door de Bluetooth LE stack op een Raspberry PI te combineren met web m.b.v. NodeJS door gebruik te maken van de Noble library: https://github.com/sandeepmistry/noble
Wij zijn zeer geinteresseerd in de mogelijkheden die jullie zien voor MBED en BLE in het onderwijs,
Wouter van Kleunen
Wilco Bonestroo
HBO-ICT Saxion
Diff: main.cpp
- Revision:
- 1:33f443eaa422
- Parent:
- 0:23c0b182cbe6
--- a/main.cpp Mon Jan 08 12:32:21 2018 +0000 +++ b/main.cpp Fri Feb 02 14:55:38 2018 +0000 @@ -30,22 +30,22 @@ // TODO .. Change the name of this device const static char DEVICE_NAME[] = "Nioc_BLE"; -// The UUID (Unique Universal Identifier) of our Led service and Led characteristic -enum { LED_SERVICE_UUID = 0xA000 }; -enum { LED_VALUE_UUID = 0xA001 }; +// The UUID (Unique Universal Identifier) of our Alert service and Alert characteristic +enum { ALERT_SERVICE_UUID = 0x1811 }; +enum { ALERT_VALUE_UUID = 0x2A06 }; -// Definition our led characteristic -ReadWriteGattCharacteristic<uint8_t> led_characteristic(LED_VALUE_UUID, NULL, +// Definition our alert characteristic +ReadWriteGattCharacteristic<uint8_t> alert_characteristic(ALERT_VALUE_UUID, NULL, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); // This function is called when data is written to a characteristic void onDataWrittenCallback(const GattWriteCallbackParams *params) { - // Check if it really was the led characteristic that was written by checking the handle - if(params->handle == led_characteristic.getValueHandle() && params->len == sizeof(uint8_t)) + // Check if it really was the alert characteristic that was written by checking the handle + if(params->handle == alert_characteristic.getValueHandle() && params->len == sizeof(uint8_t)) { - // We got a new value for the led characteristic, do something useful with this - uint8_t led_value = *(uint8_t const *)(params->data); + // We got a new value for the alert characteristic, do something useful with this + uint8_t value = *(uint8_t const *)(params->data); // TODO: .. do something useful with this value } } @@ -66,15 +66,15 @@ BLE &ble = BLE::Instance(); - // Initialize the default of our led characteristic - uint8_t init_led_value = 0; - BLE::Instance().gattServer().write(led_characteristic.getValueHandle(), &init_led_value, sizeof(uint8_t)); + // Initialize the default of our alert characteristic + uint8_t init_alert_value = 0; + BLE::Instance().gattServer().write(alert_characteristic.getValueHandle(), &init_alert_value, sizeof(uint8_t)); // First create our GATT Service (basicly a list of characteristics ) enum { TOTAL_SERVICE_CHARACTERTERISTICS = 1 }; - GattCharacteristic *characteristics_table[TOTAL_SERVICE_CHARACTERTERISTICS] = { &led_characteristic }; - GattService led_service(LED_SERVICE_UUID, characteristics_table, TOTAL_SERVICE_CHARACTERTERISTICS); - ble.gattServer().addService(led_service); + GattCharacteristic *characteristics_table[TOTAL_SERVICE_CHARACTERTERISTICS] = { &alert_characteristic }; + GattService alert_service(ALERT_SERVICE_UUID, characteristics_table, TOTAL_SERVICE_CHARACTERTERISTICS); + ble.gattServer().addService(alert_service); // Setup the BLE callbacks ble.gap().onDisconnection(disconnectionCallback); @@ -83,7 +83,7 @@ // Configure the advertisement, we add the name of the device to the advertisement and some service data ble.gap().setDeviceName((uint8_t const *)DEVICE_NAME); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (uint8_t const *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (uint8_t const *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1); uint8_t service_data[] = { 0x11, 0x18, 0x00 }; ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, service_data, sizeof(service_data));