Forum: Mikrocontroller und Digitale Elektronik Arduino Interrupt


von Dan N. (noname88)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?

: Bearbeitet durch Moderator
von Dan N. (noname88)


Angehängte Dateien:

Lesenswert?

im Anhang der Schaltplan

von Dan N. (noname88)


Lesenswert?

Lothar M. schrieb:
>> Leider reagiert der Interrupt...
> Und was macht dann die andere LED?

Die andere LED blinkt ganz normal weiter...

von Georg M. (g_m)


Lesenswert?

Dan N. schrieb:
> 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).

Note
Inside the attached function, delay() won’t work

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dan N. schrieb:
> im Anhang der Schaltplan
Da fehlt ein Pulldown für einen halbwegs definierten Low-Pegel...

Du könntest auch den Pullup im uC-Pin aktivieren und mit dem Taster nach 
GND schalten. So machen es alle Anderen.

: Bearbeitet durch Moderator
von Michael M. (michael89)


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

: Bearbeitet durch User
von Dan N. (noname88)


Lesenswert?

Lothar M. schrieb:
> Da fehlt ein Pulldown für einen halbwegs definierten Low-Pegel...

Oh, ja klar...den hab ich vergessen!

von Dan N. (noname88)


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
  }
}

von Michael M. (michael89)


Lesenswert?

ne so wird das auch nichts, aber mit mein Ansatz sollte dein Problem zu 
lösen sein.

MfG
M.V

von S. Landolt (Gast)


Lesenswert?

„Und bist du nicht willig, so brauch’ ich Gewalt.“
Sagte der Arduino zum Programmierer und schmiss das delay aus der ISR.

von Dan N. (noname88)


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
  }
}

von Michael M. (michael89)


Lesenswert?

Wenn das blinken unwichtig ist.

von Dan N. (noname88)


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

von Dan N. (noname88)


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.

von Michael M. (michael89)


Lesenswert?

Sei froh das der noch irgendwas macht !

Spannung vom Analogen Eingang sind 0-5V

von Dan N. (noname88)


Lesenswert?

Michael V. schrieb:
> Sei froh das der noch irgendwas macht !
>
> Spannung vom Analogen Eingang sind 0-5V

keine sorge, ich hab nen spannungsteiler drin. maximal liegen 4,5 Volt 
an!

von Michael M. (michael89)


Lesenswert?

kannst du mal dein ganzen Code und Schaltplan posten? Dann kann man dir 
besser helfen.

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

Dan N. schrieb:
> da es sich um eine zeitabhängige programmierung im ms-bereich handelt
> und da kann ich mir keine weitere zeitverzögerung erlauben.

Aber sekundenlange Unterbrechung im Int ist ok? Statemachine wäre ein 
Stichwort für eine Lösung.

von Dan N. (noname88)


Angehängte Dateien:

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
  }
}

von Michael M. (michael89)


Lesenswert?

bei A0 soll doch sicher +12V nicht +9 Volt gemessen werden ? hast du das 
so in der realität ?

Welche Relais benutzt du ?

von Michael M. (michael89)


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.

von Dan N. (noname88)


Lesenswert?

Michael V. schrieb:
> bei A0 soll doch sicher +12V nicht +9 Volt gemessen werden ? hast
> du das
> so in der realität ?
>
> Welche Relais benutzt du ?

doch die 9 volt stimmen, da hängt zusätzlich eine 9V Bolckbatterie 
dran...diese soll eben überwacht werden.

von Michael M. (michael89)


Lesenswert?

War beim ersten blick nicht so klar -.-

ich muss jetzt los hab, aber dein Problem verstanden meld mich später 
oder morgen mal.

von Dan N. (noname88)


Lesenswert?

Michael V. schrieb:
> War beim ersten blick nicht so klar -.-
>
> ich muss jetzt los hab, aber dein Problem verstanden meld mich später
> oder morgen mal.

ich muss auch los und bin erst am wochenende wieder online

von Eric B. (beric)


Angehängte Dateien:

Lesenswert?

Zur Inspiration ;-)

(Edit: Hm, die erste Datei bitte ignorieren - habe ein bisschen 
nachgebessert. Kann aber die Datei im Beitrag nicht löschen)

: Bearbeitet durch User
von Dan N. (noname88)


Lesenswert?

Eric B. schrieb:
> Zur Inspiration ;-)
>
> (Edit: Hm, die erste Datei bitte ignorieren - habe ein bisschen
> nachgebessert. Kann aber die Datei im Beitrag nicht löschen)

Danke...das ist etwas zu hoch für mich ;-)
Ich bin ja ein Arduino-Neuling...

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.