Forum: Mikrocontroller und Digitale Elektronik Arduino Interrupt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dan N. (noname88)


Bewertung
0 lesenswert
nicht 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. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht lesenswert
im Anhang der Schaltplan

von Dan N. (noname88)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Wenn das blinken unwichtig ist.

von Dan N. (noname88)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Sei froh das der noch irgendwas macht !

Spannung vom Analogen Eingang sind 0-5V

von Dan N. (noname88)


Bewertung
0 lesenswert
nicht 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)


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

: Bearbeitet durch User
von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.