HC-05 gibt immer eine 0 aus


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?

Gruss

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.

mfg ein Moderator.

Soll ich jetzt wirklich das Programm vom Bild abtippen, um eine vernünftige Programmänderung vorzuschlagen?
Oder auch nur zu testen?

Nee, sorry, das mache ich nicht.

Übrigens , die Null bekommst du, weil die (globale) Variable automatisch mit Null initialisiert wird.

1 Like

Mal hier lesen

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

Das kann man wenigstens bearbeiten!
Und testen...

Alternativvorschlag:

#include <SoftwareSerial.h>
SoftwareSerial myBlue(2, 3);

const byte ledPin = LED_BUILTIN;

void setup()
{
  Serial.begin(9600);
  myBlue.begin(9600);
  Serial.println(F("Start..."));
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  int einByte;
  switch(einByte = myBlue.read())
  {
    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);
  }
}

Habe ich schon mal gesagt, dass ich verschachtelte if, oder solche Kaskaden, wegen ihrer Unübersichtlichkeit, nicht mag?

Ich kann auch ohne, aber mir war (wieder einmal) so, einen Level basierend auf die Ausgangslage zu finden.
Damit wars dann aber auch.

Du hast es das ein oder andere mal erwähnt. Ja. :stuck_out_tongue_winking_eye:

Ja, ich bin ein Planhirn.
Kann/Will nicht tief denken.
:japanese_ogre: Drum auch immer wieder die gleichen Mantras :japanese_ogre:

Hallo,

Wie will man sonst auf mehrere verschiedene Werte prüfen und gezielt irgendwelche Ausgaben machen?

Um die Übersichtlichkeit zu erhöhen formatiere ich das in Tabellenform. Würde dann in dem Fall so aussehen. Oder mit Streaming etwas kürzer.

switch(einByte = myBlue.read())
{
  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);
}

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.

Hallo,

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

jeder wie er mag.

ich finde das übersichtlicher:

switch(einByte = myBlue.read())
{
  case -1 : return; // 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);
}

als ein ein extra if:

if(!MyBlue.available()) return;
switch(einByte = myBlue.read())
{
  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);
}

Hallo,

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. :wink:

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.