Go Down

Topic: Senden von Zahlenwerten über HC-05 und HC-06 (Read 2690 times) previous topic - next topic

adruinoboy

Apr 02, 2020, 07:23 pm Last Edit: Apr 02, 2020, 08:55 pm by adruinoboy
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:

Code: [Select]

#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:
Code: [Select]

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

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

my_xy_projekt

Bitte beherzige Tommy56.

Zu Deinem Code am Empfänger:
Quote
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...

combie

Quote
Ich bin noch nicht fortgeschritten und bitte um kleinschrittige Anweisen
evtl. möchtest du ja die CmdMessenger Lib einsetzen.
Säge kein Sägemehl.

adruinoboy

#4
Apr 02, 2020, 08:59 pm Last Edit: Apr 02, 2020, 09:00 pm by adruinoboy
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

Serenifly

#5
Apr 02, 2020, 09:02 pm Last Edit: Apr 02, 2020, 09:07 pm by Serenifly
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/parseint/

Quote
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()

adruinoboy

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

Serenifly

#7
Apr 02, 2020, 09:15 pm Last Edit: Apr 02, 2020, 09:17 pm by Serenifly
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

my_xy_projekt

Quote
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.


adruinoboy

#9
Apr 02, 2020, 09:51 pm Last Edit: Apr 02, 2020, 10:09 pm by adruinoboy
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:
 
Code: [Select]

#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
  }
}

my_xy_projekt

Ich habe meinen Code etwas verändert, jetzt liest er die ganze Zahl auf einen Schlag aus. Sehr gut.
Na geht doch ;)

Quote
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:
Code: [Select]

 btSerial.println(btData);


Schau in der Referenz nach, was .println macht und was .read macht.

Serenifly

Das Gegenteil ist offensichtlich der Fall wenn da zu viel am Ende steht

adruinoboy

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

Serenifly


adruinoboy

#14
Apr 03, 2020, 10:53 pm Last Edit: Apr 04, 2020, 08:58 am by adruinoboy
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.

Go Up