Frage Arduino counter + button

Hey ich habe mal ne Frage:
Ich habe den anfang eines sketches geschrieben, welcher einen counter einen button und einen led enthält:
int button = 8;
int x = 0;
int ledPin = 13;

void setup (){
pinMode(button, INPUT);
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
ledPin == LOW;

}

void loop(){
button = digitalRead(8);
if ( button == HIGH){
delay(10);
x ++;
Serial.print(x);
Serial.print("\n");
}
else( button == LOW);{
delay(1);
}

jetzt möchte ich, dass der arduino immer nur die Zahl liest, auf der der counter steht. Ich möchte dass der arduino für verschidene zahlenwerte des counters verschiedene aufgaben ausfühtr.
ZB:
x == 200
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
und für
x == 230
digitalWrite(ledPin, HIGH);
delay(5000);
digitalWrite(ledPin, LOW);
delay(5000);
oder eine weitere led anschalten.

wär cool wenn ich ne hilfreiche antwort kriegen könnte :slight_smile: danke schonmal im vorraus :slight_smile:

Hallo und willkommen im Forum,

bitte verwende für das Posten von Code immer die "code"-Tags, sonst wird es unübersichtlich.
Weiterhin ist es gut, erstmal einen vollständigen Sketch zu haben, auch wenn der noch nicht alles macht was Du evtl. willst. Du siehst aber schonmal Fehler in der Syntax und kann schauen ob sich das Programm auf den Arduino übertragen läßt. Außerdem ist es besser wenn man schrittweise vorgeht, sonst hat man am Ende ein Programm mit vielen Funktionen das aber nicht funktioniert und man nicht weiss wo man anfangen soll mit suchen.

Nun zu Deinem Programm. Der Anfang ist schonmal gar nicht schlecht. Du wirst aber eine zusätzliche Variable brauchen, oder den Button-Pin per #define festlegen müssen.
Du verwendets die Variable "button" nämlich einmal, um das Pin zu speichern, an dem der Button angeschlossen ist und gleichzeitg um den gelesenen Wert zu speichern, das wird nicht funktionieren.

Was genau meinst Du mit:

jetzt möchte ich, dass der arduino immer nur die Zahl liest, auf der der counter steht

Die Lösung hast Du ja selbst eigentlich schon angegeben? (x == 200 ...)
Das problem sind allerdings die "delay(5000)..." Aufrufe. Hier bleibt Dein Programm jedesmal für die angegebene Zeit stehen und macht erstmal nix mehr. Damit wird natürlich auch Dein Button nicht gelesen.
Es gibt mehrere Möglichkeiten das zu lösen.

  1. Button an Pin 2 oder Pin 3 anschliessen und das ganze per Interrupt-Routine auswerten. (siehe http://arduino.cc/en/Reference/AttachInterrupt)
  2. Statt delay() zu verwenden, einfach per millis() die "aktuelle" zeit mit einem berechneten Wert bei jedem durchlauf von loop() vergleichen und dann die aktionen auslösen
  3. Eine eigene button_delay(long) Funktion schreiben, die ein "delay" umsetzt, dabei aber zusätzlich immer wieder den button abfragt.

Ich hoffe das reicht erstmal als "Denkanstoss" damit Du mit Deinem Sketch weiter kommst.

Grüße,
Mario.

naja also ich hatte es bereits mit if und else, while, und switch case probiert aber immer hatte ich dasproblem, dass wenn ich zwei verschiedene werte für x einsetzte, dass er zuerst am ersten stehenbleibt und die aktion ständig wiederhohlt und wenn man dann nochmal rdauf gedrückt hat ist er zum nächsten gespungen.

ich möchte, dass er wirklich nur dann den ersten wert spielt, wenn der counter auf der zahl stehen bleibt und nicht wenn er nur drüberliest. sonst spielt er ja immer den ersten, und dann den zweiten wert...

naja also ich hatte es bereits mit if und else, while, und switch case probiert aber immer hatte ich dasproblem, dass wenn ich zwei verschiedene werte für x einsetzte, dass er zuerst am ersten stehenbleibt und die aktion ständig wiederhohlt und wenn man dann nochmal rdauf gedrückt hat ist er zum nächsten gespungen.

Dann bitte poste doch mal die vollständige Version, auch wenn sie nicht funktioniert. Es ist einfacher den Fehler im bestehenden Code zu suchen, als zu raten.

Die Fehlfunktion ist denkbar schlecht beschrieben. Sehe ich das richtig, dass du nur eine einmalige Aktion ausführen willst, wenn der entsprechende Zählerstand erreicht ist? Oder stehe ich mit der Annahme noch immer auf dem Schlauch?
Sollte ich richtig liegen, so musst du nur eine Art Flag setzen, dass die Aktion ausgeführt wurde und und dieses Flag wieder löschen, wenn der Zähler weitergelaufen ist.

genau das möchte ich :slight_smile:

Der folgende Code ist ein Code, der eig. das kann was ich möchte. Doch das Problem ist, dass der Counter, sowie er zwischen den Zahlen steht, bei denen er den Button prüfen soll, er nichts macht. Er bleibt dann also auf der gezählten Zahl stehen.
Ich möchte aber, dass er wenn er zwischen den Zahlen steht, dass er den Zähler wieder auf 0 setzt.
Wer eine Idee hat möge bitte den Code kopieren und mit einer Lösung oder einem Lösungsansatz Posten.

int button = 11;
int x = 0;
int ledPin = 6; 


void setup (){
  pinMode(button, INPUT);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  ledPin == LOW;
}

void loop(){
  button = digitalRead(11);
  if ( button == HIGH){
    delay(1000);
   x ++;
   Serial.print(x);
  Serial.print("\n");
  }
  else( button == LOW);{
  delay(1);
  }
 if ( x == 5){
   
    button = digitalRead(11);
    if ( button == LOW){
 
   digitalWrite(ledPin, HIGH);
   delay(1000);
   digitalWrite(ledPin, LOW);
   delay(10);
   
   x = 1;
 
 
 }
 }
 
 if ( x == 10){
   
   button = digitalRead(11);
    if ( button == LOW){
 
   digitalWrite(ledPin, HIGH);
   delay(5000);
   digitalWrite(ledPin, LOW);
   delay(1000);
   digitalWrite(ledPin, HIGH);
   delay(5000);
   digitalWrite(ledPin, LOW);
   delay(10);
   
   x = 1;
   
    }
 }
   
 else(x < 5 );{
   
   digitalWrite(ledPin, LOW);
   
 if (x == 11){
   x = 1;
 }
 }
 
   
 
 }

Hallo Marvinmarco,

ich habe nicht ganz verstanden, was dein Problem ist. Aber ich würde dir empfehlen, deinen Code etwas besser zu strukturieren, dann kannst du nämlich auch leichter Fehler erkennen.
Eine Möglichkeit wäre z. B. die Aufteilung in mehrere kleine Funktionen, die du von loop() aus aufrufst, dann brauchst du nicht so viel auf einmal zu überblicken.

Dann habe ich auch noch ganz konkret eine verdächtige Stelle gefunden (eigentlich sind es zwei)

  if ( button == HIGH){
    delay(1000);
   x ++;
   Serial.print(x);
  Serial.print("\n");
  }
  else( button == LOW);{
  delay(1);
  }

Siehst du den ";" hinter "else ( button == LOW);"?

Der bewirkt, dass sich das else-Statement nur auf die nächste Anweisung bezieht. In diesem Fall ist das Statement ";", ein sogenanntes Leer-Statement. Dein Sketch macht also in dem Fall, dass button == LOW gilt, gar nichts!
Das nächste Statement

{
  delay(1)
}

wird dann immer durchgeführt, unabhängig davon, welchen Wert die Variable button hatte.

Ein else-Statement mit einen Semikolon abzuschließen, ist in 99,99% der Fälle keine gute Idee. Für den Fall, dass man das doch einmal braucht,
habe ich mir angewöhnt, das ";" auf eine eigene Zeile zu schreiben, sonst geht es optisch unter und falls jemand anders deinen Code warten müsste, muss er erst einmal überlegen, wie das Teil eigentlich funktioniert;-)

Rudi

Wobei da einiges mehr nicht stimmt:

  if ( button == HIGH){
...
  }
  else( button == LOW);{
  delay(1);
  }

Das "(button == LOW)" macht keinen Sinn. Mich wundert eigentlich, dass das der Compiler nicht anmeckert.
Richtig sollte es so lauten:

  if ( button == HIGH){
...
  }
  else{
  delay(1);
  }

Und weiter unten:

 if ( x == 10){
...
 }
   
 else(x < 5 );{

Funktioniert so nicht, richtig sollte es so lauten:

 if ( x == 10){
...
 }

 else if(x < 5 ){

Ich denke, dass hier noch einiges an Grundlagenwissen zu Variablen fehlt: hier wird eine button-Variable als Integer initialisiert, die erst die Pinnummer, später jedoch den Status (HIGH/LOW) beeinhalten soll. Dass das ganze trotzdem funktioniert, grenzt schon an Voodoo... :wink: