Hallo,
ich habe zwei Arduinos. Einer soll Zahlenwerte mit einem HC-05 auf den anderen senden, der mit einem HC-06 ausgestattet ist.
Ich habe beide Sketch soweit gebracht, dass der HC-05 einen Zahlenwert aus einem String in einen float umwandelt und dann ziffer für ziffer rüber schickt.
Der HC-06 empfängt diese dann auch.
Aber wenn ich das dann auf dem Ic2-Display(4x20) ausgeben will, wird immer nur die aktuell gesendete Ziffer angezeigt. Nicht die ganze Zahl.
Meine Frage ist jetzt, wie kann ich die ganze Zahl in einem Schlag schicken?
Hier ist der Sketch vom Slave:
#include <SoftwareSerial.h>
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
#define ledPin 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
char btData;
void setup()
{
Serial.begin(9600); //serieller Monitor wird gestartet, Baudrate auf 9600 festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
}
void loop()
{
if(Serial.available()) //wenn Daten empfangen werden...
{
btData = Serial.read(); //..sollen diese ausgelesen werden
Serial.print(btData); //Schreiben der Empfangenen Daten
digitalWrite(ledPin,HIGH); //Anzeige zur Verbindungsüberprüfung
lcd.setCursor(0, 0); //Den Cursor an den Anfang setzen
lcd.print(btData); //Das erste Zeichen auf dem Display anzeigen
delay(1000); //1 sec. warten
lcd.setCursor(1, 0); //Den Cursor auf das nächste Zeichen setzen
lcd.print(btData); //Die nächste Ziffer ins Display schreiben
delay(1000); //warten ... u.s.w
lcd.setCursor(2, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(3, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(4, 0);
lcd.print(btData);
delay(5000);
}
}
Das ist der Sketch vom Master:
String btData = ""; //Definition des Strings für die Messwerte
#include <SoftwareSerial.h>
#define ledPin 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
void setup()
{
btSerial.begin(9600);
while (!Serial)
{
; // Warte auf serielle Kommunikation
}
btSerial.println("bluetooth available");
}
void loop()
{
if (btSerial.available())
{
btData=12.2;
Serial.println(btData.toFloat());
btSerial.println(btData);
// clear the string for new input:
btData = "";
digitalWrite(ledPin, HIGH);
delay(1000);
}
}
Gruß
Adruinoboy
Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [*code] davor und [*/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.
Gruß Tommy
Bitte beherzige Tommy56.
Zu Deinem Code am Empfänger:
if(Serial.available()) //wenn Daten empfangen werden...
{
btData = Serial.read(); //..sollen diese ausgelesen werden
Serial.print(btData); //Schreiben der Empfangenen Daten
digitalWrite(ledPin,HIGH); //Anzeige zur Verbindungsüberprüfung
lcd.setCursor(0, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(1, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(2, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(3, 0);
lcd.print(btData);
delay(1000);
lcd.setCursor(4, 0);
lcd.print(btData);
delay(5000);
}
Wenn Du Deinen Code mit dem kommentieren würdest, was Du erwartest, dann wäre Dir geholfen.
Tipp: Du liest ein Zeichen ein, gibst das aus, wartest eine Sekunde, gibst das erneut aus, wartest eine Sekunde, gibst...
Ich bin noch nicht fortgeschritten und bitte um kleinschrittige Anweisen
evtl. möchtest du ja die CmdMessenger Lib einsetzen.
Ich habe einige Kommentare hinzugefügt, ich hoffe dass jetzt klar ist, was ich mit meinem Code erreichen wollte.
Da immer nur eine Ziffer geschickt wird, wollte ich den Cursor um eins verschieben und dann den nächsten Eintrag auf dem Display erscheinen lassen.
Aber das funktioniert nicht. Es erscheint an allen fünf Stellen immer die erste Ziffer, die geschickt wurde.
Im nächsten durchlauf der Loop werden alle 1-sen dann mit 2-en überschrieben uns so weiter.
Ich denke der Trick ist, die ganze Zahl sofort zu schicken. Ich weiß nur nicht wie???
Gruß
Adruinoboy
Der Code passt überhaupt nicht zusammen. Mit read() kannst du keine als String formatierten Gleitkommazahlen einlesen. Sondern nur ein einzelnes Zeichen. Klar zeigt er dir da immer das gleiche Zeichen an.
https://www.arduino.cc/reference/en/language/functions/communication/serial/parsefloat/ (https://www.arduino.cc/reference/en/language/functions/communication/serial/parsefloat/)
https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/ (https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/)
Ich denke der Trick ist, die ganze Zahl sofort zu schicken
Das Absenden ist zwar unnötig kompliziert, aber der Fehler legt beim Auslesen. Du liest nur ein Zeichen aus. Und es fehlt jegliche Überprüfung ob die Übertragung fertig ist. Du kannst dich nicht darauf verlassen dass der String immer gleich lang ist
Wenn du kein CR + LF am Ende brauchst, macht man übrigens print() statt println()
Welchen Code würdest du vorschlagen?
Laut deinen Links müsste in meinem Fall also folgender Code beim Slave sinnvoller sein!?
btData = Serial.parseInt();
Dann müsste ich also btData als Int deklarieren?
Gruß
Adruinoboy
parseFloat() hast du übersehen?
Es gibt bessere Optionen aber bei deinen Kenntnissen ist es das einfachste
Man könnte auch readString() verwenden. Eigentlich ist hier der Umweg über eine String/Zahl Konvertierung nicht nötig. Schadet aber auch nichts. Und man kann evtl. die Ausgabe so besser formatieren
void loop()
{
if(Serial.available()) //wenn Daten empfangen werden...
{
// Wird ein Zeichen ausgelesen
btData = Serial.read(); //..sollen diese ausgelesen werden
// Wird das eingelesene Zeichen auf dem ser.Mon. ausgegeben
Serial.print(btData); //Schreiben der Empfangenen Daten
digitalWrite(ledPin,HIGH); //Anzeige zur Verbindungsüberprüfung
lcd.setCursor(0, 0); //Den Cursor an den Anfang setzen
// Wird das eingelesene Zeichen auf dem LCD...
lcd.print(btData); //Das erste Zeichen auf dem Display anzeigen
delay(1000); //1 sec. warten
lcd.setCursor(1, 0); //Den Cursor auf das nächste Zeichen setzen
// Dafür müsste erstmal eine neue Ziffer da sein
lcd.print(btData); //Die nächste Ziffer ins Display schreiben
Was fehlt?
Wenn Du einen Ansatz hast, schreibs rein. Keine Angst.
Dir wird geholfen.
Ich habe meinen Code etwas verändert, jetzt liest er die ganze Zahl auf einen Schlag aus. Sehr gut.
Aber hinter der Zahl stehen noch 2 Felder mit horizontalen Linien.
Wahrscheinlich fehlt mir irgendwie eine Endsequenz. Gibt es so etwas, dass er eine Endsequenz direkt mitschickt? Oder kann man das auch einfacher lösen?
Hier der Sketch:
#include <SoftwareSerial.h>
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
#define ledPin 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
float btData;
void setup()
{
Serial.begin(9600); //serieller Monitor wird gestartet, Baudrate auf 9600 festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
}
void loop()
{
if(Serial.available()) //wenn Daten empfangen werden...
{
//Wird ein Zeichen ausgelesen
btData = Serial.parseFloat(); //..sollen diese ausgelesen werden
//Wird das eingelesene Zeichen auf dem seriellen Monitor ausgegeben
Serial.println(btData); //Schreiben der Empfangenen Daten
digitalWrite(ledPin,HIGH); //Anzeige zur Verbindungsüberprüfung
lcd.setCursor(0, 0); //Den Cursor an den Anfang setzen
//Wird das eingelesene Zeichen auf dem LCD...
lcd.println(btData); //Das erste Zeichen auf dem Display anzeigen
delay(5000); //5sec. warten
}
}
Ich habe meinen Code etwas verändert, jetzt liest er die ganze Zahl auf einen Schlag aus. Sehr gut.
Na geht doch ;)
Aber hinter der Zahl stehen noch 2 Felder mit horizontalen Linien.
Wahrscheinlich fehlt mir irgendwie eine Endsequenz. Gibt es so etwas, dass er eine Endsequenz direkt mitschickt? Oder kann man das auch einfacher lösen?
Dir fehlt keine Endsequenz. Die hast Du schon und die wird Dir - weil es eigentlich nicht sichtbare Zeichen sind - so angezeigt
Grund ist:
btSerial.println(btData);
Schau in der Referenz nach, was .println macht und was .read macht.
Das Gegenteil ist offensichtlich der Fall wenn da zu viel am Ende steht
Also .println schickt quasi eine Endsequenz mit "/n".
Was .read macht, daraus wurde ich nicht schlau.
Wie kann ich aber meine zwei Kästchen auf dem Display weg bekommen, damit ich die reinen Zahlenwerte erhalte?
Gruß
Adruinoboy
Vergleiche das (https://www.arduino.cc/reference/en/language/functions/communication/serial/println/) und das (https://www.arduino.cc/reference/en/language/functions/communication/serial/print/)
Herzlichen Danke, ich meine es verstanden zu haben.
Also println schickt immer den Code mit einem \r und \n hintendran. Mein Empfänger wusste nicht genau, was es damit anfangen sollte und hat daraus horizontale Linien gemacht.
Danke für die Hilfe.
Ich habe also aus dem Sketch erstmal alle println() rausgenommen, es funktioniert besser.
Was mir allerdings aufgefallen ist: Wenn ich den seriellen Monitor nicht öffne, wird die Lampe nicht angeschaltet und das Programm sieht die Bedingung if(serial.available()) als nicht wahr angenommen.
Ich kann mir nicht erklären warum.
Sobald ich den seriellen Monitor öffne, wird die Lampe aktiviert und das Programm läuft wie gewünscht.
Ich freue mich, wenn weiterhin genauso geduldige und kompetente Ratschläge und Hilfestellungen kommen würden, wie bisher.
Wenn ich den seriellen Monitor nicht öffne, wird die Lampe nicht angeschaltet und das Programm sieht die Bedingung if(Serial.available()) als nicht wahr angenommen.
Ich kann mir nicht erklären warum.
Ich schon. Hab mal die Doku angeschaut. Serial.available() (https://www.arduino.cc/reference/en/language/functions/communication/serial/available/) liefert die Anzahl angekommener, aber noch nicht per read() gelesener Zeichen. Sei froh, dass kein Müll ankommt, wenn da gar kein Sender angeschlossen ist, und in deinem Fall eine 0 (false) geliefert wird.
Mein Empfänger wusste nicht genau, was es damit anfangen sollte und hat daraus horizontale Linien gemacht.
Nein. Der weiß das genau. Steuerzeichen sind nun mal auf Displays nicht druckbar. Das Display verwendet den Speicher an der Stelle einfach für andere Zeichen.
Sei froh, dass kein Müll ankommt, wenn da gar kein Sender angeschlossen ist, und in deinem Fall eine 0 (false) geliefert wird.
Warum ist kein Sender angeschlossen? Das verstehe ich nicht. Ich habe einen Sender und Empfänger. Die finden sich auch.
Oder meinst du, dass ich einen Willkommenstext senden und empfangen muss, damit die Verbindung automatisch startet?
Ich freue mich, wenn du mir praktisch zeigst, was du meinst.
Hi
Das soll heißen, daß die Lib (oder Empfänger) genügend Intelligenz mitbringt, daß ein Sender sicher erkannt wird und - viel wichtiger, kein Sender ebenso erkannt wird.
Anders, wenn die Lib (oder Empfänger) einfach nur rauswirft, was wohl am Empfänger eingetrudelt ist, bekommst Du 'irgend was' - Das können korrekte Daten sein - aber eben auch nicht.
Das zu unterscheiden, ist nicht trivial - macht hier aber wohl Lib (oder Empfänger) bereits für Dich.
Somit ist Das, was Du als Antwort bekommst und nicht Null ist, eine echte Antwort - mit Der man arbeiten kann.
MfG
Hallo,
danke für die Erklärung nochmal. Also ich bekomme zwar sinnvolle Zahlenwerte, aber kannst du mir einen Ansatz zeigen, wie ich die Ausgabe bzw. das Empfangen auch intelligent steuern kann.
Ich würde mich freuen.
Übringens: Sender und Empfänger verbinden sich zwar, aber die Kommunikation startet nicht.
Ich bin euch echt dankbar, wenn ihr mir hierbei helft. Ich habe keinen Ansatz.
Hat keiner einen anregenden Gedanken?
Ich hoffe, dass ich noch eine Antwort auf meine Frage bekomme.
Mein Projekt entwickelt sich immer weiter. Ich habe jetzt einen DHT22 an meinen Master angeschlossen und sende jetzt die Temperatur und die Feuchtigkeit über den HC-05 auf den HC-06. Soweit alles in Ordnung, die Zeiten zum senden und empfangen passen auch so weit.
Um die Kommunikation zu ermöglichen, sendet der HC-06 den Text "Willkommen". Ist das eine gute Lösung?
Hier der aktuelle Sketch vom Master:
#include <SoftwareSerial.h> //Bibliothek für Serielle Schnittstelle
#include "DHT.h" //DHT Bibliothek laden
#define ledR 11 //Die rote LED wird an PIN 11 angeschlossen
#define ledG 12 //Die grüne LED wird an PIN 12 angeschlossen
#define ledB 13 //Die blaue LED wird an PIN 13 angeschlossen
#define rxPin 0 //Für die BL Verbindung
#define txPin 1 //Für den BL Verbindung
#define DHTPIN 2 //Der Sensor wird an PIN 2 angeschlossen
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600); //Serielle Verbindung starten
dht.begin(); //DHT22 Sensor starten
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(rxPin,INPUT);
pinMode(txPin,OUTPUT);
btSerial.println("bluetooth available");
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
analogWrite(ledB,255); //Blaue LED wird eingeschaltet
delay(5000);
}
void loop()
{
if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an und LED Bla aus
//Wartezeit, damit der Sensor die Messwerte ermitteln kann
delay(2000); //2 sek. bis zur Messung, weil der Sensor etwas langsam ist
//Definition beider Variablen für beide Messwerte
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Werte über HC-05
btSerial.println(tempaussen);
delay(30000); //Warten
btSerial.println(feuchteaussen);
// clear the string for new input:
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
tempaussen = 0; //Der Wert für Temperatur wird genullt
delay(28000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}
}
Und hier ist der aktuelle Sketch vom Slave:
#include <SoftwareSerial.h>
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
#define ledG 11
#define ledR 12
#define ledB 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
float btData;
void setup()
{
btSerial.begin(9600); //serieller Monitor wird gestartet
pinMode(11,OUTPUT); //PIN 11 wird als Ausgang festgelegt
pinMode(12,OUTPUT); //PIN 12 wird als Ausgang festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
lcd.setCursor(0,0); //Cursor auf Poition 0,0 setzen
lcd.print("Start"); //Schreib Start auf das Display
analogWrite(ledB,255);//Blaue LED an
delay(5000);
lcd.clear(); //Das Dispaly komplett löschen
}
void loop()
{
if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG,255);analogWrite(ledB,0); //Blaue LED aus und Grüne LED an
delay(2000); //2 sek. warten, für erfolgreiche Anmeldung
btSerial.print("Willkommen");
//Hier wird die Temperatur ausgelesen
delay(15000);
btData = btSerial.parseFloat(); //..sollen diese ausgelesen werden
//Wird das eingelesene Zeichen auf dem seriellen Monitor ausgegeben
btSerial.print(btData); //WICHTIG! Schreiben der Empfangenen Daten
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0,0); //Die Zeile wird gelöscht
lcd.print(" ");
lcd.setCursor(0, 0); //Den Cursor an den Anfang setzen
lcd.print(btData,2); //Den Zahlenwert auf das Display schreiben
lcd.setCursor(4,0); //Der Cursor wird auf die 2. Nachkommastelle gesetzt
lcd.print(" "); //Die 2. Nachkommastelle wird nicht benötigt und wird geslöscht
lcd.setCursor(5,0);
lcd.print("Grad"); //Grad hinter die Zahl setzen
//clear the float for new input
btData = 0;
delay(30000);
//Hier wird die Feuchtigkeit ausgelesen
btData = btSerial.parseFloat(); //..sollen diese ausgelesen werden
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0, 1); //Die Zeile wird gelöscht
lcd.print(" ");
lcd.setCursor(0, 1); //Den Cursor an den Anfang setzen
lcd.print(btData,2); //Den Zahlenwert auf das Display schreiben
lcd.setCursor(4,1); //Der Cursor wird auf die 2. Nachkommastelle gesetzt
lcd.print(" "); //Die 2. Nachkommastelle wird nicht benötigt und wird geslöscht
lcd.setCursor(5,1);
lcd.print("%"); //Grad hinter die Zahl setzen
//clear the float for new input
btData = 0;
delay(13000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}
}
Hallo Leute, ich habe auf dieser Seite die Lösung meines Problems gefunden.
https://forum.arduino.cc/index.php?topic=214276.0
Auf der Seite wird beschrieben, wie ein Reset ausgeführt werden kann. Nämlich ein Kabel von RES kurz auf den neutralen Rückleiter geben. Das ist genau so viel, wie das öffnen des seriellen Monitors damit startet das Programm wie gewünscht.
Ich muss nur noch rausfinden, wie ich das am besten in meinen Sketch einbaue.
Falls jemand ebenfalls das Problem hat, dann gibt es hier einen Ansatz.
Was willst du mit einem Reset im Sketch?
Das ist meist eine ganz dumme Idee.
Der Reset ist meine Rettung, sonst könnte ich mein Projekt nicht verwirklichen. Zumindest mit meinen Programmierkenntnissen.
Die Sache ist, der Master geht alleine nicht in die if-Bedingung, obwohl sich beide Bluetooth Module gefunden haben (laut dem Blinkrythmus bzw. dem leuchten). Der wartet solange, bis ich den seriellen Monitor öffne, dann geht er in die if-Bedingung und sendet die Messwerte an den HC-06.
Ich habe ihm gesagt, wenn die if-Bedingung nicht wahr ist, dann mach einen Reset.
Das läuft wie geschmiert.
Der Watchdog soll eine elegantere Lösung sein, freue mich sehr für Vorschläge mit der Watchdog-Lösung. Dann ersetze ich meinen Neustart sofort.
Hier nochmal der Sketch vom Master, mit dem Reset-Befehl.
#include <SoftwareSerial.h> //Bibliothek für Serielle Schnittstelle
#include "DHT.h" //DHT Bibliothek laden
#define ledR 11 //Die rote LED wird an PIN 11 angeschlossen
#define ledG 12 //Die grüne LED wird an PIN 12 angeschlossen
#define ledB 13 //Die blaue LED wird an PIN 13 angeschlossen
#define rxPin 0 //Für die BL Verbindung
#define txPin 1 //Für den BL Verbindung
#define DHTPIN 2 //Der Sensor wird an PIN 2 angeschlossen
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600); //Serielle Verbindung starten
dht.begin(); //DHT22 Sensor starten
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(rxPin,INPUT);
pinMode(txPin,OUTPUT);
btSerial.println("bluetooth available");
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
analogWrite(ledB,255); //Blaue LED wird eingeschaltet
delay(5000);
}
void loop()
{
if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an und LED Bla aus
//Wartezeit, damit der Sensor die Messwerte ermitteln kann
delay(2000); //2 sek. bis zur Messung, weil der Sensor etwas langsam ist
//Definition beider Variablen für beide Messwerte
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Werte über HC-05
btSerial.println(tempaussen);
delay(30000); //Warten
btSerial.println(feuchteaussen);
// clear the string for new input:
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
tempaussen = 0; //Der Wert für Temperatur wird genullt
delay(28000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}
else
{
asm volatile ("jmp 0"); //Wenn BT Verbindung weg, dann Neustart
}
}
Du machst mich erschrocken.
Wäre es nicht besser, die ganzen delay zu entsorgen, und ein ordentliches Protokoll zwischen den Beiden zu fahren?
Aber was solls, des Menschen Wille ist sein Himmelreich.
Ja, ich habe bemerkt, dass die delay-Zeiten sich verschieben. Dann zeigt er mir nach wenigen Stunden, an der Stelle für Temp. die Feuchtigkeit an und anders herum. Das ist Schade :(
Ich weiß aber nicht, wie ich ein ordentliches Protokoll fahren kann.
Ich freue mich für jeden Ansatz und jeden Hinweis.
CmdMessenger
Das wäre ein korrekte Lösung.
Aber wenigstens ein Minimaldings (ich will es nicht Protokoll nennen) sollte doch möglich sein:
...
//Senden der Werte über HC-05
btSerial.print("T:"); // Kennung Temperatur außen; Doppelpunkt kommt in den Zahlen nicht vor und ist Ende der Kennung
btSerial.println(tempaussen);
btSerial.print("F:"); // Kennung Feuchte außen (könnte auch "FA" sein, falls später mal "FK" für "Feuchte Keller" dazukommt)
btSerial.println(feuchteaussen);
...
Dann auf der Gegenseite mit readBytesUntil() die Zeichen bis zum Doppelpunkt weglesen und dann kommt der passende Wert.
ich will es nicht Protokoll nennen
Ich schon :)
Den Doppelpunkt kann man sich sogar sparen, denn weder 'T' noch 'F' kommt in einer Zahl vor.
Wenn eine Zeile mit einem Buchstaben anfängt und man dann die folgende Zahl (bis zum Zeilenende) auswertet, sollte man schon fertig sein.
Dieses "Protokoll" könnte man sogar auf einige (min. zwei) Dutzend verschiedene Messwerte anwenden.
Danke Leute, dass ihr mir so schnell helft.
Ich habe den Ansatz versucht anzuwenden. Aber ich habe den Befehl "CmdMessenger" noch nicht verstanden.
Hier ist der Sketch vom Slave, der macht Probleme :( Freue mich bei weiterer Hilfe.
#include <SoftwareSerial.h>
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
#include <CmdMessenger.h> // CmdMessenger für geschickte Datenübertragung
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
#define ledG 11
#define ledR 12
#define ledB 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
float btData = 0; //Für eingehende Messwerte
char T = 0; //Kennung für Temp
char F = 0; //Kennung für Feuchtigkeit
void setup()
{
btSerial.begin(9600); //serieller Monitor wird gestartet
pinMode(11,OUTPUT); //PIN 11 wird als Ausgang festgelegt
pinMode(12,OUTPUT); //PIN 12 wird als Ausgang festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
lcd.setCursor(0,0); //Cursor auf Poition 0,0 setzen
lcd.print("Start"); //Schreib Start auf das Display
analogWrite(ledR,0);analogWrite(ledG,0);analogWrite(ledB,255);//Blaue LED an
}
void loop()
{
if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG,255);analogWrite(ledB,0); //Blaue LED aus und Grüne LED an
delay(2000); //2 sek. warten, für erfolgreiche Anmeldung
btSerial.print("Willkommen");
//Hier wird die Temperatur ausgelesen
T = btSerial.readBytesUntil();
//btData = btSerial.parseFloat(); //..sollen diese ausgelesen werden
//Wird das eingelesene Zeichen auf dem seriellen Monitor ausgegeben
btSerial.print(btData); //WICHTIG! Schreiben der Empfangenen Daten
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0,0); //Cursor an den Anfang setzen
lcd.print(" "); //Die Zeile wird gelöscht
lcd.setCursor(0, 0); //Den Cursor wieder an den Anfang gesetzt
lcd.print(btData,2); //Die Temperatur auf das Display schreiben
lcd.setCursor(4,0); //Der Cursor wird auf die 2. Nachkommastelle gesetzt
lcd.print(" "); //Die 2. Nachkommastelle wird gelöscht
lcd.setCursor(5,0); //Cursor hinter Temp. setzen
lcd.print("Grad"); //Grad hinter Temp. schreiben
//clear the float for new input
btData = 0; //Den Float auf Null setzen
//Hier wird die Feuchtigkeit ausgelesen
F = btSerial.readBytesUntil();
//btData = btSerial.parseFloat();
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0, 1); //Cursor an den Anfang der 2. Zeile setzen
lcd.print(" "); //Die Zeile wird gelöscht
lcd.setCursor(0, 1); //Den Cursor an den Anfang der 2. Zeile setzen
lcd.print(btData,2); //Die Feuchtigkeit auf das Display schreiben
lcd.setCursor(4,1); //Der Cursor auf die 2. Nachkommastelle setzen
lcd.print(" "); //Die 2. Nachkommastelle wird gelöscht
lcd.setCursor(5,1); //Den Cursor auf 2. Nachkommastelle setzen
lcd.print("%"); //% hinter die Feuchtigkeit setzen
//clear the float for new input
btData = 0;
delay(13000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}
}
Ich erhalte folgende Fehlermeldung:
no matching function for call to 'SoftwareSerial::readBytesUntil()'
Muss ich T und F vorher irgendwie als "int" oder "char" oder sonst was deklarieren??
Muss ich T und F vorher irgendwie als "int" oder "char" oder sonst was deklarieren??
Ja, hast du. Als
char.
no matching function for call to 'SoftwareSerial::readBytesUntil()'
Schau dir readBytesUntil an. Das erwartet Parameter, und liefert nicht das zurück, was du vermutlich erwartest. Vermutlich wäre das einfache read() eher das was du suchst.
Ich habe große Schwierigkeiten mit dem Code!
char T = 0; //Kennung für Temp
char F = 0; //Kennung für Feuchtigkeit
Aus meiner Sicht müssen Variablen klein geschrieben werden!
Also eher so:
char kennung = 'T';
Aber nicht unbedingt so.
lcd.print(btData,2); //Die Feuchtigkeit auf das Display schreiben
lcd.setCursor(4,1); //Der Cursor auf die 2. Nachkommastelle setzen
lcd.print(" "); //Die 2. Nachkommastelle wird gelöscht
lcd.setCursor(5,1); //Den Cursor auf 2. Nachkommastelle setzen
lcd.print("%"); //% hinter die Feuchtigkeit setzen
Das tut in meinen Augen richtig weh!
lcd.setCursor(4,1); //Der Cursor auf die 2. Nachkommastelle setzen
lcd.setCursor(5,1); //Den Cursor auf 2. Nachkommastelle setzen
Wo ist sie denn nun, die zweite Nachkommastelle?
Auf 4 oder 5?
Warum 2 Stellen ausgeben, wenn doch nur eine gewünscht ist.
Dieses macht doch das gleiche, wie der obige ganze Klumpen, oder?
lcd.print(btData,1); //Die Feuchtigkeit auf das Display schreiben
lcd.print(" %"); //% hinter die Feuchtigkeit setzen
Aus meiner Sicht müssen Variablen klein geschrieben werden!
Du meinst "
Ich schreibe Variablen immer mit kleinem Anfangsbuchstaben, weil..."
(alles andere erzeugt nur unnötige Verwirrung bei menschlichen Lesern) oder andere Begründung.
Früher
TM hat man Konstanten gerne Namen nur mit Großbuchstaben gegeben, um sie von Variablen zu unterscheiden.
const char T {'T'}; // relativ sinnlos, aber erlaubt.
if (Serial.read() == T) {
// es folgt ein Temperatur-Wert
char line[20];
byte len = readBytesUntil('\n', line, sizeof(line)-1);
line[len] = 0; // terminator
temperatur = atoi(line);
}
Hat den Nachteil, dass der Kennbuchstabe weggelesen ist, wenn es kein 'T' war.
Du meinst "Ich schreibe Variablen immer mit kleinem Anfangsbuchstaben, weil..."
Und ganz sicher nehme ich nicht T als Variablenbezeichner!
wg.: template<typename T>
Ein buchstabige Bezeichner nur in einem ganz klar begrenzten Geltungsbereich.
Z.B. begrenzt auf einer Bildschirmseite im Editor.
i, j, k für Schleifenzähler
p für Referenzen auf Print
T, U, V, W für variable Typen, aber auch da lieber Mehrbuchstabig
t für temporäre Daten, aber auch da lieber temp, als t
FrüherTM hat man Konstanten gerne Namen nur mit Großbuchstaben gegeben, um sie von Variablen zu unterscheiden.
Das sollte man für defines beibehalten, auch wenn ich selber manchmal dagegen verstoße.
INTERTVAL() <- richtig
taskBegin() <- Verstoß
Nachtrag:
Natürlich kann da jeder seine eigene Systematik entwickeln.
Aber je ähnlicher mit anderen etablierten, desto leichter zu lesen.
Ich habe den Ansatz versucht anzuwenden. Aber ich habe den Befehl "CmdMessenger" noch nicht verstanden.
Du hast leider beide Ansätze durcheinander geworfen.
CmdMessenger ist eine Library, die das Implementieren von solchen Protokollen unterstützt (eigentlich eine Klasse). Im alten Playground habe ich Dokumentation (https://playground.arduino.cc/Code/CmdMessenger/) gefunden - vielleicht hat combie noch was besseres.
Hier ist der Sketch vom Slave, der macht Probleme :(
Das ist dann kein Wunder.
Die Erläuterungen zu readBytesUntil() finden sich hier (https://www.arduino.cc/reference/en/language/functions/communication/serial/readbytesuntil/).
Wenn Du tatsächlich nur einen Buchstaben 'T' oder 'F' als Kennung verwendest, brauchst Du da natürlich kein readBytesUntil(); dann reicht das Lesen dieses einen Zeichens und danach dann den Wert (aber das konntest Du ja schon).
Hier ist meine Quelle (https://github.com/thijse/Arduino-CmdMessenger)
Im Grunde ist der sehr einfach einzusetzen.
Könnte ich hier auch als Beispiel mal zeigen, wenn man mir mal erklärt, was das überhaupt werden soll, hier...
Denn, einer guten Problembeschreibung wohnt die Lösung schon (fast) inne.
Ansonsten hilft ja auch der gute alte Parserbau.
Endliche Automaten in Reinform.
Ein Hand gedengeltes Protokoll und selbst gestrickte Ausgabe und Parser Funktionen/Methoden.
--- Ist schon schön, wenn man das mal begriffen hat. ---
Ein einfacher Sender:
#include <Streaming.h>
#include <SoftwareSerial.h>
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define rxPin 3
#define txPin 4
SoftwareSerial btSerial(rxPin, txPin);
void setup()
{
btSerial.begin(9600);
}
void loop()
{
delay(3000);
btSerial << Temperatur << ',' << 18.6 << ';' << endl;
delay(3000);
btSerial << Feuchtigkeit << ',' << 54.77 << ';' << endl;
}
Dieser sendet schön abwechselnd 2 Kommandos:
1,18.6;
und
2,54.77;
Und ein Empfänger, welcher diese Daten auswertet:
#include <CmdMessenger.h>
#include <Streaming.h>
#include <SoftwareSerial.h>
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define rxPin 3
#define txPin 4
SoftwareSerial btSerial(rxPin, txPin);
CmdMessenger cmdMessenger {btSerial};
void setup()
{
Serial.begin(9600);
btSerial.begin(9600);
Serial << "Start: "<< __FILE__ << endl;
cmdMessenger.attach(Temperatur, [](){
float t = cmdMessenger.readFloatArg();
Serial << "Temperatur " << t << " C" << endl;
});
cmdMessenger.attach(Feuchtigkeit, [](){
float f = cmdMessenger.readFloatArg();
Serial << "Feuchtigkeit " << f << " %" << endl;
});
}
void loop()
{
cmdMessenger.feedinSerialData();
}
* Beides völlig ungetestet, da die Hardware nicht bereit steht *
Oh - danke für das Beispiel.
Muss ich mich mal genauer mit beschäftigen, denn Du setzt CmdMessenger nur auf der Empfängerseite ein. Das finde ich spannend.
Gruß Walter
Du setzt CmdMessenger nur auf der Empfängerseite ein.
Ein Schnellschuß ohne tiefere Bedeutung.
Eigentlich nur um zu zeigen, wie klar und naiv dieses Protokoll ist.
Natürlich kann man auch die volle Featuritis des CmdMesseger nutzen.
Macht sogar Sinn, wenn es komplexer wird.
Danke für die vielen Hinweise.
Ich muss das erstmal verarbeiten. Danke auch für das Beispiel. Ich denke, dass wird mir helfen.
Hallo Leute, ich bin von eurer Hilfsbereitschaft begeistert.
Ich habe jetzt meinen Sketch nach dem Beispiel angepasst.
So weit, so gut. Der Sketch an sich macht auch keine Probleme, aber der HC-05 und der HC-06 finden sich nicht.
Freue mich, wenn ihr drüber schaut und mich auf meinen Fehler aufmerksam macht.
Hier der Master:
#include <SoftwareSerial.h> //Bibliothek für Serielle Schnittstelle
#include "DHT.h" //DHT Bibliothek laden
#include <CmdMessenger.h> // CmdMessenger
#include <Streaming.h> //Bibliothek für die BT Verbindung
enum Comand
{
Temperatur = 1,
Feuchtigkeit = 2
};
#define ledR 11 //Die rote LED wird an PIN 11 angeschlossen
#define ledG 12 //Die grüne LED wird an PIN 12 angeschlossen
#define ledB 13 //Die blaue LED wird an PIN 13 angeschlossen
#define rxPin 0 //Für die BL Verbindung
#define txPin 1 //Für den BL Verbindung
#define DHTPIN 2 //Der Sensor wird an PIN 2 angeschlossen
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600); //Serielle Verbindung starten
Serial.begin(9600); //Serieller Monitor
dht.begin(); //DHT22 Sensor starten
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(rxPin,INPUT);
pinMode(txPin,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
analogWrite(ledB,255); //Blaue LED wird eingeschaltet
btSerial.println("bluetooth available");
}
void loop()
{
if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an und LED Bla aus
//Wartezeit, damit der Sensor die Messwerte ermitteln kann
delay(2000); //2 sek. bis zur Messung, weil der Sensor etwas langsam ist
//Auslesen der Temperatur und Feuchtigkeit
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
delay(3000);
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
delay(3000);
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*Senden der Werte über HC-05
btSerial.print("T:"); // Kennung Temperatur außen; Doppelpunkt kommt in den Zahlen nicht vor und ist Ende der Kennung
btSerial.println(tempaussen);
btSerial.print("F:"); // Kennung Feuchte außen (könnte auch "FA" sein, falls später mal "FK" für "Feuchte Keller" dazukommt)
btSerial.println(feuchteaussen);*/
// clear the string for new input:
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
tempaussen = 0; //Der Wert für Temperatur wird genullt
//delay(28000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}
/*else
{
asm volatile ("jmp 0"); //Wenn BT Verbindung weg, dann Neustart
}*/
}
Und hier der Slave:
#include <SoftwareSerial.h>
#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
#include <Streaming.h> //Bibliothek zum Empfangen
#include <CmdMessenger.h> // CmdMessenger für geschickte Datenübertragung
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
enum Comand
{
Temperatur = 1,
Feuchtigkeit = 2
};
#define ledG 11
#define ledR 12
#define ledB 13
#define rxPin 0
#define txPin 1
SoftwareSerial btSerial(rxPin, txPin);
CmdMessenger cmdMessenger {btSerial};
char tempaussen = 'T'; //Kennung für Temp
char feuchteaussen = 'F'; //Kennung für Feuchtigkeit
void setup()
{
btSerial.begin(9600); //serielle Verbindung wird gestartet
Serial.begin(9600); //serieller Monitor wird gestartet
Serial << "Start: "<< __FILE__ << endl;
cmdMessenger.attach(Temperatur, []()
{
float t = cmdMessenger.readFloatArg();
Serial << "Temperatur " << t << " C" << endl;
});
cmdMessenger.attach(Feuchtigkeit, []()
{
float f = cmdMessenger.readFloatArg();
Serial << "Feuchtigkeit " << f << " %" << endl;
});
pinMode(11,OUTPUT); //PIN 11 wird als Ausgang festgelegt
pinMode(12,OUTPUT); //PIN 12 wird als Ausgang festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
lcd.setCursor(0,0); //Cursor auf Poition 0,0 setzen
lcd.print("Start"); //Schreib Start auf das Display
analogWrite(ledR,0);analogWrite(ledG,0);analogWrite(ledB,255);//Blaue LED an
}
void loop()
{
/*if(btSerial.available()) //wenn Daten empfangen werden...
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG,255);analogWrite(ledB,0); //Blaue LED aus und Grüne LED an
delay(2000); //2 sek. warten, für erfolgreiche Anmeldung
btSerial.print("Willkommen");
//Hier wird die Temperatur ausgelesen
tempaussen = btSerial.read();
//btData = btSerial.parseFloat(); //..sollen diese ausgelesen werden
//Wird das eingelesene Zeichen auf dem seriellen Monitor ausgegeben
btSerial.print('T'); //WICHTIG! Schreiben der Empfangenen Daten
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0, 0); //Cursor an den Anfang setzen
lcd.print(" "); //Die Zeile wird gelöscht
lcd.setCursor(0, 0); //Den Cursor wieder an den Anfang gesetzt
lcd.print(tempaussen,1); //Die Temperatur auf das Display schreiben
lcd.print(" Grad"); //Grad hinter Temp. schreiben
//Hier wird die Feuchtigkeit ausgelesen
feuchteaussen = btSerial.read();
//btData = btSerial.parseFloat();
//Wird die eingelesene Feuchigkeit angezeigt
Serial.print(feuchteaussen);
//Das eingelesene Zeichen soll auf dem LCD ausgegeben werden
lcd.setCursor(0, 1); //Cursor an den Anfang der 2. Zeile setzen
lcd.print(" "); //Die Zeile wird gelöscht
lcd.setCursor(0, 1); //Den Cursor an den Anfang der 2. Zeile setzen
lcd.print(feuchteaussen,1); //Die Feuchtigkeit auf das Display schreiben
lcd.print(" %"); //% hinter die Feuchtigkeit setzen
//clear the float for new input
delay(13000);
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Grüne LED aus und rote LED an
}*/
cmdMessenger.feedinSerialData();
}
Hier ist meine Quelle (https://github.com/thijse/Arduino-CmdMessenger)
Könnte ich hier auch als Beispiel mal zeigen, wenn man mir mal erklärt, was das überhaupt werden soll, hier...
Denn, einer guten Problembeschreibung wohnt die Lösung schon (fast) inne.
Verstehe ich das richtig, dass das Ziel meines Projekts nicht klar definiert ist?
Falls dem so ist: Ich möchte die Temperatur und die Feuchtigkeit außen messen und dann die Werte auf dem Arduino innen auf dem Display ablesen können.
#define rxPin 0 //Für die BL Verbindung
#define txPin 1 //Für den BL Verbindung
Bei den üblichen Arduinos sind die beiden Pins schon von HardwareSerial belegt.
Darum hatte ich extra andere verwendet.
Verstehe ich das richtig, dass das Ziel meines Projekts nicht klar definiert ist?
Ja.
Zumindest nicht so klar, dass dein Arduino begreift, was du von ihm willst.
Ich, als Mensch, kann in deine Aussagen was rein interpretieren.
Arduino kann das nicht.
Da muss man ganz klar denken und diese klare Denke dem Dingen aufprägen.
Ich habe die Ports jetzt verlegt. Aber die Bluetooth-Module finden sich immer noch nicht.
Die blinken so, dass sie sich suchen, finden sich aber nicht.
Eine Verständnisfrage: Spielt das eine Rolle, wenn ich bei einem Arduino die Ausgänge 2 und 3 und bei dem anderen Arduino 3 und 4 nehme? Oder funktioniert das nicht?
Eine Verständnisfrage: Spielt das eine Rolle, wenn ich bei einem Arduino die Ausgänge 2 und 3 und bei dem anderen Arduino 3 und 4 nehme? Oder funktioniert das nicht?
Einfach mal die Doku lesen.... (https://www.arduino.cc/en/Reference/SoftwareSerial)
Ich habe dein Beispiel mal ausprobiert. Es gibt wie schon gesagt, keine Schwierigkeiten beim Hochladen.
Mit LEDs habe ich auch geprüft, dass das gesamte Programm durchlaufen wird.
Nur kann keine Verbindung zwischen den Modulen hergestellt werden. Beide suchen, können sich aber gegenseitig nicht finden.
Auf dem seriellen Monitor des Senders gibt es keine Ausgabe.
Beim Empfänger ist folgender Eintrag im seriellen Monitor zu finden:
16:01:30.774 -> Start: D:\Dateiordner\Arduino zu Hause\Beispielsketch empfänger\Beispielsketch_empf_nger\Beispielsketch_empf_nger.ino
Ich hoffe die Informationen reichen, damit meinem Problem geholfen werden kann.
Suchtipp: "hc-05 hc-06 pairing"
Ich bin schon lange dabei meine hc-05 und hc-06 zu verbinden, doch ohne Erfolg.
Als ich die Frage gestellt habe, lief die Verbindung einwandfrei.
Ich weiß nicht was da passiert ist, dass meine Verbindung weg ist.
Ich habe den Beitrag oben befolgt und die Einstellungen für beide Module mit den AT-Befehlen durchgeführt.
Der Master findet sogar die Adresse vom Slave mit +INQxxxx.xx.xx u.s.w. aber ich habe bei AT-PAIR kein OK zurückbekommen.
Ich weiß nicht, was ich mit den beiden noch machen soll?
Die suchen sich wieder, aber finden sich nicht.
Ich freue mich auf Rückmeldung. Es gibt doch bestimmt welche die mir helfen können.
Es liegt bestimmt an irgendwelchen AT-Einstellungen. Ich weiß nur nicht welche.
Wie schon gesagt: Ich habe deine Module nicht bereit liegen, um zu testen.
Auch hältst du geheim, was du versuchst, so kann man es noch nicht mal mit der Doku vergleichen.
Wie stellst du dir so eine Hilfe vor?
Hallo Leute,
plötzlich hat es bei mir geklappt :) Also das Problem lag wahrscheinlich im Master. Ich habe dem im AT-Modus gesagt: AT+CMODE=1. Aber das ging mit diesem Sketch:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
Serial.begin(9600);
pinMode(9,OUTPUT); digitalWrite(9,HIGH);
Serial.println("Enter AT commands:");
mySerial.begin(38400);
}
void loop()
{
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
}
Folgend habe ich das hc-05 Modul mit dem UNO verbunden:
Rx -> Pin 10
Tx -> Pin 11
Gnd -> Gnd
Vcc -> 5V
En -> 3,3v
Dann hat er mir Rückmeldungen auf meine AT-Commands gegeben.[/code]
Jetzt habe ich deinen Code hochgeladen:
#include <Streaming.h>
#include <SoftwareSerial.h>
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define rxPin 3
#define txPin 4
int c = 0;
SoftwareSerial btSerial(rxPin, txPin);
void setup()
{
Serial.begin(9600);
Serial.println("Arduino with HC-05 is ready");
btSerial.begin(9600);
Serial.println("Bluetooth Modul also ready");
}
void loop()
{
if(btSerial.available())
{
c = btSerial.read();
Serial.write(c);
}
if(Serial.available())
{
c = Serial.read();
Serial.write(c);
btSerial.write(c);
}
delay(3000);
btSerial << Temperatur << ',' << 18.6 << ';' << endl;
delay(3000);
btSerial << Feuchtigkeit << ',' << 54.77 << ';' << endl;
}
Ich habe das hc--05 Modul jetzt so angeschlossen:
Rx -> Pin 4
Tx -> Pin 3
Gnd -> Gnd
Vcc -> 5V
EN -> nicht
Auf meinem Slave ist folgender Code drauf:
#include <CmdMessenger.h>
#include <Streaming.h>
#include <SoftwareSerial.h>
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define rxPin 3
#define txPin 4
SoftwareSerial btSerial(rxPin, txPin);
CmdMessenger cmdMessenger {btSerial};
void setup()
{
Serial.begin(9600);
btSerial.begin(9600);
Serial.println("Arduino with HC-06 is ready");
Serial.println("BTSerial started at 9600");
Serial << "Start: "<< __FILE__ << endl;
cmdMessenger.attach(Temperatur, [](){
float t = cmdMessenger.readFloatArg();
Serial << "Temperatur " << t << " C" << endl;
});
cmdMessenger.attach(Feuchtigkeit, [](){
float f = cmdMessenger.readFloatArg();
Serial << "Feuchtigkeit " << f << " %" << endl;
});
}
void loop()
{
if(btSerial.available())
{
btSerial.write(Serial.read());
}
if(Serial.available())
{
Serial.write(btSerial.read());
}
cmdMessenger.feedinSerialData();
}
Das hc-06 Modul ist so angeschlossen:
Rx -> Pin 4
Tx -> Pin 3
Gnd -> Gnd
Vcc -> 3.3V
Ich hoffe ich habe alles notwendige geschrieben. Falls ich irgendwas vergessen habe zu schreiben, freue ich mich auf Rückmeldung. Ich weiß immer nicht was ihr für Informationen braucht um mir zu helfen.
btSerial.begin(9600);
mySerial.begin(38400);
Welche Baudrate ist denn nun richtig?
Ich arbeite immer mit der Baudrate 9600. Diese 38400 sind nur in dem Sketch, indem ich die AT-Commands ausgeführt habe. Es scheint auch so funktioniert zu haben. Der Sketch, der jetzt bei mir läuft hat die Baudrate 9600.
Auf dem seriellen Monitor schreibt der hc-05 im Abstand von 3 Sekunden ein Fragezeichen??? Ich habe dem das eigentlich nicht gesagt ;)
Die Ausgabe des seriellen Monitors sieht so aus:
11:07:04.691 -> Arduino with HC-05 is ready
11:07:04.691 -> Bluetooth Modul also ready
11:07:10.691 -> ⸮⸮⸮⸮⸮⸮⸮
Der hc-06 schreibt auch etwas interessantes im seriellen Monitor:
Die Ausgabe sieht da so aus:
11:08:12.408 -> Arduino with HC-06 is ready
11:08:12.408 -> BTSerial started at 9600
11:08:12.455 -> Start: D:\Daniel\Arduino zu Hause\Beispielsketch empfänger\Beispielsketch_empf_nger\Beispielsketch_empf_nger.ino
11:08:14.049 -> Temperatur 0.00 C
11:08:29.111 -> Temperatur 0.00 C
11:08:32.157 -> Temperatur 0.00 C
11:08:41.204 -> Feuchtigkeit 18.00 %
11:08:53.204 -> Temperatur 0.00 C
11:09:08.250 -> Temperatur 54.00 C
11:09:17.297 -> Feuchtigkeit 5.00 %
11:09:53.436 -> Temperatur 0.00 C
11:09:56.436 -> Temperatur 0.00 C
11:10:02.483 -> Feuchtigkeit 1.00 %
11:10:20.529 -> Feuchtigkeit 0.00 %
11:10:26.529 -> Feuchtigkeit 5.00 %
Kann das sein, dass etwas mit den Empfangs- und Sendezeiten nicht passt. Oder muss irgendeine Endsequenz eingetragen werden?
Jetzt habe ich deinen Code hochgeladen:
Das ist nicht mein Code!
Du hast da Zeugs eingebaut.
In beide mein Codes.
Und so selber das Versagen eingeleitet.
if(Serial.available())
{
c = Serial.read();
Serial.write(c);
btSerial.write(c);
}
Das Fragment zerhackt das Protokoll.
Tipp:
Ein Protokoll kann nur "wirken", wenn sich alle daran halten!
Wenn da einer unkultiviert zwischen quatscht, oder dem Messenger Zeichen klaut, wird es versagen.
Perfekt, danke. Jetzt funktioniert das. Die Daten werden ausgelesen und sauber in den seriellen Monitor geschrieben.
Eine Frage habe ich noch. In welche Variable wird die Temperatur bzw. die Feuchtigkeit geschrieben?
Ich möchte nähmlich die Temp. und Feuchtigkeit auf einem Display ausgeben.
Das t wurde vorher ja als float deklariert, aber wenn ich das "t" auf dem Dispaly ausgeben möchte, erscheint der Fehler, dass das "t" nicht deklariert sei.
Das t hat einen eingeschränkten Geltungsbereich!
Lesetipp: "C++ variable scope"
Herzlichen Dank. Es funktioniert sehr gut. Der Tipp hat mich zu folgender Lösung gebracht.
Ich freue mich, wenn ihr noch mal drüber schauen könntet, ob es sich um eine gute Lösung handelt.
Das ist mein Sender:
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define ledR 11
#define ledG 12
#define ledB 13
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
analogWrite(ledB,255); //Blaue LED wird eingeschaltet
}
void loop()
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Messwerte
delay(3000);
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
delay(3000);
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*****************************************/
//Löschen der Messwerte
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
tempaussen = 0; //Der Wert für Temperatur wird genullt
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Rote LED an
}
Und das ist der Empfänger:
#include <CmdMessenger.h> //Bibliothek zur BT Verbindung
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h> //LiquidCrystal_I2C Bibliothek einbinden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define ledR 11
#define ledG 12
#define ledB 13
#define rxPin 3
#define txPin 4
float t = 0;
float f = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
SoftwareSerial btSerial(rxPin, txPin);
CmdMessenger cmdMessenger {btSerial};
void setup()
{
Serial.begin(9600);
btSerial.begin(9600);
Serial << "Start: "<< __FILE__ << endl;
cmdMessenger.attach(Temperatur, [](){
t = cmdMessenger.readFloatArg();
Serial << "Temperatur " << t << " °C" << endl;
});
cmdMessenger.attach(Feuchtigkeit, [](){
f = cmdMessenger.readFloatArg();
Serial << "Feuchtigkeit " << f << " %" << endl;
});
pinMode(11,OUTPUT); //PIN 11 wird als Ausgang festgelegt
pinMode(12,OUTPUT); //PIN 12 wird als Ausgang festgelegt
pinMode(13,OUTPUT); //PIN 13 wird als Ausgang festgelegt
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
lcd.setCursor(0,0); //Cursor auf Poition 0,0 setzen
lcd.print("Start"); //Schreib Start auf das Display
analogWrite(ledR,0);analogWrite(ledG,0);analogWrite(ledB,255);//Blaue LED an
}
void loop()
{
analogWrite(ledR,0);analogWrite(ledG,255);analogWrite(ledB,0); //Grüne LED an
cmdMessenger.feedinSerialData();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(t,1);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(f,1);
lcd.print(" %");
delay(5000); //5 Sekunden Pause
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Rote LED an
}
Wie wäre es, wenn du alle delay() entsorgst, und statt dessen den Nachtwächter zum Einsatz bringst?
Hallo Combie, danke für den Hinweis. Ich habe auch schon vorher den Gedanken gehabt einen Watchdog einzufügen, aber das schien mir zu kompliziert.
Ich habe in meinen Sketch stumpf den Nachtwächter-Sketch von folgender Seite eingebaut:
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Und dann meine delay-Zeiten gelöscht.
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN;
// Variables will change:
int ledState = LOW;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;
//constants won´t change
const long interval = 1000;
#define ledR 11
#define ledG 12
#define ledB 13
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
//set the digital pin as output:
pinMode(ledPin, OUTPUT);
analogWrite(ledB,255); //Blaue LED wird eingeschaltet
}
void loop()
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{//save the last time you blinked the LED
previousMillis = currentMillis;
}
//if the LED is off turn it on and vice-versa
if(ledState == LOW)
{
ledState = HIGH;
}
else
{
ledState = HIGH;
}
//set the LED with the ledState of the variable
digitalWrite(ledPin, ledState);
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Messwerte
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*****************************************/
//Löschen der Messwerte
tempaussen = 0; //Der Wert für Temperatur wird genullt
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
analogWrite(ledR,255);analogWrite(ledG,0);analogWrite(ledB,0); //Rote LED an
}
Beim Hochladen gab es keine Fehlermeldung, aber die Zahlenwerte werden nicht gesendet. Die Bluetoothmodule finden sich, aber auf dem Display und auf dem seriellen Monitor wird nichts ausgegeben.
Ich freue mich, wenn mir jemand weiterhelfen könnte.
Hi
Sorry - aber den Nachtwächter sehe ich nicht wirklich.
Du merkst Dir alle x Millisekunden die neue Uhrzeit - mehr aber auch nicht.
IMMER werden die LED auf Grün gestellt, die Messungen gemacht, die LED umgeschaltet, Zeugs ans BT-Modul geschickt und die rote, statt der grünen LED angeworfen.
Was soll das Ganze machen?
MfG
Ein paar Tipps könnte ich dir geben...
Denn im Augenblick kann ich dein Programm nicht gut lesen.
Ich fange mal an:
> const int ledPin = LED_BUILTIN;
Eigentlich gut, und richtig so, wenn da nicht ein:
> #define ledB 13
folgen würde...
Ich rate da zu es einheitlich zu machen!!!
Entweder alle als defines oder als Konstanten.
Ich empfehle Konstanten.
Dann ist ist auch noch LED_BUILTIN in der Regel 13
Da steht dann also:
const int ledPin = 13;
#define ledB 13
Du verwendest die LED an Pin 13 doppelt.
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
//set the digital pin as output:
pinMode(13, OUTPUT); // ledPin durch 13 ersetzt
Du siehst die Unsinnigkeit des doppelten?
Wen du schon Symbole/Bezeichner für die LED verwendest, dann setze sie auch konsequent ein!
pinMode(ledR,OUTPUT);
pinMode(ledR,OUTPUT);
pinMode(ledB,OUTPUT);
----------
analogWrite(ledR,0);analogWrite(ledG, 255);analogWrite(ledB,0); //LED Grün an
Sowas schmeckt mir auch nicht sonderlich.
Alternativen:
Schön untereinander, eine Anweisung pro Zeile maximal.
(üblich)
analogWrite(ledR, 0);
analogWrite(ledG,255);
analogWrite(ledB, 0);
Verketten, mit dem Anweisungsverkettungsoperator.
(nicht so schön, weil es keine Notwendigkeit dafür gibt)
analogWrite(ledR,0),analogWrite(ledG, 255),analogWrite(ledB,0); //LED Grün an
Die beste Lösung:
Den LED Melderkram in eine Funktion/Klasse auslagern.
Sauber, wiederverwendbar, leicht zu lesen.
Danke Combie für die Tipps. Ich habe das gesagte angewendet.
Jetzt müsste der Sketch mehr nach deinem Geschmack sein.
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
int ledState = LOW;
const int ledR = 11;
const int ledG = 12;
const int ledB = 13;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;
//constants won´t change
const long interval = 1000;
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(ledR,OUTPUT);
pinMode(ledG,OUTPUT);
pinMode(ledB,OUTPUT);
//set the digital pin as output:
analogWrite(ledB,255);
}
void Lampegruen()
{
//Bestätigung zur erfolgreichen Funkanmeldung
analogWrite(ledR,0);
analogWrite(ledG, 255);
analogWrite(ledB,0);
}
void Lamperot()
{
analogWrite(ledR,255);
analogWrite(ledG,0);
analogWrite(ledB,0);
}
void loop()
{
Lampegruen();
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
//save the last time you blinked the LED
previousMillis = currentMillis;
}
//if the LED is off turn it on and vice-versa
if(ledB == LOW)
{
ledState = HIGH;
}
else
{
ledState = HIGH;
}
//set the LED with the ledState of the variable
digitalWrite(ledB, ledState);
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Messwerte
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*****************************************/
//Löschen der Messwerte
tempaussen = 0; //Der Wert für Temperatur wird genullt
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
Lamperot();
}
Ich weiß nicht genau, wie ich den Nachtwächter programmieren kann.
Ich freue mich über Anregungen.
Ich habe jetzt den Nachtwächter angepasst. Jetzt müsste dieser aber funktionieren.
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
int LedStatus = LOW;
int LedPin = 13;
unsigned long LED_timestore; //Variable Speicher für Systemzeit
const long interval = 1000;
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(LedPin, OUTPUT); //teilt dem Arduino mit, dass das ein Ausgang ist
}
void loop()
{
if (LedStatus == LOW)
{
if (millis() - LED_timestore>1000)
{
digitalWrite (LedPin, HIGH);
LED_timestore = millis();
LedStatus = HIGH;
}
}
else
{
if (millis() - LED_timestore>300)
{
digitalWrite(LedPin, LOW);
LedStatus = LOW;
}
}
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Messwerte
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*****************************************/
//Löschen der Messwerte
tempaussen = 0; //Der Wert für Temperatur wird genullt
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
}
Meine beiden Funkmodule verbinden sich nicht. Weiß jemand woran das liegt.
Beide suchen sich fleißig, aber können sich nicht finden.
Ich habe nochmal beide Sketch miteinander verglichen. Der Sendersketch mit Nachtwächter und den Sendersketch ohne Nachtwächter.
Am Werteauslesen und senden habe ich nichts geändert. Wie kann es sein, dass die Verbindung mit dem sketch ohne Nachtwächter eingegangen wird und die Verbidung mit dem Sketch ohne Nachtwächter nicht eingegangen wird.
Der einzige Unterschied liegt ja nur am Anfang des Cods, wo die Variablen definiert werden und am Anfang der Loop, wo die Nachtwächteraktion durchgeführt wird.
Ich freue mich über Tipps und Hinweise.
In den ersten Sketches wurde noch mit ein paar Sekunden Abstand gesendet.
Jetzt donnerst du das Zeugs ohne Gnade raus.
Ist das ein Unterschied?
Ja!
Ist er Relevant?
KA.
So, jetzt hat es geklappt.
Danke, Combie für den Hinweis. Die delays sind mir gar nicht aufgefallen.
Auf jeden Fall finden sich die Funkmodule wieder.
Ich musste den HC-05 noch mal mit den AT-Commands einstellen. Warum der manchmal so zickt weiß ich auch nicht. Der vertsellt sich immer: Er verliert "AT+ROLE=1" und "AT+CMODE=1" immer wieder.
Jetzt schickt der Sender sein Signal und der Empfänger schreibt die Zahlen fein säuberlich auf das Display. Nebenbei läuft der Nachtwächter und schaltet beim Sender die LED an Pin 13 alle 6 Sekunden an und aus.
Also, herzlichen Dank an alle die zu meinem Problem und zur Hilfe aller beigetragen haben.
Für alle, die ein ähnlichen Problem haben sollten, hier ein Sketch, der soweit funktioniert.
Zunächst der Sender mit Nachtwächter:
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
int LedStatus = LOW;
int LedPin = 13;
unsigned long LED_timestore; //Variable Speicher für Systemzeit
const long interval = 1000;
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
//Festlegen der Ein- und Ausgänge für die BL Verbindung
pinMode(LedPin, OUTPUT); //teilt dem Arduino mit, dass das ein Ausgang ist
}
void loop()
{
if (LedStatus == LOW)
{
if (millis() - LED_timestore>1000)
{
digitalWrite (LedPin, HIGH);
LED_timestore = millis();
LedStatus = HIGH;
}
}
else
{
if (millis() - LED_timestore>300)
{
digitalWrite(LedPin, LOW);
LedStatus = LOW;
}
}
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
//Senden der Messwerte
delay(3000);
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
delay(3000);
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
/*****************************************/
//Löschen der Messwerte
tempaussen = 0; //Der Wert für Temperatur wird genullt
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
}
Der Empfänger-Sketch sieht so aus:
#include <CmdMessenger.h> //Bibliothek zur BT Verbindung
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h> //LiquidCrystal_I2C Bibliothek einbinden
///////////Für das "°" Zeichen ////////////
byte degree[8] = {
B01110,
B01010,
B01110,
B00000,
B00000,
B00000,
B00000,
B00000
};
/////////////Für das "³" Zeichen ////////////////
byte hochdrei[8] = {
B00111,
B00001,
B00011,
B00001,
B00111,
B00000,
B00000,
B00000
};
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
#define ledfR 8
#define ledfG 9
#define ledfB 10
#define ledR 11
#define ledG 12
#define ledB 13
#define rxPin 3
#define txPin 4
float t = 0;
float f = 0;
float ti = 0;
float fi = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um welches Display es sich handelt
SoftwareSerial btSerial(rxPin, txPin);
CmdMessenger cmdMessenger {btSerial};
void setup()
{
Serial.begin(9600);
btSerial.begin(9600);
Serial << "Start: "<< __FILE__ << endl;
cmdMessenger.attach(Temperatur, [](){
t = cmdMessenger.readFloatArg();
Serial << "Temperatur " << t << " °C" << endl;
});
cmdMessenger.attach(Feuchtigkeit, [](){
f = cmdMessenger.readFloatArg();
Serial << "Feuchtigkeit " << f << " %" << endl;
});
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten
analogWrite(ledR,0);
analogWrite(ledG,0);
analogWrite(ledB,255);
}
void loop()
{
cmdMessenger.feedinSerialData();
//Berechnung der absoluten Feuchtigkeit
float RD = 461.5;
float e_sat = 611.2*pow(2.7183, (17.62*t/(243.12+t)));
float rho_sat = (e_sat*1000)/(RD*(t+273.15));
float rho_fi = rho_sat*(f/100);
//Displayausgabe der Temperatur Außen
if(t >= 9.95)
{
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(t, 1);
lcd.createChar(0, degree);
lcd.setCursor(5, 0);
lcd.write(0);
lcd.print("C");
}
if(t < 9.95)
{
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(1, 0);
lcd.print(t, 1);
lcd.createChar(0, degree);
lcd.setCursor(5, 0);
lcd.write(0);
lcd.print("C");
}
//Displayausgabe der Feuchtigkeit Außen
if(f >= 9.95)
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(f, 1);
lcd.print(" %");
}
if(f < 9.95)
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(1, 1);
lcd.print(f, 1);
lcd.print(" %");
}
//Displayausgabe der absoluten Feuchtigkeit Außen
if(rho_fi >= 9.95)
{
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(rho_fi, 1);
lcd.print(" g/m");
}
if(rho_fi < 9.95)
{
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(1, 2);
lcd.print(rho_fi, 1);
lcd.print(" g/m");
}
lcd.createChar(1, hochdrei);
lcd.setCursor(8, 2);
lcd.write(1);
//Auswertung der Luftfeuchtigkeit
if((f < 30) or (f > 70))
{
analogWrite(ledfR,255);
analogWrite(ledfG,0);
analogWrite(ledfB,0);
}
if((f >= 30) and (f < 40) or (f > 60) and (f <= 70))
{
analogWrite(ledfR,255);
analogWrite(ledfG,100);
analogWrite(ledfB,0);
}
if((f >= 40) and (f <= 60))
{
analogWrite(ledfR,0);
analogWrite(ledfG,150);
analogWrite(ledfB,0);
}
delay(5000); //5 Sekunden Pause
}
Falls es für die Sketche irgendwelche Verbesserungen gibt, bin ich dafür offen.
Ich wollte den Facelift von meinem Sender noch präsentieren. Jetzt wird nicht nur eine LED über die Nachtwächterfunktion an und aus geschaltet, sondern ich habe es jetzt hingekriegt, dass mit der Nachtwächterfunktion die Messwerte geschickt werden. Und zwar ganz ohne delay.
Das ist echt eine wichtige Funktion, wenn man den Mikrokontroller nicht untätig herumstehen lassen will.
Der Sendersketch sieht jetzt so aus:
#include <Streaming.h> //Bibliothek zur BT Verbindung
#include <SoftwareSerial.h>
#include "DHT.h" //DHT Bibliothek laden
enum Comand {
Temperatur = 1,
Feuchtigkeit = 2
};
unsigned long BT_timestore; //Variable Speicher für Systemzeit
#define rxPin 3
#define txPin 4
#define DHTPIN 2
#define DHTTYPE DHT22 //Es handelt sich um den DHT22 Sensor
SoftwareSerial btSerial(rxPin, txPin);
DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit "dht" angesprochen
void setup()
{
btSerial.begin(9600);
Serial.begin(9600);
dht.begin();
}
void loop()
{
float tempaussen = dht.readTemperature(); //Temperatur außen wird gemessen und gespeichert
float feuchteaussen = dht.readHumidity(); //Luftfeuchte außen wird gemessen und gespeichert
/*Senden der Messwerte mit Nachtwächterfunktion*/
if (millis() - BT_timestore > 10000) //Wenn 10 Sek. seit dem letzten Loopdurchlauf vergangen sind, dann senden
{
//Senden der Messwerte
btSerial << Temperatur << ',' << tempaussen << ';' << endl;
btSerial << Feuchtigkeit << ',' << feuchteaussen << ';' << endl;
Serial.println(tempaussen);
Serial.println(feuchteaussen);
BT_timestore = millis();
}
//Löschen der Messwerte
tempaussen = 0; //Der Wert für Temperatur wird genullt
feuchteaussen = 0; //Der Wert für Feuchte wird für die nächste Runde genullt
}
Falls jemand den Sketch noch sinnvoll weiter tunen kann, fänd ich interessant.
Da hätte ich nur eine Anregung zum Tunen:
In jedem, wirklich jedem, loop()-Aufruf liest Du Temperatur und Feuchtigkeit aus.
Die Mehrzahl davon verschwindet aber im Nirwana, weil sinnvollerweise das Senden nur alle 10s erfolgt.
Wie das geht, kannst Du aber leicht selbst herausfinden - deshalb kein Code.
Du meinst also, dass ich das Auslesen der Temp. und Feuchtigkeit auch in die if(millis)-Bedingung schreiben soll.
Perfekt danke. Auf die Idee bin ich nicht gekommen.
Ist wirklich nur eine kleine Änderung, aber total sinnvoll.
Danke