Im letzten Beitrag Drahtlose Datenübertragung: Python-Skript für Bluetooth-Kommunikation mit Mikrocontroller habe ich dir bereits ein Python-Skript gezeigt, wie man Daten vom Raspberry Pi an einen beliebigen Mikrocontroller senden kann. Hier soll es nun die andere Richtung gehen und die Daten sollen vom Mikrocontroller an einen Raspberry Pi gesendet werden.
Der Mikrocontroller in diesem Fall ist ein Arduino UNO R3 an welchem ein DHT11 Sensor angeschlossen ist. Der DHT11 Sensor liefert die Messdaten zur Temperatur sowie die rel. Luftfeuchtigkeit. Es bietet sich hier an, diese Daten im JSON Format zu senden.
Inhaltsverzeichnis
- Aufbau der Schaltung – DHT11 Sensor mit HC-06 Bluetoothmodul am Arduino UNO R3
- Aufbau der Programme auf dem Arduino & Raspberry Pi
- Schreiben des Programmes in der Arduino IDE
- Aufarbeiten der JSON-Daten via Python-Skript
- Fazit & Ausblick zu Bluetoothverbindung mit dem Arduino & Raspberry Pi
Aufbau der Schaltung – DHT11 Sensor mit HC-06 Bluetoothmodul am Arduino UNO R3
Bauen wir zunächst die kleine Schaltung auf und schließen einen DHT11 Sensor sowie das Bluetooth Modul HC-06 an den Arduino UNO R3 an.
Für den Aufbau der Schaltung benötigst du:
- einen Arduino UNO R3*,
- ein USB-Datenkabel*,
- einen DHT11 Sensor*,
- ein HC-06 Bluetooth Modul*,
- diverse Breadboardkabel*,
- ein 400 Pin Breadboard*
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Statt einem Arduino UNO R3 kannst du auch einen Arduino Nano V3 oder Arduino Leonardo, Arduino Mega 2560 R3 verwenden.
Den DHT11 Sensor bekommst du als losen Baustein wie du diesen in der Schaltung siehst und auch auf einer kleinen Platine mit nur 3 Kontakten. Bei den Modulen mit nur 3 Kontakten entfällt die Schaltung mit dem 4,7 kOhm Widerstand!
Aufbau der Programme auf dem Arduino & Raspberry Pi
Im nachfolgenden YouTube-Video erläutere ich dir wie die Programme funktionieren.
Schreiben des Programmes in der Arduino IDE
Einfaches senden einer festen Zeichenkette via Bluetooth vom Arduino an den Raspberry Pi
Als Erstes möchte ich dir gerne zeigen, wie du eine Zeichenkette vom Arduino UNO R3 via Bluetooth an den Raspberry Pi senden kannst. Wie erwähnt arbeitet das Bluetooth Modul HC-06 mit einer einfachen seriellen Schnittstelle und somit ist der Code von dem Arduino selber wieder recht einfach gehalten.
//Bibliothek zum erzeugen neuer serieller Schnittstellen //an digitalen Pins. #include <SoftwareSerial.h> //Bluetooth Modul HC-06 an den Pins verbunden //TXD > D11 //RXD > D10 SoftwareSerial BT(11,10); void setup() { //beginn der seriellen Kommunikation mit 9600 baud //dieser Wert muss mit dem auf dem Zielgerät übereinstimmen BT.begin(9600); } void loop() { //Senden von der Zeichenkette "Hallo Welt!" BT.write("Hallo Welt!"); //eine Pause von 2 Sekunden delay(2000); }
Wenn wir dieses Programm auf den Arduino übertragen haben, dann können wir zum Raspberry Pi wechseln und dort die Verbindung zum Arduino bzw. Bluetooth Modul HC-06 aufbauen.
Zunächst müssen wir die MAC-Adresse des Bluetooth Moduls herausfinden (soweit uns diese bereits nicht bekannt ist).
pi@raspberrypi:~/Python/BluetoothReceiveData $ bluetoothctl
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:AA:D5:1A Discovering: yes
[NEW] Device 7D:31:1B:0A:67:3B 7D-31-1B-0A-67-3B
[NEW] Device DE:28:81:28:4A:5C ID205L
[CHG] Device 20:15:12:15:21:33 RSSI: -46
[bluetooth]# info 20:15:12:15:21:33
Device 20:15:12:15:21:33 (public)
Name: HC-06
Alias: HC-06
Class: 0x00001f00
Paired: yes
Trusted: yes
Blocked: no
Connected: no
LegacyPairing: yes
UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb)
RSSI: -46
[bluetooth]# exit
In meinem Fall hat das Modul die MAC-Adresse 20:15:12:15:21:33.
Nun müssen wir zu diesem eine Verbindung aufbauen, das ist mit nur einer kleinen Befehlszeile möglich:
sudo rfcomm bind rfcomm0 20:15:12:15:21:33
Von nun an wird in die Datei /dev/rfcomm0 die Daten geschrieben, welche über Bluetooth empfangen wurden.
Mit dem Befehl cat können wir uns diese dann fortlaufend anzeigen lassen.
pi@raspberrypi:~/Python/BluetoothReceiveData $ cat /dev/rfcomm0
Hallo Welt!Hallo Welt!Hallo Welt!
Um die Verbindung zum Bluetooth Modul zu beenden, müssen wir den nachfolgenden Befehl eingeben, jedoch bedenke, dass dann auch alle Daten gelöscht werden, welche empfangen wurden!
sudo rfcomm unbind rfcomm0
Damit wir die Daten also weiterhin behalten müssen wir uns diese speichern, hier werde ich dir ein kleines Python-Skript anbieten, welches die Daten von der seriellen Schnittstelle liest und in eine Datei schreibt.
In meinem Arduino Programm sende ich die Daten alle 2 Sekunden daher werden auch leere Zeichen empfangen diese filtere ich heraus.
Zusätzlich schreibe ich diese Daten in eine Datei, welche als Dateinamen einen Zeitstempel trägt, dieses erleichtert das Ordnen der Daten welche empfangen wurden.
import serial import time appendTimestamp = True serialData = None try: while True: with serial.Serial('/dev/rfcomm0', timeout=1, baudrate=9600) as data: print("Verbunden mit ", data.name) print("Zum beenden Strg+C betaetigen!") while True: serialData = data.readline().decode('utf-8').strip() if len(serialData) > 0: if appendTimestamp : serialData = time.strftime('[%d.%m.%Y %H:%M:%S] ') + serialData print(serialData) filename = time.strftime('%d%m%Y') + data.name.replace("/","_") + ".txt" with open(filename, "a") as file: file.write(serialData) file.write("\r") except KeyboardInterrupt: exit() except IOError as ioEx: print("Unerwarteter Fehler aufgetreten") print(f"{ioEx=}, {type(ioEx)=}", ) exit()
Auf der Konsole starten wir das Skript mit „python testSerial.py“ es wird dann eine Verbindung aufgebaut und die Daten fortlaufend ausgegeben und parallel in die Datei geschrieben.
python testSerial.py
Verbunden mit /dev/rfcomm0
Zum beenden Strg+C betaetigen!
[28.11.2023 20:27:33] Hallo Welt!
[28.11.2023 20:27:35] Hallo Welt!
[28.11.2023 20:27:37] Hallo Welt!
[28.11.2023 20:27:39] Hallo Welt!
[28.11.2023 20:27:41] Hallo Welt!
[28.11.2023 20:27:43] Hallo Welt!
Übertragen von Sensordaten vom Arduino via Bluetooth an den Raspberry Pi
Nachdem wir eine feste Zeichenkette vom Arduino an den Raspberry Pi gesendet haben, wollen wir nun Sensordaten senden. In meinem Fall verwende ich wie eingangs gezeigt den DHT11 Sensor, dieser liefert die Temperatur sowie die relative Luftfeuchtigkeit.
Um die Sensordaten des DHT11 Sensors via Bluetooth zu übertragen, bietet es sich an diese im JSON-Format zu übertragen.
Was ist ein JSON-Format und warum sollte man dieses verwenden?
Das JSON-Format eignet sich besonders für die Datenübertragung von Sensordaten aufgrund seiner Leichtgewichtigkeit, menschenlesbaren Struktur und universellen Unterstützung in verschiedenen Programmiersprachen. Die klare Schlüssel-Wert-Paar-Struktur ermöglicht eine präzise Darstellung von Sensorwerten wie Temperatur und Luftfeuchtigkeit, während die einfache Handhabung in Python und anderen Sprachen die Integration und Verarbeitung der Daten erleichtert. Dies fördert eine effiziente und zuverlässige Kommunikation zwischen Geräten wie dem Arduino UNO R3 und dem Raspberry Pi.
Ein Beispiel mit JSON-Daten und Sensorwerte
Wie erwähnt ist ein Datensatz im JSON-Format von Menschen einfach lesbar und auch kannst du dieses theoretisch selber schreiben.
{ "temperatur": "34°C", "rel.Luftfeuchtigkeit": "30%" }
Es gibt auch die Möglichkeit Listen in JSON-Daten zu verpacken und so kannst du deine Daten zunächst aufzeichnen und dann in einem Rutsch an den Raspberry Pi versenden.
{ "liste": [ { "zeitstempel": 1700675735, "temperatur": "34°C", "rel.Luftfeuchtigkeit": "30%" }, { "zeitstempel": 1700675935, "temperatur": "32°C", "rel.Luftfeuchtigkeit": "31%" }, { "zeitstempel": 1700975735, "temperatur": "30°C", "rel.Luftfeuchtigkeit": "29%" } ] }
Wie du am Arduino Daten im JSON-Format speicherst, hatte ich dir bereits im veröffentlichten Beitrag JSON-Format zur Datenübertragung zwischen zwei Mikrocontroller gezeigt.
Hier möchte ich jedoch einfach nur die beiden Sensordaten in einen String speichern und dann absenden.
//Bibliothek zum auslesen des DHT11 Sensors #include <DHTStable.h> //Bibliothek zum erzeugen neuer serieller Schnittstellen //an digitalen Pins. #include <SoftwareSerial.h> //Bluetooth Modul HC-06 an den Pins verbunden //TXD > D11 //RXD > D10 SoftwareSerial BT(11,10); //Initialisieren eines Objektes vom Typ DHTStable DHTStable DHT; //Der Sensor ist am digitalen Pin D5 angeschlossen #define DHT11_PIN 5 void setup() { Serial.begin(9600); //beginn der seriellen Kommunikation mit 9600 baud //dieser Wert muss mit dem auf dem Zielgerät übereinstimmen BT.begin(9600); } void loop() { //Anfordern der Sensorwerte, //zusätzlich gibt diese Funktion einen Status zurück //Wenn dieser Status gleich DHTLIB_OK ist, dann sollen //die Werte ausgelesen und abgesendet werden. int check = DHT.read11(DHT11_PIN); if (check == DHTLIB_OK){ //Auslesen der Temperatur und kürzen auf eine Stelle nach dem Komma String temperatur = String(DHT.getTemperature(), 1); //Auslesen der relativen Luftfeuchtigkeit und kürzen auf eine Stelle nach dem Komma String relLuftfeuchtigkeit = String(DHT.getHumidity(), 1); //Aufbau der JSON Daten String jsonData = "{\"temperatur\": \""+temperatur+"°C\", \"rel.Luftfeuchtigkeit\": \""+relLuftfeuchtigkeit+"%\"}"; //ausgeben der Daten auf der seriellen Schnittstelle des Arduino Serial.println(jsonData); //senden der Daten via Bluetooth BT.write(jsonData.c_str()); //Der DHT11 Sensor liefert alle 1,5 Sekunden einen neuen Messwert, daher ist eine Pause //von 2 Sekunden ratsam. delay(2000); } else { //Im Fehlerfall soll eine Nachricht abgesendet werden. String msg = "Fehler bei der Kommunikation mit dem DHT11 Sensor!"; Serial.println(msg); BT.write(msg.c_str()); } }
Wenn wir das kleine Programm auf dem Arduino ausführen, dann wird auf der seriellen Schnittstelle die Daten des DHT11 Sensors im JSON-Format ausgegeben.
Das Python-Skript hat einen kleinen „Schalter“ für den Zeitstempel, ich habe diesen deaktiviert so das kein zusätzlicher Zeitstempel gespeichert wird. Dieses entfernen des Zeitstempels erleichtert uns das spätere parsen der Textdatei!
pi@raspberrypi:~/Python/BluetoothReceiveData $ python testSerial.py
Verbunden mit /dev/rfcomm0
Zum beenden Strg+C betaetigen!
{"temperatur": "20.0°C", "rel.Luftfeuchtigkeit": "41.0%"}
{"temperatur": "20.0°C", "rel.Luftfeuchtigkeit": "42.0%"}
{"temperatur": "19.0°C", "rel.Luftfeuchtigkeit": "42.0%"}
{"temperatur": "20.0°C", "rel.Luftfeuchtigkeit": "45.0%"}
{"temperatur": "20.0°C", "rel.Luftfeuchtigkeit": "42.0%"}
{"temperatur": "20.0°C", "rel.Luftfeuchtigkeit": "43.0%"}
{"temperatur": "19.0°C", "rel.Luftfeuchtigkeit": "42.0%"}
{"temperatur": "19.0°C", "rel.Luftfeuchtigkeit": "43.0%"}
Aufarbeiten der JSON-Daten via Python-Skript
Die Daten haben wir nun auf dem Raspberry Pi empfangen und in einer Textdatei gespeichert. Und können diese Zeileweise parsen und als CSV-Datei umwandeln.
import json import csv # Pfad zur JSON-Datei json_file_path = '29112023_dev_rfcomm0.txt' # Lese JSON-Daten aus der Datei with open(json_file_path, 'r') as json_file: # Lade JSON-Daten json_data_list = [json.loads(line) for line in json_file] # Pfad zur CSV-Datei csv_file_path = 'output.csv' # Oeffne CSV-Datei im Schreibmodus with open(csv_file_path, 'w', newline='') as csvfile: # CSV-Schreibobjekt erstellen csv_writer = csv.writer(csvfile) # Schreibe die Headerzeile header = ["temperatur", "rel.Luftfeuchtigkeit"] csv_writer.writerow(header) # Schreibe die Daten for data in json_data_list: row = [data["temperatur"], data["rel.Luftfeuchtigkeit"]] csv_writer.writerow(row) print(f'Die JSON-Daten aus der Datei {json_file_path} wurden in die CSV-Datei {csv_file_path} umgewandelt.')
Im Skript wird der Dateiname angegeben und danach auf der Konsole mit dem Befehl „python convertJsonCSV.py“ gestartet.
pi@raspberrypi:~/Python/BluetoothReceiveData $ python convertJsonCSV.py
Die JSON-Daten aus der Datei 29112023_dev_rfcomm0.txt wurden in die CSV-Datei output.csv umgewandelt.
Die CSV-Datei mit den Daten wird parallel zum Skript abgelegt und kann nun in zbsp. Microsoft Excel geladen und visualisiert werden.
Fazit & Ausblick zu Bluetoothverbindung mit dem Arduino & Raspberry Pi
Mit diesem Beitrag habe ich dir nun gezeigt wie du Daten vom Arduino an den Raspberry Pi senden kannst. Im nächsten Beitrag möchte ich dir dann zeigen wie du dieses mit dem Raspberry Pi Pico W machen kannst. Dieser kleine Mikrocontroller verfügt über WiFi und seit dem Firmwareupdate auch über Bluetooth.