Interrupt routine Arduino Leoanrdo

Hallo,

habe in meinem Programm eine Funktion, die meine Batteriespannung überprüft und wenn diese zu niedrig ist, soll ein Alarm ausgegeben werden.

Nun wollte ich diese Funktion anhand einer Interrupt routine ausführen , sodass unabhängig vom Programm jede 2 minuten meine Batterie überprüft.

Habe auch dazu folgendes gefunden, jedoch scheint es nicht für den Leonardo geeignet zu sein:

http://playground.arduino.cc/Deutsch/HalloWeltMitInterruptUndTimerlibrary

Könnte ich diese doch verwenden oder habt ihr noch eine andere Alternative bzw, Tipp wie ich das realisieren kann?

Interrupts sind für sowas langsames völliger Unsinn.

Verwende einfach millis() und frag ab ob die Zeit verstrichen ist:

Auf dem Arduino läuft auf Timer0 schon ein Zähler den man man mit millis() abfragen kann. Also braucht man keinen zweiten Timer. Sowas macht man nur wenn etwas sehr schnell und/oder regelmäßig gehen soll. Deine Zeit ist aber extrem lange und außerdem ist es egal ob das mal ein paar µs oder ms früher oder später geschieht.

@Serenify, danke sehr, stimmt hast recht ist einfacher sogar und kann auch das so machen :D.

D.h. kann sagen überprüfe jede 2 minuten die Batteriespannung, während das Programm läuft, habe ich das richtig verstanden?-- indem man die vorherige Zeit, in der die funktion ausgeführt wurde mit der aktuellen zeit subtrahiert wird und mit der intervallzeit verglichen wird?

Danke dir

Ja

Dafür sollte man auf delay() verzichten, damit loop() so schnell wie möglich durchläuft. Aber bei zwei Minuten ist das auch nicht so extrem wichtig.

ok jetzt it mir das dank deinen guten Tipps klar. :smiley: seid echt klasse :D.
Inwiefern mit delays vermeiden? - wie meinst du das? -> etwa anstatt delay-funkntionen millis verwenden?

milito:
Inwiefern mit delays vermeiden? - wie meinst du das? -> etwa anstatt delay-funkntionen millis verwenden?

Ja genau; aber wenn Du delays von eingen Sekunden hast ist dies auch kein Problem da somit die Frequenz der Batteriekontrolle sich maximal um die delay()-Zeit schwankt.
Du kannst aber auch jegliche Intervallkontrolle weglassen und bei jedem loop()-Durchgang messen. Es bringt Dir keine Vorteile dies nur selten zu machen da die Messunf keinen zusätzlichen Stromverbrauch verursacht.
Grüße Uwe

Hi hab nach langer zeit das jetzt ausprobiert und es funktioniert danke euch.

nun wollte ich fragen, ist es möglich die Batterie beim Systemstart zu überprüfen und dann jede 2 minuten?

Weil die Lösung ist ja dass er erst nach einer bestimmten Zeit den Batteriecheck ausführt.
Ich will das so realisieren, dass er beim systemstart die Batterieüberprüft und danach jede 2 minuten

Gibt es das eine Möglichkeit?

Vllt, das ich diese in void setup() einfüge-> diese wird beim start des Programms einamlig ausgeführt?

Genau. Alles was einmal am Anfang gemacht werden soll kommt in setup().

Packe dazu deinen Überprüfungs-Code in eine eigene Funktion. Die kannst du dann von mehrere Stellen aus aufrufen.

ah perfekt danke :slight_smile:

hi wie meisnt du das?

Ich habe das mit milli gemacht -> http://arduino.cc/en/Tutorial/BlinkWithoutDelay

oder wie meinst du das mit dem Überpürfungscode?

void setup()
{
    checkBattery();
}

void loop()
{
     if(millis() .... )
     {
          checkBattery();
     }
}

void checkBattery()
{
   ...
}

Geht allerdings auch anders. Da man das hat

if(currentMillis - previousMillis > interval)

kann man previousMillis so vorbesetzten, dass der Vergleich am Anfang immer wahr ist und damit der Code gleich beim ersten mal ausgeführt wird. Dabei nutzt man aus dass bei unsigned Variablen z.B. 0 - 1000 eine positive Zahl ist, und damit größer als Interval wird.

Das in setup() zu schreiben ist aber wesentlich deutlicher und sauberer.

Ah ok stimmt danke hast recht ;). Thanks manchmal ist das so einfach, aber man macht sich immer das leben schwer :).

Achso ok, d.h. gebe PreviousMillis nicht 0 sondern zb schon eine Zeitangabe, z.b. previousMillis= 1000; ?

Danke @serenify

previousMillis und currentMillis sollten ja beide unsigned long sein. Wenn dann previousMillis 1000 ist und millis() den Wert 0 hat (oder vielleicht 1 wenn setup() mehr Zeit braucht), hat man 0 - 1000. Da der Wertebereich aber nur positiv ist hat man einen Überlauf und die Differenz ist ist in der Nähe des oberen Limits von unsigned long.

Aber wie gesagt, ist das nicht wirklich schön und man sieht auch den ersten Blick nicht was gemacht wird.

Danke sehr serenify :D.

Hab eine andere frage bzgl den sleep modus zum xbee S1. Habe herausgefunden, dass man anhand der Parameter Einstellungen SM und D07 und dem verstellen vom DTR Pin (pin 9) am xbee diesen im schlafmodus versetzern kann es geht auch habe es getestet, aber verstehe folgendes nicht:

void xbeeSleep()
{
  pinMode(XBee_wake, INPUT); // put pin in a high impedence state
  digitalWrite(XBee_wake, HIGH);
}//end function
/*----------------------------------------------------------------------*/

/*----------------------------------------------------------------------*/
//xbeeWake function
void xbeeWake()
{
  pinMode(XBee_wake, OUTPUT);
  digitalWrite(XBee_wake, LOW);
}//end function

warum wird er beim Wake als Output und beim sleep als Input gesetzt?
Das ist mir unklar

Sieht nach nem kleinen Trick aus: pinMode auf Input mit dem entsprechendem digitalWrite High auf dem Pin aktiviert den internen Pullup-Widerstand. Somit wird der Pin des Xbee gegen die Versorgungspannung gezogen.

Hi der pullup wir doch mit INPUT_PULLUP aktiviert oder?
ja aber warum nicht OUTPUT?

bzw warum nicht beide Input oder Output?

milito:
Hi der pullup wir doch mit INPUT_PULLUP aktiviert oder?

Ja, beide Varainten sind möglich. INPUT_PULLUP kam aber erst später hinzu, in den Arduino-Anfangstagen war das weniger intuitive digitalWrite (pin, HIGH) noch nötig. Macht man das heute, ist man zumindest zu alten IDE-Versionen kompatibel.

milito:
bzw warum nicht beide Input oder Output?

Warum das so gemacht wird weiß ich nicht, habe da keine Erfahrungen mit den Xbees. Könnte mir vorstellen, dass ein Arduino-Pin als Ausgang mit direktem HIGH oder LOW das selbe bewirkt - reine Vermutung meienrseits, also nicht ohne Nachfrage ausprobieren.

Ich kann mir nur eins (oder das andere) vorstellen:
Wenn der internen Pullup reicht um die Leitung auf 1 zu ziehen ...
Dann spart man evtl. einen Winz Batterieladung gegenüber einer aktiven 1, und man spart einen Widerstand.
Oder deswegen auf input gesetzt, damit man es nicht versehentlich auf 0 zieht..... (DAU Sicherung)