Problem mit Interrupt (Interrupt funktioniert nicht)

Hallo liebe Arduino-Profis,

ich habe ein Problem mit meinem Arduino Code, und zwar bastel ich gerade an einer Schrittmotorsteuerung, nichts besonderes und ist auch noch nicht ganz fertig. Jetzt soll das ganze einen Endschalter bekommen und den step_pin beim erreichen der Endposition auf LOW bzw. den Status “state” auf false schalten. Den Taster habe ich an Pin 2 (Interrupt 0) angeschlossen, aber aus irgendeinem, mir nicht ersichtlichen Grund, löst dieser nicht aus. Kann mir vielleicht von euch jemand weiterhelfen?

#include <LiquidCrystal.h>

// Define the Pins used
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  //LCD-Display Pin´s
#define step_pin 0    // Pin 0 connected to Steps pin on EasyDriver
#define dir_pin 3     // Pin 3 connected to Direction pin
#define end_switch 2  // Endschalter

#define sleep_pin 11   // Pin 11 connected to SLEEP pin
#define home_switch 12 // Pin 12 connected to Home Switch (MicroSwitch)
#define mode_switch 13 // Umschalten zwischen Timelapse und Video
int poti = 24;      // Poti-Pin A2
int delay_time = 0;
volatile boolean state = true;  
int direction;    // Variable to set Rotation (CW-CCW) of the motor
int steps;        // Used to set HOME position after Homing is completed
void setup() {

   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   pinMode(sleep_pin, OUTPUT);
   pinMode(mode_switch, INPUT_PULLUP);
   pinMode(end_switch, INPUT_PULLUP);
   pinMode(poti, INPUT);
   pinMode(home_switch, INPUT_PULLUP);
   digitalWrite(sleep_pin, HIGH);  // Wake up EasyDriver
   delay(5);  // Wait for EasyDriver wake up


lcd.begin(16, 2);            
lcd.setCursor(0,0);
lcd.print(" Kamera-Slider");

delay(3000);
lcd.clear();

// Start Homing procedure of Stepper Motor at startup

 lcd.setCursor(0,0);
  lcd.print("Kamera-Homing...");


  while (digitalRead(home_switch)) {  // Do this until the switch is activated   
    digitalWrite(dir_pin, HIGH);      // (HIGH = anti-clockwise / LOW = clockwise)
    digitalWrite(step_pin, HIGH);
    delay(5);                       // Delay to slow down speed of Stepper
    digitalWrite(step_pin, LOW);
    delay(5);   
}

  while (!digitalRead(home_switch)) { // Do this until the switch is not activated
    digitalWrite(dir_pin, LOW); 
    digitalWrite(step_pin, HIGH);
    delay(10);                       // More delay to slow even more while moving away from switch
    digitalWrite(step_pin, LOW);
    delay(10);
  }

  steps=0;  // Reset position variable to zero


     lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Homing beendet!");
  delay(2000);
  lcd.clear();
 attachInterrupt(0, end_switch_ISR, FALLING);
  
}

void loop() {


steps = 0;
  while ((digitalRead(mode_switch) && state == true && steps < 5)) {
   delay_time = analogRead(poti);
        delay_time = map(delay_time, 0, 1023, 1000, 10000);
        Serial.println(delay_time);
    lcd.setCursor(0,0);
    lcd.print("Timelapse-Modus");
    lcd.setCursor(0,1);
    lcd.print("Intervall:");
    lcd.setCursor(11,1);
    lcd.print(delay_time / 1000); 
    lcd.setCursor(13,1);
    lcd.print("sek");
      digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(step_pin, HIGH);
      delay(1);
      digitalWrite(step_pin, LOW);
      delay(1);
      steps++;   // Decrease the number of steps taken
    }
          steps = 0; 
          delay(delay_time);
          lcd.clear();
   
    while ((!digitalRead(mode_switch) && (state == true))) {
   
        delay_time = analogRead(poti);
        delay_time = map(delay_time, 0, 1023, 10, 1);
        lcd.setCursor(0,0);
        lcd.print("Video-Modus");
        lcd.setCursor(0,1);
        lcd.print("Speed:");
        lcd.setCursor(7,1);
        lcd.print(delay_time); 
        digitalWrite(dir_pin, HIGH);
        digitalWrite(step_pin, HIGH);
        delay(delay_time);
        digitalWrite(step_pin, LOW);
        delay(delay_time);
        steps++;  // Increase the number of steps taken
        
    

   }
   steps = 0; 
   lcd.clear();

   while (state == false) {
    digitalWrite(step_pin, LOW);
    lcd.setCursor(0,0);
    lcd.print("Endpos. erreicht!!!");
   }
   }




void end_switch_ISR() {
state = !state;
}

Wenn Dein Taster prellt (und das tun die meisten) schaltet er mehrfach state um.

Gruß Tommy

Ich sehe hier keine Notwendigkeit für einen Interrupt.

Auch braucht man in Loop() keine lang laufenden Schleifen und delay().

Tommy56: Wenn Dein Taster prellt (und das tun die meisten) ...

ALLE mechanischen Taster prellen.

https://de.wikipedia.org/wiki/Prellen

Gruß

Gregor

Hmmm, danke schon mall für eure Antworten, stimmt, eine normale Tasterabfrage sollte hier auch reichen. Ja, das mit den ganzen delays ist mir auch ein Dorn im Auge, weil das den Programmablauf doch sehr einschränkt. Wie könnte man das denn optimieren?

Gruß,

Martin

RAMPRO: ... Ja, das mit den ganzen delays ist mir auch ein Dorn im Auge, weil das den Programmablauf doch sehr einschränkt. Wie könnte man das denn optimieren?

Ich bin in diesem Thread „Quereinsteiger“ und habe nicht alle Postings oder Sketche gelesen (schon gar nicht vollständig).

Wenn Du delay() vermeiden möchtest, kannst Du das IMO am besten, indem Du einen „endlichen Automaten“ programmierst. Was mir dazu eingefallen ist, habe ich hier und hier ins Netz gekippt.

Um den Unterschied in der „Pausen-Denke“ zu verstehen, muss man sich möglicherweise einen kleinen Knoten ins Hirn machen, aber so schlimm wie Rekursion ist das nicht. Sehr verständlich finden viele die Nachtwächter-Erklärung.

Gruß

Gregor

Der analoge Eingang braucht kein pinMode()

gregorss: ALLE mechanischen Taster prellen.

https://de.wikipedia.org/wiki/Prellen

Gruß

Gregor

Ich habe schon einige wenige erlebt, die in einem schnellen Loop - nur mit digitalRead - jeweils nur einen Signalpegel ausgegeben haben.

Gruß Tommy

Tommy56: Ich habe schon einige wenige erlebt, die in einem schnellen Loop - nur mit digitalRead - jeweils nur einen Signalpegel ausgegeben haben.

Echt?! Ich hatte noch keinen einzigen mechanischen Kontakt in den Fingern, der nicht geprellt hat - egal, ob Mikro- oder Quecksilberschalter. Ich habe einige Zeit gebraucht, um das Prellen als „immer da“ zu akzeptieren und entsprechend zu behandeln. Ohne irgendeine Art der Entprellung kommt mir kein mechanischer Kontakt mehr in die Schaltung.

Gruß

Gregor

Ich habe auch gestaunt. ich habe extra versucht die zum Prellen zu bekommen - nix zu machen. Da, wo die Reaktionszeit kurz genug ist, nutze ich auch keine unentprellten Taster. Wenn der Taster sowieso erst wieder nach 5 Sekunden abgefragt wird, ist es ja unnötig.

Gruß Tommy