Wie füge ich ein Interrupt ein?

Hi :wink:

ich weiß nicht wie ich ein Interrupt bei der Schaltung einfügen soll geschweigen wie ich ein Interrupt überhaupt einfüge.
Da ich leider nach längerer Suche im Internet nicht auf ein für mich schlüssiges Ergebnis gekommen bin bitte ich euch nun um Hilfe.

Zum kurzen Verständnis:
Wenn ich Taster 1 Drücke soll das Lichtspiel 1 laufen wenn Taster 2 gedrückt wird Lichtspiel2 und das so schnell es geht und nicht nach ewigem warten bis das Programm einmal durch ist. :frowning:

int tasterPinA = 2;                  //Taster 1
int tasterPinB = 3;                  //Taster 2
int tasterStatusA;                   //Taster Status1
int tasterStatusB;                   //Taster Status2
int ledPinC = 20;                    //Kontrolled 1
int ledPinD = 21;                    //Kontrolled 2
int ledCstatus;                      //Kontrolledstatus 1
int ledDstatus;                      //Kontrolledstatus 2
int ledPin1 = 7;                     //Blinkled 1
int ledPin2 = 8;                     //Blinkled 2
int ledPin3 = 9;                     //Blinkled 3
int ledPin4 = 10;                    //Blinkled 4
int ledPin5 = 11;                    //Blinkled 5
int ledPin6 = 12;                    //Blinkled 6
int ledPin7 = 13;                    //Blinkled 7
int delay1 = 150;                    //Delay ein
int delay2 = 200;                    //delay aus


void setup()               //Immer wiederholend
{
 pinMode(tasterPinA, INPUT);
 pinMode(tasterPinB, INPUT); 
 pinMode(ledPin1, OUTPUT);
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(ledPin5, OUTPUT);
 pinMode(ledPin6, OUTPUT);
 pinMode(ledPin7, OUTPUT);
 pinMode(ledPinC, OUTPUT);
 pinMode(ledPinD, OUTPUT);
 
 }

void loop() {
 
 tasterStatusA = digitalRead(tasterPinA);
 tasterStatusB = digitalRead(tasterPinB);
 ledCstatus = digitalRead(ledPinC);
 ledDstatus = digitalRead(ledPinD);

   if(tasterStatusA == HIGH)
   {
   digitalWrite(ledPinC, HIGH);
   digitalWrite(ledPinD, LOW);
 }  

 
 if(tasterStatusB == HIGH)
 {
   digitalWrite(ledPinD, HIGH);
   digitalWrite(ledPinC, LOW);
  }
 // Lichtspiel 1
 if (ledCstatus == HIGH)
    {
    
      digitalWrite(ledPin1, HIGH);
      delay(delay1);
      digitalWrite(ledPin1,LOW);
      delay(delay2);
      
      digitalWrite(ledPin2, HIGH);
      delay(delay1);
      digitalWrite(ledPin2,LOW);
      delay(delay2);
      
      digitalWrite(ledPin3, HIGH);
      delay(delay1);
      digitalWrite(ledPin3,LOW);
      delay(delay2);
      
      digitalWrite(ledPin4, HIGH);
      delay(delay1);
      digitalWrite(ledPin4,LOW);
      delay(delay2);
      
      digitalWrite(ledPin5, HIGH);
      delay(delay1);
      digitalWrite(ledPin5,LOW);
      delay(delay2);
      
      digitalWrite(ledPin6, HIGH);
      delay(delay1);
      digitalWrite(ledPin6,LOW);
      delay(delay2);
      
      digitalWrite(ledPin7, HIGH);
      delay(delay1);
      digitalWrite(ledPin7,LOW);
      delay(delay2);
      }
    

  //Lichtspiel 2
    if(ledDstatus == HIGH)
    {
      digitalWrite(ledPin7, HIGH);
      delay(delay1);
      digitalWrite(ledPin7,LOW);
      delay(delay2);
     
      digitalWrite(ledPin6, HIGH);
      delay(delay1);
      digitalWrite(ledPin6,LOW);
      delay(delay2);
      
      digitalWrite(ledPin5, HIGH);
      delay(delay1);
      digitalWrite(ledPin5,LOW);
      delay(delay2);
      
      digitalWrite(ledPin4, HIGH);
      delay(delay1);
      digitalWrite(ledPin4,LOW);
      delay(delay2);
      
      digitalWrite(ledPin3, HIGH);
      delay(delay1);
      digitalWrite(ledPin3,LOW);
      delay(delay2);
      
      digitalWrite(ledPin2, HIGH);
      delay(delay1);
      digitalWrite(ledPin2,LOW);
      delay(delay2);
      
      digitalWrite(ledPin1, HIGH);
      delay(delay1);
      digitalWrite(ledPin1,LOW);
      delay(delay2);
    }
   
}

Ich hoffe mein Code ist einigermaßen verständlich und vielen Dank für eure Hilfe.

mit freundlichen Grüßen,
Nessy

Hallo Nessy
Du hast sehr viel Blockierenden Code drin. Du musst die delays rausschmeißen aus deinem Programm und das zeitliche Ein / Aus mit millis() abfragen machen. Schau mal unter den Beispielen aus der IDE Blink without delay und versuche das in dein Programm einzufügen. Momentan bleibt der Controller jedes mal komplett stehen für die delayZeit wenn ein delay in deinem Programm kommt.
Gruß
DerDani

Danke für die schnelle Antwort,
und entschuldige das ich da jetzt gleich so doof nachfragen muss aber macht das dann den Programmdurchlauf schneller oder wie darf ich den unterschied zwischen millis und delay verstehen?
Und ich habe mich gerade drüber informiert wie man das mit dem millis macht bin aber leider an einer zweiten Led gescheitert :frowning:

aber macht das dann den Programmdurchlauf schneller oder wie darf ich den unterschied zwischen millis und delay verstehen?

ja, bei delay bleibt der uC stehen und bei millis läuft er weiter. Ein normaler Loopdurchlauf sollte nicht länger als 2ms dauern.

Ich habe mir dein Programm mal angeschaut, deine Taster hast du zwischen Vcc und Arduino Pin angeschlossen, hast du auch einen Pulldown Widerstand eingebaut? Ansonsten schließ die Taster zwischen GND und Arduino Pin an und aktiviere den internen Pullup Widerstand (pinMode INPUT_PULLUP), dann mußt du im Code auf ==LOW abfragen. Außerdem solltest du deine Taster noch entprellen

@ardubu: Ich habe in meiner Schaltung einen Pulldown Widerstand eigenbaut da es sich für mich nicht richtig erschloßen hat was der Vorteil des interenen Wiederstandes ist.

Ist es denn so wichtig ihn zu entprellen und gegebenfalls kann ich auch einen Taster benutzen der diesen Schutz hat ;).

Jedoch bleibt mir immer noch die Frage wie ich mehrere LEDs ansteuern kann mit millis statt delay.

Nessy:
oder wie darf ich den unterschied zwischen millis und delay verstehen?
Und ich habe mich gerade drüber informiert wie man das mit dem millis macht bin aber leider an einer zweiten Led gescheitert :frowning:

ganz einfach: delay() heißt: bleibe stehen und warte, tue sonst nichts.
millis() ist eine Uhr, auf der du schauen kannst wie spät es ist.

ich hatte das Prinzip an anderer Stelle schon mal anschaulich beschrieben:
Der Wachmann

Was dann rauskommt ist ein Code in dem die loop() sehr schnell durchlaufen wird, und nur ab und verzweigt wird, um den Ablauf abzuarbeiten.

Wenn du also in der loop() auch deine Taster abfragst, dann kannst du sofort drauf reagieren.

wie darf ich den unterschied zwischen millis und delay verstehen

Als Ergänzung zu guntherbs Erklärung:
Der Haupt-Unterschied ist, dass loop() keinen Zeitlichen Ablauf beschreibt, sondern nur einen aktuellen Moment beschreibt. Und immer sofort fertig ist.

Um zu entscheiden, wann was zu tun ist, brauchst du die aktuelle Zeit ( millis() ) und einen Merker, wann der Startzeitpunkt war. Wenn mehrere Zeiten parallel laufen, brauchst du mehrere Zeit-Merker. Wenn du mehrere Schritte ausführen willst, brauchst du einen Merker, wo du in deinem Programm grade bist.

Es wird nicht delay durch millis ersetzt, sondern ganz anders angefangen :wink:
Statt dieser delays:

void loop() { 
      digitalWrite(ledPin1, HIGH);
      delay(delay1);
      digitalWrite(ledPin1,LOW);
      delay(delay2);
      
      digitalWrite(ledPin2, HIGH);
      delay(delay1);
      digitalWrite(ledPin2,LOW);
      delay(delay2);
 }

Z.B. 4 Schritte erfinden:

const int delay1=150;
const int delay2=300;

int schritt = 0;
unsigned long start;

void loop() {

   int dauer;
   if ( schritt == 0 || schritt == 2) 
      dauer = delay1;
   else
      dauer = delay2;

   // eventuell nächsten Schritt 0 -1 - 2 - 3- 0 - ...
   if ( millis() - start > dauer) {
      schritt++;
      if (schritt > 3) schritt=0;
      start = millis();
   } 
 
   // LED Ausgabe
   switch (schritt) {
   case 0: 
     digitalWrite(ledPin1, HIGH);
     digitalWrite(ledPin2, LOW);
     break;
   case 1: 
     digitalWrite(ledPin1, LOW);
     digitalWrite(ledPin2, LOW);
     break;
   case 2: 
     digitalWrite(ledPin1, LOW);
     digitalWrite(ledPin2, HIGH);
     break;
   case 3: 
     digitalWrite(ledPin1, LOW);
     digitalWrite(ledPin2, LOW);
     break;
   }

   // hier kann noch beliebiger anderer Code hin, 
   // der auch permanent dran kommt und selber nicht wartet..
}

Und mit interrupt hat das dann gar nichts zu tun...

Nessy:
Da ich leider nach längerer Suche im Internet nicht auf ein für mich schlüssiges Ergebnis gekommen bin bitte ich euch nun um Hilfe.

Was ist denn jetzt passiert?
Nessy sucht keinen Programmierer mehr, sondern möchte selbst programmieren lernen?

Nessy:
Zum kurzen Verständnis:
Wenn ich Taster 1 Drücke soll das Lichtspiel 1 laufen wenn Taster 2 gedrückt wird Lichtspiel2 und das so schnell es geht und nicht nach ewigem warten bis das Programm einmal durch ist. :frowning:
...
Ich hoffe mein Code ist einigermaßen verständlich und vielen Dank für eure Hilfe.

Der Code ist verständlich, aber der Ansatz ist vollkommen falsch.

"Interrupts" programmieren ist absolut nichts für blutige Anfänger beim Programmieren. Das ist eher etwas für Fortgeschrittene.

Und wenn Du ein Pseudo-Multitasking programmieren möchtest, bei dem ein

  • Button-Task und
  • Lightshow-Task
    quasi parallel ablaufen sollen, dann ist
  • jeder den Programmablauf blockierende Befehl wie z.B. "delay()" komplett verboten.

Stattdessen mußt Du einen Button-Task programmieren, der

  • feststellt, ob und welcher Button gedrückt wird
  • sich den Zeitpunkt merkt, wann welcher Button gedrückt wird, und zwar den Stand der millis() Millisekundenzählers

Und je nachdem, welcher Button zuletzt gedrückt wurde, rufst Du dann Deine Lichtspielfunktion auf, die aber auch nicht blockierend programmiert sein darf (also nix mit delay()), sondern die alleine aus dem Ablauf des millis() Millisekundenzählers (und ggf. der Startzeit) ermitteln muss, wann welche LED wie zu schalten ist.

Aus Deinem Code muss jedenfalls JEDES delay() RAUS und die Programmlogik muss komplett auf ein kooperatives Multitasking angepasst werden.

Interruptprogrammierung wird dafür definitiv NICHT benötigt.

Eine Nummer einfacher für jemanden komplett ohne Programmierkenntnisse hast Du es wohl nicht zufällig?

@ardubu: Ich habe in meiner Schaltung einen Pulldown Widerstand eigenbaut da es sich für mich nicht richtig erschloßen hat was der Vorteil des interenen Wiederstandes ist.

Du sparst dir den externen, wenn du den internen verwendest.
Bei längeren Kabeln kann ein (kleinerer) externer besser sein.

Jedoch bleibt mir immer noch die Frage wie ich mehrere LEDs ansteuern kann mit millis statt delay.

Das Zauberwort lautet: "Endlicher Automat"

Hallo,

habe mir mal ein Grundgerüst ausgedacht. Vielleicht ist das brauchbar.

Die aktuelle Bounce2 Lib zum Taster entprellen liegt bei.
Den Ordner Bounce2 nach ...\Dokumente\Arduino\libraries\ kopieren
Allerdings erzeugt die in meiner aktuellen IDE Warnungen beim kompilieren. Funktioniert dennoch, aber unschön. Habe damit 3 Beispiele erstellt für 3 Taster. Verhalten sich unterschiedlich. Kannste mal damit rumspielen und Erkenntnisse sammeln.

Eigentlich dachte ich als Grundlage an die "Bounce2Lib_mit_3_Tastern_Bounce_Status". Hier werden für die Taster, wenn gedrückt, je eine Statusvariable gesetzt. Diese kannste für die Lichtauswahl verwenden. Am Ende mußte nur diese Statusvariable zurück auf false setzen damit die Lichtshow nicht nochmal beginnt. So meine Gedanken.

Dann dachte ich mir, dass entprellen brauchst du nicht, du willst ja nichts gezielt auf Tastendruck umschalten. Also Bounce2 Lib rausgewurfen. Weniger Code wird übersichtlicher. Das wäre "mit_3_Tastern_Status". Kannste rumspielen was mit den Taster so passiert und den Code möglichst nachvollziehen können. Dann kannste Deine Lichtershow einbauen. Die mußte aber noch vom delay befreien.

Wenn dir das alles nicht gefällt, ist auch nicht schlimm. Jeder geht da anders ran.

Nessy.zip (86.6 KB)