Arduino Interrupt

OP #5368544
Lesenswert?

Hallo,
könnt Ihr mir bitte sagen, ob folgender Code richtig ist?
Ich möchte probeweise für ein Projekt einen Interrupt ablaufen lassen.
Über einen Taster setze ich den Pin 3 auf High. Dann sollte ja 
eigentlich der "loop" unterbrochen werden und der Interrupt "pin_ISR_1" 
ablaufen.
Leider reagiert der Interrupt entweder gar nicht, oder nur ganz 
kurz(d.h. die LED leuchtet nur ganz kurz auf, obwohl sie ja 3 sek. 
leuchten sollte).
Wenn der Code richtig ist, dann muss es wohl doch an der Hardware 
liegen?!

const int ledPin = 13;
const int ledPin2 = 7;

void setup()
{
 pinMode(ledPin, OUTPUT);
 pinMode(ledPin2, OUTPUT);
 attachInterrupt(1, pin_ISR_1, RISING);
}

void loop()
{
 digitalWrite(ledPin2, HIGH);
 delay(500);
 digitalWrite(ledPin2, LOW);
 delay(500);
}

void pin_ISR_1()
{
 digitalWrite(ledPin, HIGH);
 delay(3000);
 digitalWrite(ledPin, LOW);
}

Danke im Voraus.
Moderator (Firma: Titel) Persönliche Seite #5368556
Lesenswert?

Mal grundlegend: der strukturelle Fehler ist das delay im Interrupt.
Ein Interrupt ist eine " Unterbrechung" und Unterbrechungen sollten 
nicht allzu lang dauern...

Dan N. schrieb:
> Über einen Taster setze ich den Pin 3 auf High.
Wie ist der Taster angeschlossen?

> Leider reagiert der Interrupt...
Und was macht dann die andere LED?
#5368614
Lesenswert?

Hi,
hab dir mal dein Code bisschen umgeschrieben das die Delays da raus 
sind. Sollte sich alles selbst erkären. So kann der µcontroller noch 
andere Dinge außer "warten" machen.

const int ledPin = 13;
const int ledPin2 = 7;
bool interrupt = 0;

void setup()
{
 pinMode(ledPin, OUTPUT);
 pinMode(ledPin2, OUTPUT);
 attachInterrupt(1, pin_ISR_1, RISING);
}

void loop()
{
static long timer1=0;
static long timer2=0;

if (millis()-timer1>=500){
 timer1+=500;
 digitalWrite(ledPin2, digitalRead(ledPin2)^1);  // wechselt ~alle 500ms
 }
if (interrupt == 1){
 digitalWrite(ledPin, HIGH);   // letzt Led nach Interrupt
 interrupt = 0;
 timer2=millis();
 }
if (abs(timer2-millis())>3000){ // Schaltet nach 3 Sec die Led wieder 
aus
 digitalWrite(ledPin, LOW);
 }

//
//Hier könnte noch viel viel mehr code stehen.
//

}

void pin_ISR_1()
{
interrupt = 1;
}

Hab den jetzt nicht getestet aber sollte so schon passen... und nicht 
den Pulldown Widerstand vergessen.

MfG
M.V
OP #5368642
Lesenswert?

Georg M. schrieb:
> Note
> Inside the attached function, delay() won’t work

Dann hab ich sowieso ein größeres Problem. Diesen Code hab ich nur 
schnell geschrieben, um generell die Funktion des Interrupts zu testen.
In meinem eigentlichen Code für mein Projekt hab ich im Interrupt 
mehrere delays drin. Und der Code ist generell länger!


Code für Interrupt:

void showBATTERY()
{
  batteryVALUE = ((int32_t)analogRead(battery) * 1000l)/1024; // 
Umwandlung von Analog in Digital

 if (batteryVALUE < 750) // Bedingung
  {
    digitalWrite(ledRED , HIGH);  // Wenn Bedingung erfüllt, wird ledRED 
auf High gesetzt
    delay(3000);
    digitalWrite(ledRED , LOW);
  }
 else
  {
    digitalWrite(ledRED , LOW);  //Wenn Bedingung nicht erfüllt, wird 
ledRED auf Low gesetzt
  }
 if (batteryVALUE > 750) // Bedingung
  {
    digitalWrite(ledGREEN , HIGH); // Wenn Bedingung erfüllt, wird 
ledGREEN auf High gesetzt
    delay(3000);
    digitalWrite(ledGREEN , LOW);
  }
 else
  {
    digitalWrite(ledGREEN , LOW); // Wenn Bedingung nicht erfüllt, wird 
ledGREEN auf Low gesetzt
  }
}
OP #5368667
Lesenswert?

Ich könnte mich auch damit anfreunden, dass ich die delays komplett 
rauswerfe...

void showBATTERY()
{
  batteryVALUE = ((int32_t)analogRead(battery) * 1000l)/1024; //
Umwandlung von Analog in Digital

 if (batteryVALUE < 750) // Bedingung
  {
    digitalWrite(ledRED , HIGH);  // Wenn Bedingung erfüllt, wird ledRED
auf High gesetzt
  }
 else
  {
    digitalWrite(ledRED , LOW);  //Wenn Bedingung nicht erfüllt, wird
ledRED auf Low gesetzt
  }
 if (batteryVALUE > 750) // Bedingung
  {
    digitalWrite(ledGREEN , HIGH); // Wenn Bedingung erfüllt, wird
ledGREEN auf High gesetzt
  }
 else
  {
    digitalWrite(ledGREEN , LOW); // Wenn Bedingung nicht erfüllt, wird
ledGREEN auf Low gesetzt
  }
}
OP #5368703
Lesenswert?

Michael V. schrieb:
> Wenn das blinken unwichtig ist.

es soll ja nicht blinken, sondern für eine gewisse zeit die led leuchten 
lassen und dann wieder ausgehen. aber ich kann damit leben, wenn dann 
die entsprechende led dauerhaft leuchtet bis zu einem reset.

das problem ist aber, dass es ohne die delays auch nicht so richtig 
funktioniert.
wenn ich am analogen eingang die spannung auf über 7,5 Volt drehe und 
den taster drücke, dann schaltet es von der roten led auf die grüne 
um...so weit so gut, aber wenn ich den taster bei der gleichen spannung 
erneut drücke, dann schaltet es wieder auf die rote led um
OP #5368713
Lesenswert?

Michael V. schrieb:
> Hi,
> hab dir mal dein Code bisschen umgeschrieben das die Delays da raus
> sind. Sollte sich alles selbst erkären. So kann der µcontroller noch
> andere Dinge außer "warten" machen.

das ist gut gemeint, aber das ist bei meinem loop-programm leider nicht 
möglich, da dort nur mein hauptcode drin stehen darf, da es sich um eine 
zeitabhängige programmierung im ms-bereich handelt und da kann ich mir 
keine weitere zeitverzögerung erlauben.
OP #5368741
Lesenswert?

ich weiß, der schaltplan ist etwas unkonventionell gemacht...aber das 
sollte jetzt egal sein!


Gesamter Code:

const int impECU = A1;    // impECU den Pin A1 zuweisen
const int ledBLUE = 4;     // ledBLUE den Pin 4 zuweisen
int impVALUE = 0;  // den Wert von impVALUE auf Null setzen
const int REED = 2;  // REED den Pin 2 zuweisen
const int RELAY = 8; // RELAY den Pin 8 zuweisen
const int battery = A0;    // battery den Pin A0 zuweisen
const int ledRED = 13;      // ledRED den Pin 13 zuweisen
const int ledGREEN = 7;     // ledGREEN den Pin 7 zuweisen
int batteryVALUE = 0;  // den Wert von batteryVALUE auf Null setzen

void setup()
{
  pinMode(impECU, INPUT);  // impECU als INPUT deklarieren
  pinMode(ledBLUE, OUTPUT);  // ledBLUE als OUTPUT deklarieren
  pinMode(REED , INPUT);  //  REED als INPUT deklarieren
  pinMode(RELAY , OUTPUT);  // RELAY als OUTPUT deklarieren
  pinMode(ledRED, OUTPUT);  // ledRED als OUTPUT deklarieren
  pinMode(ledGREEN, OUTPUT);// ledGREEN als OUTPUT deklarieren
  pinMode(battery, INPUT);  // battery als INPUT deklarieren
  attachInterrupt(1, showBATTERY, RISING);
}

void loop()
{
  impVALUE = ((int32_t)analogRead(impECU) * 1000l)/1024; // Umwandlung 
von Analog in Digital

 if (impVALUE > 700) // Bedingung (größer als 7 Volt)
  {
    digitalWrite(ledBLUE , HIGH);  // Wenn Bedingung erfüllt, wird 
ledBLUE auf High gesetzt
  }
 else
    digitalWrite(ledBLUE , LOW);  // Wenn Bedingung nicht erfüllt, wird 
ledBLUE auf LOW gesetzt

 if (digitalRead(REED) == HIGH)  // Bedingung
  {
    digitalWrite(RELAY , HIGH);  // RELAY wird auf HIGH gesetzt
    delay(70);  // 70ms Pause
    digitalWrite(RELAY , LOW);  // RELAY wird auf LOW gesetzt

    do
    {  delay(10); // 10ms Pause
    }
    while(digitalRead(REED) == HIGH); // Abfrage, ob Taster wieder 
losgelassen wurde
  }
}
void showBATTERY()
{
  batteryVALUE = ((int32_t)analogRead(battery) * 1000l)/1024; // 
Umwandlung von Analog in Digital

 if (batteryVALUE < 750) // Bedingung
  {
    digitalWrite(ledRED , HIGH);  // Wenn Bedingung erfüllt, wird ledRED 
auf High gesetzt
  }
 else
  {
    digitalWrite(ledRED , LOW);  //Wenn Bedingung nicht erfüllt, wird 
ledRED auf Low gesetzt
  }
 if (batteryVALUE > 750) // Bedingung
  {
    digitalWrite(ledGREEN , HIGH); // Wenn Bedingung erfüllt, wird 
ledGREEN auf High gesetzt
  }
 else
  {
    digitalWrite(ledGREEN , LOW); // Wenn Bedingung nicht erfüllt, wird 
ledGREEN auf Low gesetzt
  }
}
Angehängte Dateien:
#5368785
Lesenswert?

zusätzlich sind da noch eine menge "Fehler" drin. Entweder in der 
Zeichnung und/auch von der Lokik her.

Das dürfte alles so nicht Funktionieren. Wenn die Betriebsspannung auf 
unter 9.5 V geht hört der Festspannungsregler auf zu arbeiten. Somit 
kein Strom für den µController somit keine Lampen Leuchten. Du kannst 
halt mit deiner Anordnung nur von 12-9.5 V messen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren