Lauflicht sofort abschalten

Hallo Community,
ich habe eine Frage und zwar habe ich in einem Programm unter anderem ein Lauflicht programmiert, welches sofort nach Knopfdruck auf dem zugehörigen Keypad ausgehen soll.
Die Ausgabe auf die LED's erfolgt über das 74HC595 Schieberegister.
Der Code:

if (button=='A'||'B'||'C'||'D')
  {bet = true;}
 if (button=='*')
  {ausf = true;}
 if (button=='#')
  {ausf = false;}
 if (ausf==true && bet == true)
  {laufen();} 
 if (button=='A')
  {x=50;}
 if (button=='B')
  {x=100;}
 if (button=='C')
  {x=200;}
 if (button=='D')
  {x=400;}
void laufen(){
    int leds=0;
    button = myKeypad.getKey();
    for (int i=0;i<8; i++)   
{   bitSet(leds, i);
    digitalWrite(Latch, LOW);
    shiftOut(Data,Shift,MSBFIRST,leds);
    digitalWrite(Latch,HIGH);
    delay(x); }
    leds=0;
    delay (50);
    digitalWrite(Latch, LOW);
    shiftOut(Data,Shift,MSBFIRST,leds);
    digitalWrite(Latch,HIGH); }

Das Problem ist allerdings nun, dass ich genau den Moment abpassen muss wenn das Programm wieder von vorne durch läuft, denn sonst lässt es sich nicht über '#' beenden.
Ich hoffe ihr könnt mir helfen. :slight_smile:

Da Du uns den Rest vom Sketch vorenthälst, können wir nur raten.

Ich gehe davon aus, dass das delay(x) raus muss und durch ein Konstrukt mit millis() ersetzt werden muß. Such mal nach BlinkWithoutDelay.

Gruß Tommy

Huch ja sorry, schonmal vielen Dank.
Hier natürlich der ganze Sketch:

#include <Keypad.h>
const byte COLS = 4;
const byte ROWS = 4;
char hexaKeys[ROWS][COLS] = {
  {'D','#','0','*'},
  {'C','9','8','7'},
  {'B','6','5','4'},
  {'A','3','2','1'}
  };

  byte colPins[COLS] = {2,3,4,5};
  byte rowPins[ROWS] = {6,7,8,9};
  Keypad myKeypad = Keypad(makeKeymap(hexaKeys),rowPins,colPins,ROWS,COLS);
  int Data = 10;
  int Latch = 11;
  int Shift = 12;
  char button = myKeypad.getKey();
  bool ausf = false;
  int x;
  bool bet =false;  
  
  
 void setup() {
  // put your setup code here, to run once:

  pinMode(Data,OUTPUT);
  pinMode(Latch,OUTPUT);
  pinMode(Shift,OUTPUT);
  Serial.begin(9600);  
  ledaus();
  
 }
 void loop() {evalButton();
 if (button=='0')
     {ledaus();}
 if (button=='A'||'B'||'C'||'D')
  {bet = true;}
 if (button=='*')
  {ausf = true;}
 if (button=='#')
  {ausf = false;}
 if (ausf==true && bet == true)
  {laufen();} 
 if (button=='A')
  {x=50;}
 if (button=='B')
  {x=100;}
 if (button=='C')
  {x=200;}
 if (button=='D')
  {x=400;}

if (button == '9')
  { byte leds = 0;
    byte wdh  = 3;
    for (int i=0;i<wdh;i++)
  { for (int i=0;i<8;i++) 
      { bitSet(leds,i);
        digitalWrite(Latch, LOW);
        shiftOut(Data,Shift,MSBFIRST,leds);
        digitalWrite(Latch,HIGH);}
      leds = 0;
      delay(1000);
      digitalWrite(Latch, LOW);
      shiftOut(Data,Shift,MSBFIRST,leds);
      digitalWrite(Latch,HIGH);
      leds = 8;
      delay (1000);}}
}

void evalButton() {
  button = myKeypad.getKey();

  int leds = 0;
  if (button == '1')
    leds = 1;
  if (button == '2')
    leds = 2;
  if (button == '3')
   leds = 3;
  if (button == '4')
   leds = 4;
  if (button == '5')
   leds = 5;
  if (button == '6')
   leds = 6;
  if (button == '7')
   leds = 7;
  if (button == '8')
   leds = 8;

 
  

  byte lauf = 0;
  for (int i = 0; i < leds; i++) {
    bitSet(lauf,i);
    digitalWrite(Latch, LOW);
    shiftOut(Data,Shift,MSBFIRST,lauf);
    digitalWrite(Latch,HIGH);
  }
}

void laufen(){
    int leds=0;
    button = myKeypad.getKey();
    for (int i=0;i<8; i++)   
{   bitSet(leds, i);
    digitalWrite(Latch, LOW);
    shiftOut(Data,Shift,MSBFIRST,leds);
    digitalWrite(Latch,HIGH);
    delay(x); }
    leds=0;
    delay (50);
    digitalWrite(Latch, LOW);
    shiftOut(Data,Shift,MSBFIRST,leds);
    digitalWrite(Latch,HIGH); }

void ledaus()
{byte leds = 0;
 digitalWrite(Latch, LOW);
 shiftOut(Data,Shift,MSBFIRST,leds);
 digitalWrite(Latch,HIGH);}

delay(1000);

Wie Tommy schon schrieb: das muss raus, in der Zeit kriegt der arduino NIX mit.

Und Du hast noch mehr delays drin - vermutlich überall das gleiche Phänomen, hab's mir jetzt nicht im Detail angeschaut.

Der Verdacht von #1 verdichtet sich.

Wenn Du neben den LEDs auch noch quasiparallel die Tasten abfragen möchtest, darfst Du den µC nicht mittels delay() pausieren lassen. Daher muß loop() möglichst blockadefrei durchlaufen werden.

Zusätzlich solltest Du noch die EvalButton-Funktion entschlacken.
Da sollte nur die Auswertung der Button drin sein und nichts anderes, sonst bekommst Du den Aus-Button erst zu spät mit.
Die Umsetzung der Ziffern geht auch einfacher:

int leds;
char ledstr[]="0"; // da sind 2 zeichen drin '0' und '\0'
...
button = myKeypad.getKey();
if (button >= '0' && button <=9) {
  ledstr[0] = button; // an die erste Stelle das Zeichen schreiben 
  leds = atoi(ledstr);
}
else {
  //andere Tasten
}

Zum Verständnis der Zeichenketten in C schau Dir mal diese Zusammenfassung an.

Gruß Tommy

if (button=='A'||'B'||'C'||'D')

Der Kode das macht nicht was du erwartest.

Tommy56:

  if (button >= '0' && button <=9) {

Das sieht zumindest verdächtig aus.if ('9' != 9) Serial.println ("mist");

Du hast recht. Es sollte <= '9' heißen :wink:

Gruß Tommy

:wink:
Um einen einzelnen Buchstaben zwischen '0' und '9' in eine Zahl 0 .. 9 zu wandeln, ist atoi wirklich nicht nötig. Diese zehn Buchstaben liegen nämlich direkt hintereinander.

button = myKeypad.getKey();
if (button >= '0' && button <='9') {
  leds = button - '0';
}
else
...

Auch eine Variante und wohl schneller.

Gruß Tommy

Okay, vielen Dank für die Hilfe.
Ich probiere es so bald wie möglich aus.