PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino Interrupt



Cysign
07.06.2015, 18:52
Hallo zusammen,

ich spiele grade mit nem Arduino und Interrupten rum, allerdings will das vorne und hinten nicht, wie ich mir das vorstelle.


#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

int irPin = 1; // interrupt 1 => digital pin 3

void setup()
{
lcd.init();
lcd.setCursor(0,0);
lcd.print("blablabla");
lcd.backlight();

attachInterrupt(irPin, myFunction, FALLING);
}


void loop()
{
delay(5000);
lcd.backlight();
}


void myFunction()
{
lcd.noBacklight();
}




Ich hätte gerne eine Delay-Funktion, die solange ausgeführt wird, bis ich Pin 3 (=Interrupt 1) per Taster auf Gnd lege.

Der Beispielcode von http://www.dave-auld.net/?option=com_content&view=article&id=107:arduino-interrupts&catid=53:arduino-input-output-basics&Itemid=107 unter "Making Use of Interrupts" führt bei mir dazu, dass der geschaltete Pin unendlich oft schaltet, bis ich den Interrput-Pin auf Masse lege, statt dass der Pin ruht, bis ich den Taster drücke.

Hat jemand vielleicht ein einfaches, funktionierendes Beispiel für einen Interrupt?


Ich würde gerne meinen Arduino eine Weile ruhen lassen, nach dieser Zeit soll einen Abfrage gestartet werden.
Wird vorher der Taster an Pin 3 gedrückt, soll mittels Interrupt das Ruhen unterbrochen werden und das Hintergrundlicht vom Display eingeschaltet werden (bzw. hier im Beispiel ausgeschaltet).

HeXPloreR
08.06.2015, 08:23
Hallo Cysign,

wenn ich das richtig sehen dann fehlt in deinem Setup der pinMode für den Button. Und die Zeile " int irPin = 1; " ist möglicherweise überflüssig.
Wichtig ist auch wie der Button tatsächlich auf dem Board verschaltet ist - also als PullUp oder PullDown.


Viele Grüße
Jörg

Cysign
09.06.2015, 01:16
Hallo Jörg, du hast vollkommen Recht mit deiner Aussage. Ich hab da gestern einfach so lange dran gesessen, dass ich irgendwann nur noch durch war ;)

Der Code hier funktioniert:

int ledPin = A5;
volatile int state = HIGH;
#include "sdelay.h"

void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(3, HIGH);
attachInterrupt(1, blink, FALLING);
}

void loop()
{
for (int i=0; i<100; i++)
{
sdelay(1000);
}

}

void blink()
{
state = !state;
digitalWrite(ledPin, state);
}




Wohingegen es nicht funktioniert, aus der ISR heraus ein über i2c angeschlossenes Display über die LiquidCrystal_I2C.h zu steuern:

#include "sdelay.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);


volatile int state = HIGH;


void setup()
{
digitalWrite(3, HIGH);
attachInterrupt(1, blink, FALLING);

lcd.init();
lcd.setCursor(0,0);
lcd.print("blablabla");
lcd.backlight();
}

void loop()
{
lcd.backlight();
sdelay(100);
}

void blink()
{
lcd.clear();
lcd.print("*");
}




Scheinbar kann ich aus der ISR heraus nicht auf externe Funktionen zugreifen.
Ich hab das Problem jetzt testweise folgendermaßen umschifft:



#include "sdelay.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

int activated = 0;
volatile int state = HIGH;


void setup()
{
digitalWrite(3, HIGH);
attachInterrupt(1, blink, FALLING);

lcd.init();
lcd.setCursor(0,0);
lcd.print("blablabla");
lcd.noBacklight();
}

void loop()
{
if (activated == 0)
{
sdelay(2000);
}
else
{
lcd.backlight();
sdelay(4000);
lcd.noBacklight();
activated = 0;
}

}

void blink()
{
activated = 1;
}

HeXPloreR
09.06.2015, 11:53
Hallo, das würde ich nicht umschiffen nennen - sondern jetzt richtige Benutzung des Interrupt. Der pin Mode fehtl übrigens jetzt schon wieder. Vielleciht macht es langsamm Sinn zu schreiben was Du überhaupt machen möchtest damit. Grundsätzlich macht es keinen Sinn eine ISR als Dauerschleife betreiben zu wollen. Viele Grüße Jörg

Cysign
09.06.2015, 14:50
Ich möchte einen Arduino per Akku betreiben. Hierzu versetze ich ihn per https://github.com/cano64/ArduinoSleep sdelay() in den Stromsparmodus.
Alle paar Minuten soll er aufwachen und prüfen, ob etwas zu tun ist.

Allerdings soll er auch per Interrupt geweckt werden können, damit man über Knöpfe am Display Einstellungen vornehmen kann.

Bongo_1st
23.10.2015, 20:08
Hallo zusammen.
Ich versuche geraden die interrupt Funktion kennen zu lernen.
Ich würde gern bei einem LOW einen Text ausgeben.
Das Problem dabei, immer wenn der Arduino das LOW erhält stürzt er ab.
Ich gehe davon aus, dass meine "Schaltung" auf dem Steckbrett falsch ist.

D3 mit einem Kabel auf 5V (HIGH) und einen Widerstand 1K-Ohm auf GND (LOW)

Wenn der Pin die 5V erhält, läuft das Ganze, sobald ich das 5V Kabel entferne stürzt der Arduino ab.


void setup(){
Serial.begin(9600);
attachInterrupt(1, interrupt, LOW);
}

void loop()
{
for (int i = 0; i < 1000; i++)
{
Serial.println(i);
delay(100);
}
}

void interrupt()
{

Serial.println("Hallo");
}

Dank für die Hilfe

---------------------------------------------------------------------------------------------------------------

Nachtrag:
Habe soeben bemerkt, dass das Serial.println das Problem war....

So funktioniert es


int hallo = 0;

void setup()
{
Serial.begin(9600);
attachInterrupt(1, interrupt, LOW);
}

void loop()
{
for (int i = 0; i < 1000; i++)
{
if (hallo == 1)
{
Serial.println("Hallo");
hallo = 0;
delay (100);
}
else
{
Serial.println(i);
delay(100);
}
}
}

void interrupt()
{
hallo = 1;
delay(100);
}

Cysign
24.10.2015, 20:18
Ich bin irgendwann dazu übergegangen, auf Interrupts zu verzichten, da ich auch öfters das Problem hatte, einen freeze/unvorhersehbares Verhalten zu bekommen.
Aber evtl. befasse ich mich bald nochmal damit. An sich ist es ja ein schönes Feature.
Danke, dass du deine Problemlösung mit uns teilst ;)

Rabenauge
25.10.2015, 03:42
Nö, das Problem liegt wo anders.
Delay() funktioniert beim Arduino _nicht_ innerhalb eines Interrupt-Handlers.
https://www.arduino.cc/en/Reference/AttachInterrupt

Peter(TOO)
29.10.2015, 02:03
Hallo,

Ich möchte einen Arduino per Akku betreiben. Hierzu versetze ich ihn per https://github.com/cano64/ArduinoSleep sdelay() in den Stromsparmodus.
Alle paar Minuten soll er aufwachen und prüfen, ob etwas zu tun ist.

Allerdings soll er auch per Interrupt geweckt werden können, damit man über Knöpfe am Display Einstellungen vornehmen kann.

Das ist eigentlich kein Problem.
Eine CPU im Tiefschlaf, kann nur durch einen Interrupt wieder aufgeweckt werden (oder einen Reset, wobei Reset ein eigentlich spezieller Interrupt ist).
Wichtig ist nur, dass vor dem schlafen Gehen das für den Interrupt zuständige Modul aktiviert bleibt. Alle anderen können, um maximal Strom zu sparen, abgeschaltet werden.

sdelay(); wird einen Timer-Interrupt verwenden welcher die CPU periodisch aufweckt. Bei jedem Interrupt wird einfach der Delay-Wert runtergezählt und wenn dieser noch nicht abgelaufen ist, geht die CPU wieder pennen...

MfG Peter(TOO)

Cysign
29.10.2015, 08:49
Genau so siehts aus. Mit sdelay bin ich auf ca. 2,5mA bei einem blanken AtMega328 runtergekommen. Dazu habe ich einen Linearregler, der weitere 2mA verbrät, um den µC zu versorgen.

Was man bei sdelay(); allerdings beachten sollte: Der Timer, der den Interrupt ausführt, ist wirklich ziemlich ungenau. Da können 3 Schlafsekunden auch mal 5-6 Sekunden sein!

Peter(TOO)
29.10.2015, 14:49
Hallo,

Was man bei sdelay(); allerdings beachten sollte: Der Timer, der den Interrupt ausführt, ist wirklich ziemlich ungenau. Da können 3 Schlafsekunden auch mal 5-6 Sekunden sein!
Spricht für eine schlampige Implementierung.
Technisch ist es kein Problem, da eine genaue Zeit hinzubekommen, da bestimmt dann nur der Oszillator die Genauigkeit.

Aber ich kenne das Arduino-Betriebssystem noch nicht. Bis jetzt habe ich µCs immer direkt, ohne eine Betriebssystem, programmiert.

MfG Peter(TOO)

Cysign
29.10.2015, 16:49
Der Arduino-Bootloader hat nen ziemlichen Overhead. Ich denke, dass es daran liegen wird.

Unregistriert
30.01.2017, 17:11
Hallo zusammen, ich brauche da mal bitte eure Hilfe.

Ich schreibe demnächst eine Prüfung und muss einen Interrupt Code erstellen.
Die Aufgabenstellung lautet.

Erstellen Sie einen Interrupt Code:
-Golfbälle rollen eine Rampe herunter
-Sie durchlaufen eine Lichtschranke
-Die Zeit wird gemessen
-An der Lichtschranke liegen 5V an, wenn sie unterbrochen wird.

Könnt ihr mir bitte weiterhelfen und sagen wie dieser Code auszusehen hat.

Vielen Dank.

Cysign
30.01.2017, 17:47
Schön sollte er aussehen, mit Glitzer. Glitzer ist immer gut.
Und wenn er im Dunkeln leuchten kann, ist auch nicht verkehrt!

Ne, Spaß bei Seite.
Also am Sinnvollsten erstellst du dir erstmal ienen Account im Forum. Ist einfach freundlicher, wenn man Beiträge einem Usernamen zuordnen kann "Unregistriert...wer ist das? Schreiben wir da grade mit eine oder 3 Leuten?).
Dann wäre die Frage nach deinem aktuellen Wissensstand. Wie weit bist du mit deinen Überlegungen bisher und hast du schonmal was auf Arduino-Basis programmiert?

Niemand wird dir ohne eine finanzielle Aufwandsentschädigung deinen Code schreiben. Aber wir helfen dir gerne ;)
Am besten machst du dazu auch einen eigenen Thread auf.