Eerste proefopstelling: Arduino Nano 33 BLE

In dit hoofdstuk bespreken we de opstelling waarbij we de Arduino Nano in combinatie met de HC-05 Bluetooth-module hebben vervangen door de Arduino Nano 33 BLE, met Bluetooth ingebouwd. De reden voor deze keuze was omdat de HC-05-module verouderd is en geen gebruik kan maken van de vernieuwingen van de afgelopen 13 jaar, en zodat we een compactere opstelling met minder componenten kunnen hebbe,. We zullen ook de methode om onze data te verzamelen beschrijven die we hebben bereikt met deze opstelling.

Bluetooth Low Energy

Van in het begin werd er al gekozen om met Bluetooth te werken. Met de nieuwe Arduino Nano 33 BLE kunnen we zoals het in de naam staat, gebruik maken van Bluetooth Low Energy (BLE).

Bluetooth Low Energy werd ontworpen om heel lang te draaien op knoopcelbatterijen. Terwijl dat standaard Bluetooth gebaseerd is op de asynchrone seriële UART, zal een apparaat met BLE (Peripheral device) zich volgens het GATT (Generic Attribute Profile) protocol gedragen als een prikbord. Hiermee kunnen andere BLE-apparaten (Central devices) verbinding maken en zien wat gepost wordt. Ook kan een central device informatie vragen waardoor de peripheral device zal antwoorden zoals in een client-server model. We kunnen hier spreken van een GATT server en een GATT client.

Image

Schema werking BLE

Een BLE-apparaat zal zichzelf toonbaar maken door te adverteren met General Advertising Profile (GAP), deze zal services aanbieden, waaraan een verzameling van characteristics aan hangen. Iedere service moet voorzien worden van een UUID We kunnen onze eigen service aanmaken met een 128 bit UUID of gebruikmaken van reeds bestaande services met een 16-bit UUID. Hiervoor bestaat er een officiële Assigned Numbersopen in new window lijst met UUID's die voorbehouden zijn voor een aantal veelgebruikte toepassingen en fabrikanten, met als voordeel dat de kortere UUID's aan bandbreedte besparen en herkend kunnen worden door andere apparaten. Voor dit project met luchtdruk is het dus handig om onze service aan te duiden met de UUID van 0x2871, dit duidt aan dat het gaat over druk in millimeter kwik (mmHg). Voor de characteristic kunnen we een eigen UUID gebruiken.

Verder bestaat het GATT protocol voor BLE uit Read, Write, Indicate en Notify. Bij Read zal een central device (client) vragen om de waarde van een specifieke characteristic, bijvoorbeeld een het versienummer. Bij Write zal een central device zelf een waarde sturen naar de peripheral device, bijvoorbeeld om een LED te togglen. Bij indicate en Notify zal de peripheral device op vraag van één of meerdere central devices continu data uitsturen van een characteristic zoals bij het publish-subscribe model van MQTT, totdat alle vragende partijen de vraag beëindigen. (ArduinoBLE - Arduino Reference. (z.d.).open in new window). Waarbij het enige verschil tussen Notify en Indicate is dat een indication samen gaat met een acknowledgement en een notification niet. (What is the difference between an Indication and a Notification? (z.d.). Laird Connectivity.open in new window

LightBlue-app met CloudConnect

Met behulp van de LightBlue-app was het mogelijk om een succesvolle BLE-verbinding op te zetten en gegevens van de Arduino Nano naar een mobiele telefoon te verzenden. De LightBlue-app biedt ook de mogelijkheid om gegevens naar externe services te verzenden naar Amazon AWS of Adafruit IO, om realtime grafieken van onze gegevens te verkrijgen en mogelijkheid om data op te slaan. Een nadeel is dat de app geen float-waarden kan verzenden. Om dit probleem te omzeilen hebben we dus besloten om onze gegevens te vermenigvuldigen met 100 voordat we ze verzenden en later weer te delen door 100 bij het verwerken van de gegevens.

Voor deze proefopstelling hebben we gebruikgemaakt van Adafruit IO, . Het enige nadeel was dat de gratis versie van Adafruit IO beperkt was tot het verzenden van maximaal 30 datapunten per minuut, wat resulteerde in een dode tijd van 2 seconden tussen de datapunten. Hoewel de LightBlue-app beschikbaar is op zowel Android- als iOS-apparaten, is de CloudConnect-functionaliteit alleen beschikbaar op iOS.

Adafruit IO

In deze opstelling hebben we gebruik gemaakt van Adafruit IO omdat het zeer eenvoudig was om gegevens naar dit platform te verzenden, op te slaan en te exporteren. Adafruit IO is een cloudgebaseerd platform dat speciaal is ontworpen voor het verzamelen en visualiseren van IoT-gegevens. Het biedt een eenvoudige interface waarmee gebruikers gegevenspunten kunnen verzenden, ontvangen en beheren.

Om Adafruit IO te gebruiken, moeten we eerst een account aanmaken op het Adafruit IO-platform. Vervolgens genereer je een AIO key, een speciaal token waarmee niemand anders aan jouw data zal kunnen komen. Daarna geef je je username en token in op de LightBlue-app en geef je een naam op van een feed die al bestaat of automatisch aangemaakt zal worden. Daarna kan je de gegevens zien binnenstromen op Adafruit IO en is er een download knop voorzien om de gegevens in een CSV-bestand te krijgen.

Hoewel de feed mooi voor ons gebruikscenario voldoende is, is het ook mogelijk om onze gegevens in een dashboard te steken. In dat dashboard kan je verschillende blokken toevoegen, zoals grafieken, meters en schakelaars, om de gegevens op een gebruiksvriendelijke manier weer te geven.

Een voordeel van Adafruit IO is dat we gebruik kunnen maken van een HTTP API en MQTT om naar onze gegevens luisteren of nieuwe gegevens toe te voegen.

Een nadeel was dan wel weer dat de gratis versie van Adafruit IO beperkt is tot het verzenden van maximaal 30 datapunten per minuut, wat resulteerde in een dode tijd van 2 seconden tussen de datapunten. En hoewel de LightBlue-app beschikbaar is op zowel Android- als iOS-apparaten, is de CloudConnect-functionaliteit alleen beschikbaar op iOS.

Metingen

Eerste meting

Meting 2

Meting 3

Meting 4

Software Arduino Nano BLE

Hieronder vind je een fragment van de code die ervoor zorgt dat we verbinding kunnen maken met BLE. De code om sensordata binnen te lezen kan je terugvinden op github. De code om sensorwaarden af te meten is afkomstig van een Arduino forum postopen in new window.

#include <ArduinoBLE.h>

BLEService pressureService("2781"); // BLE Pressure Service

// BLE Pressure Characteristic - custom 128-bit UUID, read and writable by central
BLEIntCharacteristic pressurizer("2A75", BLERead | BLENotify); // send data as integer
// BLEFloatCharacteristic pressurizer("2A57", BLERead | BLENotify); // send data as float !!! does not work with LightBlue app
// BLEStringCharacteristic pressurizer("2A57", BLERead | BLENotify, 6); // send data as a string

void setup()
{

  if (!BLE.begin()) {
    Serial.println("starting Bluetooth® Low Energy failed!");
  }

  // set advertised local name and service UUID:
  BLE.setLocalName("Biosensor™");
  BLE.setAdvertisedService(pressureService);

  // add the characteristic to the service
  pressureService.addCharacteristic(pressurizer);

  // add service
  BLE.addService(pressureService);

  // set the initial value for the characteristic:
  pressurizer.writeValue(0);

  // start advertising
  BLE.advertise();

  Serial.println("BLE Pressure Peripheral");
  Serial.println(BLE.address());
}

void loop()
{
  // listen for BLE peripherals to connect:
  BLEDevice central = BLE.central();

  // if a central is connected to peripheral:
  if (central) {
    Serial.print("Connected to central: ");
    // print the central's MAC address:
    Serial.println(central.address());

    // while the central is still connected to peripheral:
    while (central.connected()) {

      // Code voor het meten en verzenden van de gegevens via BLE

    pressurizer.writeValue(int(pressMmhg*100)); // Stuur data via BLE  
    // pressurizer.writeValue(String(pressMmhg, 2)); // Stuur een string door via BLE
    }

    // when the central disconnects, print it out:
    Serial.print(F("Disconnected from central: "));
    Serial.println(central.address());
  }
  else {
    // Code voor het meten en verzenden van de gegevens zonder een actieve BLE-verbinding
  }
}

Beperkingen

Zoals eerder vermeld heeft de opstelling een aantal beperkingen. Ten eerste kan de LightBlue-app geen float-waarden verzenden, waardoor we onze gegevens moeten vermenigvuldigen met 100 voordat we ze verzenden. Op Adafruit IO komt de data dus maal 100 binnen, maar dit kunnen we achteraf wegwerken in excel of als we data van Adafruit halen via de API. Daarnaast heeft Adafruit IO in de gratis versie een beperking van 30 datapunten per minuut, waardoor er een dode tijd van 2 seconden tussen de datapunten ontstaat. Als laatste is de CloudConnect-feature van de LightBlue-app alleen beschikbaar op iOS-apparaten en niet op Android. Hierdoor werd het duidelijk dat de huidige opstelling extreem gelimiteerd was in hoe we data konden verzamelen.

Daarom werd er even gekeken naar Android Studio om een app te maken voor Android en voor iOS met Xcode. Maar ook hier zijn er een aantal vereisten nodig. Hoewel je gemakkelijk aan de slag kan gaan om een simplele Android app te maken en te emuleren, wordt het vrijwel onmogelijk om een Android app te emuleren vanaf dat je gebruik wilt maken van Bluetooth. Om een app te ontwikkelen voor iOS, moet je eerst over een Apple computertoestel beschikken om met Xcode te kunnen programmeren.

Schema AIO

Dit leidde ertoe om de Arduino Nano 33 BLE nogmaals te vervangen door een ESP32. Door met deze microcontroller met wifi-capaciteiten én Bluetooth te werken kunnen we de Lightblue-app omzeilen en rechtstreeks data te sturen via MQTT, zonder dat de GSM als tussenpersoon moet dienen.

Schema ESP