Hallo lieb Community!
Ich habe Probleme mit meinem HC-05 an einem Arduino R3 Clon
Angeschlossen ist er an:
3,3V
GND
TX -RX
RX -TX
Verbindung über Bluetooth am Mobiltelefon (Xperia XZ) problemlos.
Er empängt auch den programmierten Befehl.
Abbbbber.... er wiederholt den befehl so lange, bis er einen anderen bekommt.
Und dann wiederholt er den neuen Befehl, selbst wenn Bluetooth auf dem Mobiltelefon danach abgeschaltet ist.
Was ich schon versucht habe:
Mobiltelefon Neustart.
Bluetooth am Mobiltelefon neu verbinden.
Verschiedene Apps.
Anderen HC-05
Anderen Arduino-Clon
Die App ist programmiert auf: On Press = 1 On release = 0
Wie verhindere ich, dass der HC-05 ständig weiter sendet?
char blueToothVal; //Werte sollen per Bluetooth gesendet werden
char lastValue;
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()) //wenn Daten empfangen werden...
{blueToothVal=Serial.read();//..sollen diese ausgelesen werden
}
if (blueToothVal=='0') //wenn das Bluetooth Modul eine „1“ empfängt..
{ Serial.println("0");
}
if (blueToothVal=='1') //wenn das Bluetooth Modul eine „0“ empfängt..
{
Serial.println("1");
}
if (blueToothVal=='2') //wenn das Bluetooth Modul eine „2“ empfängt..
{
Serial.println("2");
}
if (blueToothVal=='3') //wenn das Bluetooth Modul eine „3“ empfängt..
{
Serial.println("3");
}
if (blueToothVal=='4')
{
Serial.println("4");
}
if (blueToothVal=='5')
{
Serial.println("5");
}
if (blueToothVal=='6')
{
Serial.println("6");
}
if (blueToothVal=='7')
{
Serial.println("7");
}
if (blueToothVal=='8')
{
Serial.println("8");
}
if (blueToothVal=='9')
{
Serial.println("9");
}
}
bluetooth.ino (1.02 KB)
Du hast in deinem Sketch nirgends drin, dass das dann nur einmal ausgeführt werden soll.
Da musst du einen Merker(Flag) setzen oder nur ausführen, wenn sich das empfangene Byte verändert hat. Oder das empfangene Byte nach der ersten Aktion auf einen default Wert setzen, bei dem dann halt nix gemacht wird.
Und von einem Ultraschallsensor sehe ich im Sketch auch nix.
Und setz den Sketch bitte für bessere Lesbarkeit schön formatiert in Code-Tags
Also ich habe mal da rein geschaut. Er macht genau das was du programmiert hast.
Wenn einen bluetoothval==0 ist gibt er 0 am seriellen port aus. Der inhalt des bluetoothval bleibt solange gleich wie er nix neues empfängt also schreibt er auch solange was raus. Du musst die also merken das einmal was ausgegeben worden ist und dann die Augabe stoppen mit einer Hilfsvariablen. und erst wenn was neues kommt "Altterwert != neuerWert" und wieder einmalig eine Ausgabe
Gruß
DerDani
ElEspanol:
Du hast in deinem Sketch nirgends drin, dass das dann nur einmal ausgeführt werden soll.
Da musst du einen Merker(Flag) setzen oder nur ausführen, wenn sich das empfangene Byte verändert hat. Oder das empfangene Byte nach der ersten Aktion auf einen default Wert setzen, bei dem dann halt nix gemacht wird.
Und von einem Ultraschallsensor sehe ich im Sketch auch nix.
Und setz den Sketch bitte für bessere Lesbarkeit schön formatiert in Code-Tags
Verzeihung, das mit dem Code-Tags hatte ich glatt vergessen.
Wird sofort geänder.
Es sind keine weiteren Befehle drin, weil es sich im original um einen sehr großen Sketch handelt, den ich "runtergebrochen" habe, um ihn hier im Forum einfacher lesbar zu machen.
Hallo,
probiere mal, einlesen und behandeln getrennt, vielleicht Vorlage für weiteren Ausbau, wenn mehr wie nur ein Zeichen gesendet werden soll. Solange derzeit Zeichen im seriellen Empfgangspuffer sind werden diese alle einzeln behandelt. Vielleicht solltest du dich auch in Dinge wie Nullterminator, Endezeichenerkennung, atoi(), strcmp() und deren Verwandte einlesen. Könnte vielleicht noch benötigt werden.
char blueToothVal; // Werte sollen per Bluetooth gesendet werden
char lastValue;
void setup() {
Serial.begin(9600);
}
void loop()
{
handle_serial();
}
/* ****** Funktionen ****** */
void handle_serial()
{
if (read_serial() ) {
switch (blueToothVal) {
case 0: Serial.println("0");
break;
case 1: Serial.println("1");
break;
case 2: Serial.println("2");
break;
default: Serial.println("default");
}
blueToothVal = '\0'; // ist vielleicht z.Z. überflüssig?
}
}
bool read_serial()
{
if (Serial.available() ) {
blueToothVal = Serial.read();
return true;
}
return false;
}
Ich habe es wirklich versucht, aber ich komme nicht dahinter.
Ziel:
Mit dem Bluetooth- Modul HC-05 eine ZWEISTELLIGE Zahlenfolge empfangen, die dann etwas auslößt.
z.B. Arduino empfängt "01" - Licht geht an.
Bei einstellig kein Problem. Aber wie bei zweistellig?
Mit den Empfangenen Daten ein Array befüllen (sind das dann Char?) und das umwandeln (in ein INT?) und damit weiter arbeiten?
Ich komme einfach nicht dahinter....
:-[
Das musst du machen wie bei seriell. Idealerweise mit Endekennung, bsp. ascii 10 oder 13
ElEspanol:
Das musst du machen wie bei seriell. Idealerweise mit Endekennung, bsp. ascii 10 oder 13
Ähm... jaha... bekomme ich noch Einen Tipp wie guckt ganz lieb
Google kaputt?
Hab was gefunden Link post #14 ist das Grundgerüst. Lies aber den ganzen Thread.
Ansonsten such mal nach „Arduino seriell blockierungsfrei einlesen“ oder so
Hallo,
du musst ein Endezeichen mitsenden, z.Bsp. "Newline", dann liest du alles was kommt in ein char array ein bis das Newline Zeichen kommt, dann weißt du jetzt ist das Ende der Übertragung gekommen, danach wertest du alles aus, wandelst um oder machst sonst irgendwelche Dinge mit dem Inhalt des char array buffers.
Schau dir einmal Beitrag 13 hier drin an
http://forum.arduino.cc/index.php?topic=408744.msg
Hi
Habe jetzt die verlinkten Threads nicht durchgelesen, platze hier trotzdem mit einer Möglichkeit herein:
- beim Start setzt Du Deine Zahl_Variable auf Null
- beim Zahl Einlesen prüfst Du, ob eine Zahl eingelesen wurde, ja -> Zahl_Variable x 10 + Zahl (bei ASCII ggf. -0x30, da '0' 0x30 ist)
- wenn ein CR/LF (=Zeilenende) erkannt wurde, hast Du Deine Zahl in Zahl_Variable, kopierst Diese in Gelesene_Zahl und setzt Zahl_Variable wieder auf Null
- nun kannst Du mit Gelesene_Zahl Deinen Code abfrühstücken. Wenn Du damit fertig bist, Gelesene_Zahl=0, weil wir 'fertig' damit sind
MfG
@postmaster-ino: Der TE soll es doch besser gleich so lernen, dass er es in Zukunft universell verwenden kann. Und Fehlerbehandlung, so er denn soweit kommt, ist auch einfacher.
Hi
Bei dem verlinkten Beispielcode dort in #14 bekommt Er aber "14" in Sein char-Array, statt 14.
Ok, da hat auch direkt Buchstaben ect.pp. mit erschlagen.
Auch wird der Arduino eine Funktion bereit halten, womit man von der "14" wieder auf eine 14 kommt, wenn man Diese braucht.
Somit ist Dein Ansatz universeller.
Ob der Fehlerbehandlung weiß ich noch nicht so recht, aber hier oder da muß man falsche Zeichen abfangen.
MfG
Also jetzt im Moment hab ich es noch nicht durchschaut, mein Hirnschmalz für heute ist wohl schon verbraucht.
Morgen versuche ich es mit frischer Energie nochmal! 
Ausgeschlafen klappt das Denken zumindest eine Spur besser.
Ich komme noch nicht zum Ausprobieren, aber wie wäre dieser Ansatz?
int index = 0; // Die "Position" im Array. Position 1 = Ziffer 0
int befehl = 0; // int zur Weiterverarbeitung
char bluearray[3]; // Array aus zwei ASCII- Zeichen mit einem "Zusatzplatz" für die Null
void setup() {
Serial.begin(9600); //serieller Monitor starten und auf Schnarchrate einstellen
}
void loop() {
if(Serial.available())
{
char ch = Serial.read(); //Empfangenes unter "ch" speichern
if(index <2 && isDigit(ch)){ // Bist du ein ASCII- Zeichen und ist die Kette noch nicht voll?
bluearray[index++] = ch; // Ja: ASCII-Zeichen zum String hinzufugen und Index hochzählen
}
else // Puffer voll oder nicht 1-9
{
bluearray[index] = 0; // String mit einer 0 in Index 2 (Platz3) abschließen
befehl = atoi(bluearray); // String mit atoi in int-Wert umwandel (Einfach so? Oo So einfach?)
index = 0;
Serial.print("Befehl");
Serial.println(befehl);
}
}
}
Hallo,
du liest alles ein was kommt ohne jede Endeerkennung?
Im Grunde das was aus den Links entstehen sollte bzw. dort schon steht.
const byte SERIAL_BUFFER_SIZE = 3;
char serialBuffer[SERIAL_BUFFER_SIZE];
void setup() {
Serial.begin(9600);
}
void loop() {
handle_serial();
}
bool read_serial()
{
static byte index = 0;
if (Serial.available() > 0) {
char c = Serial.read();
if(c == '\n') { // 'NL' Endeerkennung
serialBuffer[index] = '\0'; // Null Terminierung
index = 0;
return true;
}
else if (c >= 32 && index < SERIAL_BUFFER_SIZE-1) { // alles lesen was kein Steuerzeichen ist
serialBuffer[index++] = c;
}
}
return false;
}
void handle_serial ()
{
if (read_serial() ) {
int value = atoi(serialBuffer); // string to int
//Serial.print(F("eingelesener Wert: "));
//Serial.println(value);
memset(serialBuffer,'\0',sizeof(serialBuffer)); // seriellen Buffer löschen
}
}
Lieber Doc!
So weit wie in deinem Code bin ich noch lange nicht.
Da sind so viele Befehle drin, die ich noch lernen sollte und noch nicht kenne.
Ich habe versucht, es mit "meinen Worten" zu erklären und so weit, wie ich es bisher verstanden und verinnerlicht habe.

Hallo,
das macht nichts, jeder fängt einmal an. Das beruht auf dem "Gerüst" von Serenifly.
Es wird immer ein Byte vom internen Buffer abgeholt bzw. von dort eingelesen. Dieser interne Ringbuffer der seriellen Lib hat Platz für 63 Zeichen. Dort lande alle Bytes die von der seriellen Hardwareeinheit ankommen. serial.read holt alle Zeichen einzeln von dort ab. Wenn der "interne Buffer" ausgelesen ist liefert serial.available den Wert 0 zurück.
Die ausgelesenen Zeichen landen im char c. Dann wird geprüft ob es das Endeerkennungszeichen ist. In dem Fall '\n'. Wenn es das ist wird noch der Nullterminator angehangen und das einlesen mit true beendet. Damit kann die Auswertung beginnen.
Wenn nicht true, dann wird das Zeichen vom Buffer geprüft ob es kein Steuerzeichen ist und ob der Buffer noch nicht voll ist. Wenn okay, landet das eingelesene Zeichen im char array, also im "seriellen Buffer".
Der gesamte Ablauf ist nicht blockierend.
Gehe Zeile für Zeile durch, irgendwann macht es Klick.
Doc_Arduino:
Hallo,
das macht nichts, jeder fängt einmal an.
Danke! 
Doc_Arduino:
Hallo,
Es wird immer ein Byte vom internen Buffer abgeholt bzw. von dort eingelesen. Dieser interne Ringbuffer der seriellen Lib hat Platz für 63 Zeichen. Dort lande alle Bytes die von der seriellen Hardwareeinheit ankommen. serial.read holt alle Zeichen einzeln von dort ab. Wenn der "interne Buffer" ausgelesen ist liefert serial.available den Wert 0 zurück.
Wenn - sagen wir mal - drei Zeichen im Buffer sind und alle drei sind abgeholt, dann "schaltet" sich das Auslesen "ab".
if (Serial.available() > 0)...
Habe ich das richtig verstanden?
Und wenn mehr Zeichen im Ringbuffer stehen, dann holt er auch mehr Zeichen ab.
Deswegen ist es so wichtig, ein Endzeichenerkennung drin zu haben?
Weil das Programm sonst im Buffer nicht weiß wo Anfang und Ende ist?
Hallo,
genauso läuft das ab. Wenn der Buffer leer ist wird nichts mehr abgeholt und deswegen die if Abfrage quasi "übersprungen".
Eine Endezeichenerkennung bzw. Übertragungsendeerkennung ist immer notwendig sobald mehr wie ein Zeichen übertragen werden soll. Sonst weiß man nicht wann sein Datenpaket fertig übertragen wurde. Im internen Buffer können ja auch mehrere Datenpakete stehen, die sind dann alle getrennt auslesbar wiederum erkennbar am "Endezeichen". Der Null-Terminator hat damit an der Stelle noch nichts zu tun. Der sorgt dafür das alle Lesefunktionen an ihm enden. Das ist jedoch nicht weniger wichtig. Sonst wird im Nirwarna weitergelesen ggf. auch geschrieben was böse enden kann. Deswegen muss die eigene char array Größe zum größtmöglichen Datenpaket passen und am Ende vom einlesen mit dem Null-Terminator versehen werden. Das sorgt für eine gewisse Grundsicherheit.