Hallo,
Kann mir wer weiterhelfen?
Ich habe noch keine Erfahrung mit dem HC-05 Modul. Ich wollte erstmal ein gefundenes Programm ausprobieren nur erhält mein Arduino aber immer eine 0 obwohl ich mit der App Bluetooth Terminal nichts sende. Was könnte das Problem sein?
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
Bitte gehe in der IDE auf BEARBEITEN - FÜR FORUM KOPIEREN
und füge den Code hier ein, damit man eine Grundlage hat.
Ausgaben aus dem Seriellen Monitor kannst Du markieren und mit STRG-C kopieren und hier in Codetags (das Symbol </> im Foreneditor) einfügen.
Einen Kurzzeiler der dir die dauernden Ausgaben unterbindet und nur was ausgibt, wenn (irgendein) BT-Signal (nicht) kommt, wäre dieser geratene Versuch.
#include <SoftwareSerial.h>
SoftwareSerial myBlue(2, 3);
bool flag;
const byte ledPin = LED_BUILTIN;
void setup()
{
Serial.begin(9600);
Serial.println(F("Start..."));
myBlue.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop()
{
if (myBlue.available())
{
if (flag == false)
{
digitalWrite(ledPin, HIGH);
Serial.println(F("LED go ON"));
flag = true;
}
}
else if (flag == true)
{
digitalWrite(ledPin, LOW);
Serial.println(F("LED go OFF"));
flag = false;
}
}
Wie man an diesem Beispiel sieht, geht es ohne if.
Nicht ohne Entscheidungen, aber ohne if.
Du kennst meine Libs, meinen Stil...
Natürlich finden sich da auch if!
Aber meist in irgendwelchen Methoden vergraben.
Gegen notwendige Entscheidungen mag ich nichts sagen... sie müssen getroffen werden.
Beispiel, beim TO finden wir dieses: if (MyBlue.available())
Bei mir nicht.
Denn die Zeile ist flüssiger als Wasser! Überflüssig.
Mit der Zeile handelt man sich eine Schachtelungstiefe ein.
Eine unnötige.
Der TO ist darüber gestolpert. So auch viele weitere Anfänger, bei sowas in straucheln geraten. Sieht man quasi täglich hier im Forum.
Es scheint so logisch einfach zu sein. Man übt das und dann denkt man nur noch im Kontrollfluss.
Ich kann das auch....
2 Ebenen!
Vielleicht 3.
Spätestens bei 5 Ebenen, male ich mir Wahrheitstabellen. Denn die Komplexität wächst exponentiell.
Wenn dann noch komplexe Bedingungen ins Spiel kommen, wird es extrem.
Es ist nicht nur meist überflüssig, das zu tun, sondern es ist auch zeitraubend beim debuggen und in der Wartung.
Je flacher die Programmstruktur, desto einfacher zu durchblicken.
Nochmal:
Das denken im Kontrollfluss, führt fast zwangsläufig zu solchen Entscheidungskaskaden.
Wenn man die Qualität eines Programms/Programmierers daran festmacht, wie tief die Entscheidungsbäume verschachtelt sind, dann bin ich kein guter Programmierer!
Denn meine Programme sind bevorzugt flach.
Schlusswort:
Ich halte es für wichtig, das if kapiert zu haben!
Mir ist die Notwendigkeit des if bewusst.
Aber dennoch, nur weil man begriffen hat, wie ein Hammer funktioniert, wird doch nicht alles und jedes dadurch zu einem Nagel.
ich halte fest. Der Entscheidungsbaum entweder mit if Kaskade oder switch case. Geht nicht anders.
Beispiel, beim TO finden wir dieses:
`if (MyBlue.available())`
Bei mir nicht.
Schweifst du ab? Wie kann man das hier anders lösen? Wir reden hier nicht von dem was man in eigenen Libs schreiben könnte. Sondern vom jetzt und hier. Ich sehe hier keine andere Möglichkeit.
Wir reden über unnötige if Konstruktionen!
Dazu gehört auch dieses if.
Das Beispiel in #6 zeigt ganz deutlich eine Alternative auf.
Obwohl ich diese auf dem Präsentierteller geliefert habe?
Interessant!
Jetzt und hier findet sich in xxx::read() schon eine solche Abfrage, ob Zeichen/Bytes vorliegen.
Da muss man nicht xxx::available() aufrufen und getrennt nochmal auswerten.
und noch mal klarer:
Stream.read():
Rückgabewert
Das erste Byte der verfügbaren Daten (oder -1, wenn keine Daten verfügbar sind).
Also genau das, was wir für diese Problemstellung brauchen!
Stream.available():
Rückgabewert
Die Anzahl der zum Lesen verfügbaren Bytes
Die Anzahl der Bytes interessiert uns nicht für diese Problemstellung.
Also muss sie auch nicht berechnet und ausgewertet werden.
_
also ich würde ja eher gegen ein '0' oder ein '1' prüfen in der Annahme dass ein '0' oder '1' von der App gesendet wird und das als Schaltsignal herhalten soll.
Aber ist eh egal, so wie es aussieht meldet sich @hdjg eh nicht mehr und ohne Mitarbeit vom TO ist das eh nur rumgerate.
Würde ich auch vermuten.....
Weiß es aber nicht. Das liegt im Schatten.
Habe drum extra das "Unerwartetes Zeichen: " eingeführt.
Das hätte solche Dinge gemeldet, wie auch Steuerzeichen, z.B. Zeilenenden usw.
Auch erwarte ich, dass es sich nicht nur um 1 zu schaltendes Element dreht. Also eher sowas wie LED1=0\r\n gesendet wird. Dann wird es nötig einen kleinen Parser zu bauen....
Der Mittelweg, so wie er in C# und Co. empfohlen wird, ist:
if(!MyBlue.available())
return;
If-Statement ohne folgende Verschachtelungstiefe.
Schlagen so auch zahlreiche Compiler vor ein Statement zu negieren und damit die Ebenen zu reduzieren.
Wo das nicht geht, fehlt eine Auslagerung in eine Funktion.
der Punkt ist imho der:
warum will man auf available == 0 prüfen, wenn die Information ("keine Daten") auch beim ersten Read mit == -1 zur Verfügung steht.
Tendenziell würde ich nur einen Funktionsaufruf machen.
Weil man dann gegebenenfalls mit read gleich ein char oder byte lesen kann.
Weil logisch gesehen die -1 etwas völlig anderes ist als ein 'x'
Eigentlich gebe ich combie ja gern (?) Recht, aber manchmal kann auch ein if mehr das Verständnis erleichtern.
Es soll Menschen geben, die --sauber eingerückt-- zwei ineinander geschachtelte Blöcke überblicken können, sich aber schwertun, zig veschiedene überladene Zuweisungsoperatoren zu unterscheiden
naja das wird eher zur Glaubensfrage. Was ich jedoch als unsauberen Stil ansehe ist ein case mit return abzubrechen. Da gehört imho auch ein break hin.
Und wegen der Prüfung auf 0. Ich hatte vor langer Zeit einmal gelesen das der Compiler auf 0 schneller prüfen kann im Vergleich zu irgendeinem anderen Wert. Deswegen sieht man das häufig auch wenn es erstmal einen Knoten ins Hirn macht.
Und wenn man es wie ihr nur mit read() macht, dann hilft der Lesbarkeit folgendes auf die Sprünge.
const int incomingByte = myBlue.read();
switch(incomingByte)
{
case -1 : break; // nix gekommen
case '0' : digitalWrite(ledPin, LOW); Serial.println(F("LED go OFF")); break;
case '1' : digitalWrite(ledPin, HIGH); Serial.println(F("LED go ON")); break;
default : Serial.print(F("Unerwartetes Zeichen: ")); Serial.println(einByte);
}
Eine Zuweisung im Ausdruck sieht schon irgendwie blöd aus. Die Hilfsvariable muss man hierfür sowieso definieren. Ich würde sie aber konsequenterweise ganz weglassen und read() alleine im Ausdruck auswerten ohne nochmalige Ausgabe im default Zweig.
Aber wie gesagt, ist alles eine Glaubensfrage. Soll jeder machen wie er es mag.