Problem: LED-Bargraph ansteigen lassen solange Taster gedrückt

Hallo,

dies ist mein erster Beitrag im Forum. Daher erstmal ein Hallo.
Seit ein paar Tagen hat mich das Arduinofieber gepackt und ich habe mir ein Starterkit mit dem Uno geholt.
Java kann ich einigermaßen, C ist da soweit ich jetzt gesehen habe ähnlich.
Nach einigen erfolgreichen kleinen Programmen habe ich nun ein Problem.
Ich will eine Bargraphanzeige ansteigend! aufleuchten lassen. Aber nur solange der Taster gedrückt ist.
D.h. wenn der Taster nach 4 Balken bzw. Leds losgelassen wird, soll die Anzeige aus oder schöner noch wieder zurück gehen.
Das bekomme ich aber mit all meinen Kenntnissen nicht hin.
Es klappt zwar, dass die Anzeige ansteigt, aber das tut sie auch wenn der Taster nur einmal kurz gedrückt wurde.

  1. Variante leuchtet immer voll auf, auch wenn der Taster bereits wieder losgelassen wurde:
const int buttonPin = 2;     // the number of the pushbutton pin
int led[] = {4,5,6,7,8,9,10,11,12,13};


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  Serial.begin(9600);
  for (int i = 0; i <10; i++)
  {
  pinMode(led[i], OUTPUT);
}
  pinMode(buttonPin, INPUT);     
}
  
void loop()
{
  buttonState = digitalRead(buttonPin);
  do 
  {     
    buttonState = digitalRead(buttonPin);      
    for (int i=0;i < 10; i++)
    {
      digitalWrite(led[i], HIGH);
      delay(25);
     } 
  } while (buttonState == HIGH);
  
  do
    {
      buttonState = digitalRead(buttonPin);
        for (int i=10;i >= 0; i--)
        {
          digitalWrite(led[i], LOW);
          delay(10);
        } 
    } while (buttonState == LOW);
}
  1. Variante gleiches Verhalten wie bei1.:
const int buttonPin = 2;     // the number of the pushbutton pin
int led[] = {4,5,6,7,8,9,10,11,12,13};


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  Serial.begin(9600);
  for (int i = 0; i <10; i++)
  {
  pinMode(led[i], OUTPUT);
}
  pinMode(buttonPin, INPUT);     
}
  
void loop()
{
  
  buttonState = digitalRead(buttonPin);
   
  for (int i=0;i < 10; i++)
  {
      while (buttonState == HIGH)
        {
        //buttonState = digitalRead(buttonPin);
        digitalWrite(led[i], HIGH);
        delay(25);
        break;
        }
      for (int i=0;i<10;i++)
      {
        while (buttonState == LOW)
        {
          digitalWrite(led[i], LOW);
          break;
        }
      }
    } 
   
}

Ich hoffe ihr könnt mir helfen, eventuell einen Denkanstoß geben wie ich das Problem lösen kann.

Du brauchst eine Variable, die den Wert des Bargraph hält:

uint8_t bvalue = 0;
uint32_t last_update = 0;

void loop() {
  if (digitalRead(buttonPin)) {
    if (millis() - last_update > 200) {
      last_update = millis();
      bvalue++;
      bvalue = bvalue % 12;
    }
  } else {
     bvalue = 0;
  }
  uint8_t i;
  for (i = 0; i < 10; i++) {
    digitalWrite(leds[i], i < bvalue ? HIGH : LOW);
  }
}

Nur so schnell zusammengehackter Code, keine Garantie, dass er läuft, aber er sollte Dir einen Anschub geben können. Damit das etwas schöner wird, solltest Du das Runterfahren noch nachrüsten und den Taster entprellen. Für Letzteres findest Du bei Google haufenweise Anleitungen (auch hier im Forum :slight_smile: ).

matzeni:
Es klappt zwar, dass die Anzeige ansteigt, aber das tut sie auch wenn der Taster nur einmal kurz gedrückt wurde.

Wenn ich Deine Beschreibung richtig verstanden habe, dann geht Dein Code überhaupt nicht darauf ein, was Du machen möchtest.

So wie ich es verstanden habe, soll sich Im Programmablauf immer dann etwas ändern, wenn sich der Status des Buttons ändert. Mein Code (siehe unten) fängt also damit an, Änderungen im Buttonstatus festzustellen und die Zeit (Stand des millis()-Timers) zu merken, zu der sich der Status geändert hat.

Und dann soll es eine Veränderung im Zeitablauf nach einer Statusänderung geben:

  • bei gedrücktem Button soll mit zunehmender Drückzeit die Anzahl der eingeschalteten LEDs zunehmen, bis alle LEDs eingeschaltet sind
    -. bei losgelassenem Button soll mit zunehmender Zeit die Anzahl der eingeschalteten LEDs abnehmen, bis alle LEDs aus sind

So wie ich es verstanden habe, habe ich es mal in Code gepackt. Wie schnell das Ein-/Ausschalten der LEDs vonstatten gehen soll, wird über die Konstante
#define increaseLedAfter 1000 // milliseconds of continous button press
eingestellt. 1000 Millisekunden bedeutet, dass pro 1 Sekunde eine zusätzliche LED ein- bzw. ausgeschaltet wird.

#define BUTTONPIN 2  // the number of the pushbutton pin
int led[] = {4,5,6,7,8,9,10,11,12,13};
const int numLEDs= sizeof(led)/sizeof(led[0]);

#define increaseLedAfter 1000 // milliseconds of continous button press

void setup() {
  for (int i = 0; i <10; i++)
  {
    pinMode(led[i], OUTPUT);
  }
  pinMode(BUTTONPIN, INPUT);
}
  
void loop()
{
  static boolean oldButtonState;
  static unsigned long sameStateSince;
  static int ledsMaxON;
  int ledsON;
  long pressTime;
  boolean buttonState = digitalRead(BUTTONPIN);   // variable for reading the pushbutton status
  if (buttonState != oldButtonState)  // Buttonstatus hat sich geändert
  {
    oldButtonState=buttonState;
    sameStateSince=millis();             // Zeit merken
    if (buttonState==HIGH) ledsMaxON=0;  // und ggf. die Zahl der maximal geschalteten LEDs zurücksetzen
  }
  if (buttonState==HIGH)  // Taste wurde gedrückt
  { // ggf. die Zahl der eingeschalteten LEDs erhöhen
    ledsON=(millis()-sameStateSince)/increaseLedAfter; 
    if (ledsON>numLEDs) ledsON=numLEDs;
    ledsMaxON=ledsON; // Anzahl der maximal geschalteten LEDs merken
  }
  else if (ledsMaxON>0) //
  { // ggf. die Zahl der eingeschalteten LEDs vermindern
    ledsON=ledsMaxON-(millis()-sameStateSince)/increaseLedAfter;
    if (ledsON<0) {ledsON=0;ledsMaxON=0;}
  }
   
  for (int i=0;i < numLEDs; i++)
  {
    if (i+1<=ledsON)
    {
      digitalWrite(led[i], HIGH);
    }  
    else 
    {
      digitalWrite(led[i], LOW);
    }  
  } 
  delay(20); // Entprellzeit in der Loop als delay
}

matzeni: Java kann ich einigermaßen, C ist da soweit ich jetzt gesehen habe ähnlich.

Nur von der Syntax her. Im Hintergrund verhält sich das völlig anders.

Perfekt, beide Codes funktionieren. Danke schön. Nun muss ich diese nur noch richtig nachvollziehen :)