Arduino C/C++ Program funktioniert nicht richtig?
Hallo gutefrage community,
ich habe ein kleines Arduino Program geschrieben, habe aber jedoch ein kleines Problem und komm auch nicht selber auf eine Lösung.
Problem: Befehl soll ausgeführt werden während Knopf 1 oder Knopf 2 nicht gedrückt werden, jedoch funktioniert das Program nur, wenn ich die while schleife nur mit einem Knopf mache sobald ich den 2. mit reinnehme funktioniert nichts mehr. Ich lade unten auch noch ein Bild vom Program rein.
vielen Dank im Voraus für eure Hilfe,
viele Grüße
Xela
3 Antworten
Du solltest einmal schreiben was das Programm überhaupt machen soll. (Ich weiß es wird viel Text werden zum Beschreiben) Das Programm verstehe ich zwar aber es ist ziemlich unlogisch.
Ist dir zum Beispiel bewusst, dass du nur einmal in die If kommen kannst und wenn du einmal in der While bist, kommst du nie wieder in die If rein? Weil x hat dann irgendeinen Wert angenommen. Im nochmal in die if zu kommen, müsste x aber 0 sein. Da ich nicht einschätzen kann ob das alles so gewollt ist oder nicht, müsste ich (genau) wissen, was das Programm machen soll.
Es wäre gut, wenn du nächstes Mal den Code nicht als Bild hier reinstellst, sondern mit dem Codeeditor. Der ist da wo die 3 Punkte sind und dann das </> Zeichen. Man kann dann den vollständigen Code kopieren und in seine IDE stecken und auf Fehler checken.
Ich habe den Code gemäß deiner Beschreibung umgeschrieben. In so einem Kasten wie hier solltest du Code posten.
#include <Servo.h> //Die Servobibliothek wird aufgerufen. Sie wird benötigt, damit die Ansteuerung des Servos vereinfacht wird.
int button = 2;
int checkbutton = 4;
Servo myservo;
void setup(){
Serial.begin(9600);
pinMode(button, INPUT_PULLUP);
pinMode(checkbutton, INPUT_PULLUP);
myservo.attach(9);
myservo.write(0); //Servo in Grundposition bringen.
while (digitalRead(button) == HIGH){ //solange der Taster nicht gedrückt ist, warte
delay(50);
Serial.println("Erste while");
}
myservo.write(180); //Position ansteuern mit dem Winkel 180°
delay(1000); //warten bis das Servo die Position erreicht hat.
while (digitalRead(button) == HIGH){ //solange der Taster nicht gedrückt ist, warte
delay(50);
Serial.println("Zweite while");
}
//Warte bis Button wieder losgelassen wurde
delay(300);
//Langsam Zurückfahren
for(int i = 180; i > 0; i--){
Serial.println(i);
delay(40); //Je höher die Zahl, desto langsamer fährt der Motor zurück
myservo.write(i); //Position ansteuern mit dem Winkel 180°
//Bewegung abbrechen, wenn Button oder Checkbutton gedrückt wird
if (digitalRead(button) == LOW || digitalRead(checkbutton) == LOW){
break; //for Schleife verlassen
}
}
Serial.println("PROGRAMM ENDE");
}
void loop(){}
Vielen Dank! Das Programm funktioniert jetzt super. Ich würde nur auch gerne verstehen was bei mir falsch war und wieso das Programm bei mir nicht funktioniert hat da ich, wie man vielleicht merkt noch ein ziemlicher Anfänger bin und gerne aus meinen Fehlern lernen würde. Wäre super wenn du mir das noch erklären könntest. Ansonsten nochmals vielen Dank!
Gibt es eine Fehlermeldung vom Compiler?
Wenn das Programm mit
while (digitalRead(checkbutton) != LOW) {
...
}
funktioniert, mit
while (digitalRead(checkbutton) != LOW || digitalRead(button) != LOW) {
...
}
aber dann nicht mehr, ist der naheliegendste Grund, dass mit button irgendwas nicht stimmt. Allerdings ist er in der übergeordneten Abfrage eingebunden, sollte es also ein Problem damit geben, sollte er nicht bis zur Schleife kommen.
Trotzdem verstehe ich den Sinn von
digitalRead(button) != LOW
nicht. Die While Schleife könnte nie von dem Button getriggered werden, da der else if Zweig nur betreten wird, wenn button == LOW ist.
Also nur wenn du vorher den anderen Button (checkbutton) drückst und danach quasi simultan den button, könnte dieser danach die While-Schleife füttern. Ich bezweifle, dass es möglich ist, beide Knöpfe gleichzeitig zu drücken, oder hast du Hotkeys dafür definiert?
Vielen Dank für deine Antwort! Der Compiler hat jedoch keine Fehlermeldung gegeben, und die Buttons habe ich auch schonmal alle durch getauscht. Ich habe aber zum Glück jetzt ein anderes Programm das funktioniert. Trotzdem nochmal vielen Dank für deine Antwort!
Ich habe deinen Code in einem Programmablaufplan nachgebaut.... aber so nichts finden können.
Du hast geschrieben der Fehler tritt auf, wenn du einen zweiten Taster in die While mit aufnimmst. Deine While ist:
while(digitalRead(checkbutton) != LOW) || digitalRead(checkbutton) != LOW)){...
Das heißt die Schleife wird ausgeführt wenn:
Button nicht gedrückt ODER Checkbutton nicht gedrückt.
Beides ist von Natur aus erst mal True. Die Schleife wird ausgeführt wenn eins von beiden True ist. Es würde da stehen:
while(True || True){...
Jetzt drückst du einen Taster, z.B. den Checkbutton. Laut deiner Bedingung wird dann ein Glied zum False. Es steht dann da:
while(False || True){...
Jetzt aufpassen. Die Schleife wird trotzdem ausgeführt! denn es ist ja noch ein Glied True.
Hättest du beide Taster gleichzeitig gedrückt, dürfte die Schleife unterbrochen werden und der Servo hält an.
________________
Jetzt der Unterschied zu meinem Code:
if (digitalRead(button) == LOW || digitalRead(checkbutton) == LOW){
Wenn LOW dann ist der Taster gedrückt, wenn HIGH ist er nicht gedrückt. Bei mir läuft der Motor bereits so wie bei dir auch. Die Taster sind jetzt die ganze zeit nicht gedrückt, also HIGH beide. Deshalb steht in der if Bedingung:
if(false || false) {....
Wenn jetzt ein Taster gedrückt wird, also LOW wird, dann wird ein Glied true. Es steht dann
if(true || false) {....
Da nun ein Glied true ist wird bei der ODER Bedingung die if ausgeführt. Wird meine if ausgeführt, wird die for unterbrochen mit dem break; Befehl. Der Servo stoppt.

Das Programm soll sobald "button" gedrückt wird einen Servo Motor auf die Position 180 setzen und beim 2 drücken des "button" den Servo Motor langsam wieder in die Ursprungsposition setzen, bzw. solange zurück fahren, bis entweder "button" oder "checkbutton" gedrückt wird. Das Programm funktioniert ohne das "oder" (also wenn nur "while (digitalRead(checkbutton)!= LOW)" und nicht " while (digitalRead(checkbutton)!= LOW || digitalRead(button) != LOW)") super. Bezüglich der anderen Hochlade Möglichkeit muss ich gestehen, dass ich nicht ganz verstehe was du meinst. Auf jeden fall schonmal Danke für die Antwort.
PS: Ich hoffe du verstehst was ich meine, ich bin nicht gerade der beste wenn es um erklären geht.