Go Down

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

michael_x

Quote
Muss ich T und F vorher irgendwie als "int" oder "char" oder sonst was deklarieren??
Ja, hast du. Als char.

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

combie

#31
Apr 09, 2020, 12:18 pm Last Edit: Apr 09, 2020, 12:19 pm by combie
Ich habe große Schwierigkeiten mit dem Code!


Code: [Select]

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:
Code: [Select]
char kennung = 'T';
Aber nicht unbedingt so.



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


Code: [Select]
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?
Code: [Select]
lcd.print(btData,1);     //Die Feuchtigkeit auf das Display schreiben
lcd.print(" %");          //% hinter die Feuchtigkeit setzen


Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

michael_x

Quote
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üherTM hat man Konstanten gerne Namen nur mit Großbuchstaben gegeben, um sie von Variablen zu unterscheiden.

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

combie

#33
Apr 09, 2020, 01:32 pm Last Edit: Apr 11, 2020, 01:34 pm by combie
Quote
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


Quote
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.
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

wno158

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 gefunden - vielleicht hat combie noch was besseres.

Quote
Hier ist der Sketch vom Slave, der macht Probleme :(
Das ist dann kein Wunder.

Die Erläuterungen zu readBytesUntil() finden sich hier.

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).
Gruß Walter

combie

Hier ist meine Quelle
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. ---






Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

combie

#36
Apr 09, 2020, 10:23 pm Last Edit: Apr 09, 2020, 10:30 pm by combie
Ein einfacher Sender:

Code: [Select]

#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:
Code: [Select]
#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 *
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

wno158

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
Gruß Walter

combie

#38
Apr 09, 2020, 10:56 pm Last Edit: Apr 09, 2020, 10:58 pm by combie
Quote
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.
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

adruinoboy

Danke für die vielen Hinweise.
Ich muss das erstmal verarbeiten. Danke auch für das Beispiel. Ich denke, dass wird mir helfen.

adruinoboy

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:

Code: [Select]

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

Code: [Select]

#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();
}

adruinoboy


Hier ist meine Quelle
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.

combie

#42
Apr 10, 2020, 09:46 am Last Edit: Apr 10, 2020, 11:54 am by combie
Quote
#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.


Quote
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.
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

adruinoboy

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?

combie

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....
Der Verstand, und die Fähigkeit ihn zu gebrauchen, sind zweierlei Fähigkeiten.

Go Up