Bluetooth Communicatie

In voorgaande knutselaerijen werden universele HF modules gebruikt voor de afstandsbediening. Met de nRF-module is een half-duplex verbinding mogelijk, maar de meest simpele 433MHz module liet slechts dataverkeer in één richting toe. Op deze site kwam ik de app ArduinoBlue tegen als afstandsbesturing voor het fischertechnik-autootje. Zou Bluetooth-besturing met een joystick shield uit een van de vorige 'knutselaerijen' ook mogelijk zijn?

Het werd bij elkaar wel veel informatie voor één 'knutselaerij', daarom heb ik het onderwerp in tweeën geknipt. Laten we eerst een kijken naar hoe je überhaupt een full-duplex verbinding tussen twee Bluetooth modules tot stand brengt.

Video : toestemming voor cookies nodig
Instellingen

Bluetooth modules

Ik onderzocht:

  • HC-05 Bluetooth V2.1 'Classic Bluetooth' module [datasheet]
  • AT-09 Bluetooth V4.0 BLE module (Chinese kloon, compatible met HM-10) [datasheet]
  • HM-10 Bluetooth V4.0 BLE  module [datasheet]
  • HM-19 Bluetooth V5.0 BLE module [datasheet]

Bij het testen van de modules met de handige apps BlueTerm (Android) or BluTerm (iOS), kwam ik er al snel achter dat de HC-05 niet wordt herkend door Apple apparaten met iOS. Dit komt door Apple's eigen MFi Licensing Program waarbinnen 'Classic Bluetooth' zoals de HC-05 niet wordt ondersteund. Dual-mode Bluetooth modules die zowel de klassieke Bluetooth als BLE (Bluetooth Low Energy, vanaf 2009 en Bluetooth v4.0) ondersteunen kunnen met een Apple apparaat dus alleen over BLE worden gebruikt.

De opbouw van deze modules is telkens hetzelfde. De werkelijke Bluetooth module is een soort postzegel-pcb dat op een iets grotere print is gesoldeerd waarop de zes aansluitpinnen zitten waarmee de module kan worden aangesloten. Op deze onderliggende print is bij de onderzochte modellen een spanningsregulator opgenomen waardoor de aangeboden voedingsspanning doorgaans tussen de 3.3 tot 6 volt mag liggen. Let echter op: de HM-19 module mag volgens de datasheet slechts op 3.3 volt gevoed worden. Check dus altijd eerst even de datasheet en gebruik als Vcc voor de module óf de 5v, óf de 3.3v pin van de Arduino. Even configureren op 5 volt kan doorgaans geen kwaad, maar voor langduriger bedrijf zou je veiligheidshalve beter 3.3 volt kunnen aanhouden.

IMG_0025_2
IMG_9759

Hoewel dus een z.g. voltage-regulator voor de voedingsspanning is opgenomen, wordt als maximaal ingangssignaal voor de TX-ingang wél vaak slechts 3.3 volt opgegeven. De modules werken  proefondervindelijk echter uitstekend met ingangsniveau's van 5 volt.

Toch is het verstandig (voor Arduino boards die zelf op 5 volt werken, zoals de Uno) een eenvoudige z.g. level-shifter voor de TX ingang van de module te maken. Twee weerstandjes volstaan: bied het signaal aan via een weerstand van 1kΩ en hang de RX ingang van de module via een weerstand van 2k2Ω aan de GND pin van het voetje. Op die manier wordt een spanningsdeler gemaakt waardoor het ingangssignaal van de module netjes rond de 3.3 volt komt te liggen en de module beveiligd is tegen een te hoog ingangssignaal.

Verbinden met een 'Peripheral' module

Tijdens configuratie en gebruik van de Bluetooth module kunnen de seriële TX en RX van de module kan op de D0 en D1 van de Arduino worden aangesloten (hardware serial). Maar doordat deze gedeeld worden met de USB-aansluiting van de Arduino, heeft dit echter het bezwaar dat de module elke keer moet worden verwijderd voordat een Sketch kan worden geüpload. Deze RX/TX pinnen kunnen namelijk niet gedeeld worden en zijn maar voor één apparaat tegelijk beschikbaar.

Door in de Sketch gebruik te maken van SoftwareSerial, die serieel verkeer over twee vrij te kiezen pinnen van de Arduino mogelijk maakt, kan de module echter simpelweg in zes naastgelegen in-/uitgangen worden gestoken. Door de Vcc en GND pinnen respectievelijk HIGH en LOW te maken wordt ook al direct 5V voedingsspanning aangeboden. De hardware serial blijft hierbij dan vrij voor de usb verbinding.

Ik maakte en gebruikte de Sketch hiernaast om met apps als BlueTerm (Android) or BluTerm (iOS) een verbinding op te zetten met de Arduino met Bluetooth module. Dit ging probleemloos met de HM-10 module. Met de fabrieksinstellingen is deze module al in 'Peripheral'-role actief en hij kon daardoor direct door de betreffende apps worden herkend.

Sketch voor configuratie

De Sketch gebruikt SoftwareSerial zodat de hardware serial vrijblijft en de Bluetooth module in één keer op zes naastgelegen pinnen van de Arduino kan worden aangesloten.

// whizzbizz.com - Arnoud van Delden, 1st february 2021
//
// Configures a BT module connected to pins 8~12 (with optional hardware level-shifter in socket)
// For HC-05 press small button on pcb on power up, HM-10 and HM19 should automatically enter AT-mode
//
#include "SoftwareSerial.h"

// Outcomment line below for HM-10, HM-19 etc
//#define HIGHSPEED   // Most modules are only 9600, although you can reconfigure this
#define EN_PIN_HIGH   // You can use this for HC-05 so you don't have to hold the small button on power-up to get to AT-mode

#ifdef HIGHSPEED
#define Baud 38400   // Serial monitor
#define BTBaud 38400 // There is only one speed for configuring HC-05, and that is 38400.
#else
#define Baud 9600    // Serial monitor
#define BTBaud 9600  // HM-10, HM-19 etc
#endif

#define STATE 8
#define BLUETOOTH_RX 9  // Bluetooth RX -> Arduino D9
#define BLUETOOTH_TX 10 // Bluetooth TX -> Arduino D10
#define GND 11
#define Vcc 12
#define ENABLE 13

SoftwareSerial bluetooth(BLUETOOTH_TX, BLUETOOTH_RX);

void setup() {
  // Setup BT module
  pinMode(BLUETOOTH_TX, INPUT);
  pinMode(BLUETOOTH_RX, OUTPUT);  
  pinMode(STATE, INPUT);
  pinMode(GND, OUTPUT);
  pinMode(Vcc, OUTPUT);
  pinMode(ENABLE, OUTPUT);
  digitalWrite(GND, LOW);       // Ground for BLE Module
  digitalWrite(Vcc, HIGH);      // Vcc for BLE Module
#ifdef EN_PIN_HIGH  
  digitalWrite(ENABLE, HIGH);   // Used to force AT-mode for HC-05. More flexible is to press the button on the pcb
#endif

  // Start serial communications.
  // The baud rate must be the same for both the serial and the bluetooth.
  Serial.begin(Baud, SERIAL_8N1);
  bluetooth.begin(BTBaud);
  Serial.println("Bluetooth available.");
}

char c;

void loop() {
  // From BT-->Serial
  while (bluetooth.available()) {
    c = bluetooth.read();
    Serial.print(c); 
  }
  
  // From Serial-->BT
  if (Serial.available()) {
    while (Serial.available()) {
      c = Serial.read();
      Serial.print(c);
      bluetooth.write(c);
    }
  }
  delay(100);
}

Een module in 'Central'-role zetten

Als we twee Bluetooth modules met elkaar willen laten communiceren, mag er één in 'Peripheral'-modus blijven maar de andere zal in 'Central'-role moeten worden geconfigureerd om de rol over te nemen van de smartphone of het tablet met de app ArduinoBlue.

Met het tussen-voetje met ingebouwde level-shifter kan de module direct in de digitale in-/uitgangen D8 (State), D9 (RX), D10 (TX), D11 (GND), D12 (Vcc) en D13 (Enable) kan worden geprikt tbv SoftwareSerial. Zie de foto hierboven. Hierbij worden de uitgangen D11 en D12 op respectievelijk 0 (LOW) en 5 (HIGH) volt gezet zodat de module zijn voedingsspanning krijgt. De meeste modules gaan vanzelf al in AT-modus, maar op de HC-05 dient tijdens het aanleggen van de voedingsspanning een klein knopje te worden ingehouden. Ik kwam er echter achter dat deze modus ook geforceerd kan worden bereikt als de D13 (EN) pin hoog wordt gehouden. Hierdoor volstaat, met behulp van de Sketch hierboven, één systeem om alle besproken modules te configureren.

Behalve de HC-05, hebben alle modules standaard een default baud rate van 9600. Wie het nodig vindt, kan deze op 38400 (8N1) te zetten. Alle modules ondersteunen immers baudrates van 9600, 19200, 38400, 57600, 115200, 230400 en zelfs 460800. Van één module configureerde ik per ongeluk bij het controleren ervan het aantal stop bits op twee. Deze module was meteen niet meer bereikbaar via SoftwareSerial. Een bijkomend probleem was dat SoftwareSerial van de Arduino helaas géén configuratie van de parity- en/of stop-bits ondersteunt. Ik kon deze module gelukkig (gewoon interactief door AT-commando's via hardware serial) 'redden' met een Arduino Mega. Dit board heeft namelijk het enorme voordeel dat er wel vier hardwarematige seriële RX/TX interfaces op zitten waarvan ook de parity en het aantal stop bits kan worden aangepast.

Behalve het lagere stroomverbruik heeft Bluetooth BLE met de modernere HM-10 en HM-19 modules nog een ander voordeel. Zodra een dergelijke module in 'Central'-role wordt gezet, begint hij bij inschakelen automatisch te scannen en kan ook de eerste keer zelf de verbinding met de 'Peripheral'-module leggen. Bij de HC-05 moet (eenmalig) met de hand het Mac-adres van de 'Central' met het AT-commando AT+BIND worden opgegeven aan de 'Peripheral'. Hieronder heb ik, per module, wat nuttige AT-commando's ter configuratie opgenomen.

De HC-05 is een Bluetooth V2.1 module, die compatible zou zijn met de HM-15. De module is dus van de tweede generatie Bluetooth. Communicatie met smartphones en tablets, die tegenwoordig meestal pas vanaf Bluetooth BLE ondersteunen, is vaak niet mogelijk. Een app als ArduinoBlue valt er bijvoorbeeld niet mee te gebruiken omdat hij simpelweg de gehele module niet herkent. De app Bluetooth Electronics, alleen beschikbaar voor Android systemen, kan wel gebruikt worden.

Voor communicatie of besturing vanaf een zelfgemaakte fysieke afstandsbediening (zoals het joystick shield) vorm dit echter natuurlijk geen probleem, maar toekomstige, of alternatieve, besturing van een model of robot via een app op een (iOS-)smartphone is natuurlijk wel aantrekkelijk. Met Android zijn er mogelijkheden, maar onder iOS (gelimiteerd door het MFi Licensing Program) haast niet.

De HC-05 lijkt dus meer een module voor bijvoorbeeld het draadloos doorzenden van sensor-data, maar ik heb hem toch onderzocht omdat het traditionele master-slave model van het klassieke Bluetooth (dat in BLE is herontworpen tot een universeler, maar voor eenvoudige toepassingen snel overbodig complex, central-peripheral model) zich bij uitstek leent voor eenvoudige besturing waarbij met een tekstprotocol simpelweg slechts tekst en getallen hoeven te worden uitgewisseld.

Uit de datasheet van de HC-05 en het commando AT+UART? bleek dat de baudrate standaard op 38400 staat, en niet op 9600 zoals bij de meeste BLE modules. Voor het communiceren met de module met AT-commando's, moest de SoftwareSerial dus op 38400 staan. Ik heb (met het commando AT+UART=9600,0,0) dit geprobeerd aan te passen maar dit is niet gelukt. De module zegt hierna wel dat hij op 9600 baud opereert, maar blijft alleen onder 38400 bereikbaar. Vanuit de Arduino kan daarna wél 9600 baud worden gebruikt, maar de AT-commando interface (te bereiken door tijdens het aanleggen van de voedinsspanning op de module een heel klein knopje op de print in te houden) blijft rotsvast op 38400 staan.

Configuratie

Houd het kleine knopje op de print van de module ingedrukt tijdens het aanleggen van de voedingsspanning op de Arduino met de configuratie-Sketch. Het LEDje op de module knippert nu langzaam en de module accepteert AT-commando's. Stel de seriële monitor in op 38400 baud en NL/CR lijneindes. Van beide modules checkte en wijzigde ik de baudrate, respectievelijk met de commando's AT+UART? en AT+UART:38400,0,0.

Noteer of kopieer het MAC-adres van de slave-module dat met AT+ADDR? kan worden opgevraagd. Eventueel kan met met AT+ROLE? nog worden gecheckt of de role van deze module 0, oftewel 'Slave', is.

Nu mag andere module in de speciale voet, vergeet ook hier niet het kleine knopje in te houden bij het aanleggen van de voedingsspanning zodat de LED langzaam knippert en de module in AT-modus start. Wijzig desgewenst de baudrate met AT+UART:38400,0,0 en zet de role van deze module op 1, oftewel 'Master' met AT+ROLE1. Ik maakte ook een voetje waarbij de D13 EN (enable) HIGH kan worden gehouden. Hiermee wordt bij mijn HC-05 de AT-command modus geforceerd en hoeft het knopje niet te worden ingehouden bij het opstarten. Echter: om in normaal bedrijf te komen moet deze uitgang weer LOW gemaakt worden! Omdat de EN-ingang bij de meeste andere modules liefst HIGH (of gewoon niet aangesloten) is, is dit wel even iets om op te letten.

Nu kan de 'connection mode' van deze module op één fixed adres worden ingesteld met AT+CMODE=0, waarna tenslotte de automatische binding met het MAC-adres van de Slave-module worden gemaakt met AT+BIND=[MAC]. Let op: ik moest de dubbele punten die in het MAC-adres van de Slave-module terugkwamen vervangen door komma's bij dit commando. Het is allemaal even puzzelen, maar uiteindelijk lukte het.

Na plaatsen en reset van een module in elk van de twee Arduino's komt er nu automatisch een tekstverbinding tot stand tussen de twee seriele monitor schermen bij 38400 baud. Ik probeerde dit met twee verschillende computers: wat in de ene seriele monitor wordt ingetikt, verschijnt vrijwel direct in de andere.

De AT-09 Bluetooth V4.0 BLE module is eigenlijk de DX-BT05 en meldt zich als BT05. Bij nadere inspectie blijkt het een kloon van een kloon van de HM-10 module. In principe is de prijs daar dan ook naar. De werkelijke AT-commandoset was nogal een zoekplaatje. Sommige van de AT-commando's uit de originele HM-10 datasheets werkten (of de afsluitende '?' moest worden weggelaten voor hetzelfde resultaat) en het lukte uiteindelijk om een module automatisch in 'Central'-role te laten connecten met een module in 'Peripheral'-role. Echter, (tekst)dataverkeer in beide richtingen lukte niet. Heel even wel één richting op. Ook werd de module herkend door BLE scanners en kon ik er mee communiceren met bijvoorbeeld BlueTerm.

Configuratie

AT+BAUD? geeft 4. En dit zou volgens een gevonden document online, 9600 baud moeten zijn. Idealiter zou dit liever 2=38400 zijn. Maar na AT+BAUD2 blijkt de module (na veel uitproberen) alleen nog op 2400 baud op 'AT' te reageren. Andere commando's werken niet meer en dus werd de module daarmee onbruikbaar.

Ook het commando AT+RENEW om de module terug te brengen naar fabrieksinstellingen kon niet meer worden gegeven en omdat ik inmiddels twee modules op deze manier kennelijk onbruikbaar had gemaakt, besloot ik dan maar te proberen de firmware te updaten. Instructies (en succes-verhalen) om de module tot een HM-10 te maken vond ik op https://forum.arduino.cc/index.php?topic=393655.0

Dit leek op zich vrij goed te gaan, de gedownloade firmware zou direct de oorspronkelijke firmware van de HM-10 in de modules uploaden. Helaas waren de modules daarna onbruikbaar omdat ze op geen enkele baudrate meer op AT-commando's reageerden. Op diverse fora waren hier kennelijk meer mensen de dupe van geworden. Gelukkig is de aanschafprijs van deze kloon-modules niet hoog, dus ik besloot mijn verlies te nemen, bestelde enkele 'echte' HM-10 modules, en richtte me intussen op de HM-19 modules.

De eenvoudigste koppeling tussen twee modules kan tot stand worden gebracht als ze beiden tegelijk, ieder in een eigen Arduino, kunnen worden geactiveerd. Hiervoor kan eventueel twee keer bovenstaande Sketch worden gebruikt.

Bij gebruik van de speciale configuratievoet (waarbij de 'Enable' op D13 los mag blijven, of eventueel HIGH wordt gehouden) start de module in de AT-commando modus. Ik zette de baudrate van beide modules (met AT+BAUD5) op 38400 in plaats van de standaardsnelheid van 9600 baud, maar dit is in principe niet nodig. Bovendien is dit alléén de communicatiesnelheid tussen de module en de Arduino (niet de snelheid die de module op 2.4GHz Bluetooth tussen de modules hanteert).

De module in het joystick shield krijgt de 'Central' role met het commando AT+ROLE1 en de module in het te besturen model mag 'Peripheral' (AT+ROLE? geeft 'OK+Get:0') blijven. Noteer het MAC-adres van de 'Peripheral' (met AT+ADDR?). De 'Peripheral' module kan namelijk zometeen ook op MAC-adres worden gekoppeld als het lastig is deze tijdens de configuratie van de 'Central' gelijktijdig te activeren (en te laten 'discoveren') in een tweede Arduino.

De 'Peripheral'-module kan nu worden verwijderd. Nu pluggen we de module in die als Central'-role moet worden geconfigureerd. Koppelen op index na een 'discovery-scan' is het eenvoudigst, maar hiervoor is het wel nodig dat de andere module (b.v. in het uiteindelijk te besturen model) wordt ingeschakeld en detecteerbaar is. Ook is het nodig om met AT+IMME1 het automatisch scannen/detecteren van de toekomstige 'Central'-module even te onderdrukken. Maak deze module vervolgens de controller met AT+ROLE1. Nu kan de module als 'Central' gaan scannen of 'discoveren' met AT+DISC?. Er volgt een opsomming van de gevonden 'Peripheral'-modules waarbij de index bij de gewenste module van belang is. Stel dat de index van de gewenste module 2 is, dan kan hierna de koppeling tot stand worden gebracht met AT+CON2. Tenslotte dient de 'Central'-module weer in autodetect/-connect te worden teruggebracht met AT+IMME0 zodat dit pairen voortaan automatisch gaat.

Na een reset van beide modules (of het geven van AT+START aan de 'Central'), zou de verbinding automatisch tot stand moeten worden gebracht!

Dubbele besturing

De ArduinoBlue app op de smartphone koppelt, gewoon met de fabrieksinstellingen, eenvoudig met de Bluetooth module in het model. Door in de Sketch voor het bestuurbare model de ArduinoBlue functie-bibliotheek te gebruiken, kan deze dus gemakkelijk met ArduinoBlue vanaf een iOS of Android smartphone of tablet worden bestuurd.

Als een fysieke joystickbesturing (zoals bijvoorbeeld een joystick shield) hiermee ook compatible te maken is, die de rol van smartphone of tablet met ArduinoBlue kan overnemen, zijn deze besturingen uitwisselbaar en kan het model op twee compleet verschillende wijzen worden bestuurd.

De experimenten in die richting komen aan bod in deel twee van dit project.

IMG_0013