Also die Sleep-Modes kapier ich nicht so recht.
Folgendes Problem:
Programmier gerade für Arduino eine Steuerung für Gardena Bewässerung
WT1030. Klappt auch dank der Infos hier im Forum recht gut. Nun will ich
das Ganze batteriefähig machen und quäle mich deshalb mit den
Sleep_modes rum.
Also Homematic Batterie Autor gibt für die Dauer der Bewässerung einen
Pegel an den Pin2 des Arduino.
Bei der steigenden Flanke erzeugt der Arduino den Impuls zum öffnen des
Ventils und bei der fallenden Flanke einen kurzen Schließimpuls.
Jetzt hab ich Folgendes getestet:
Hat der Pin2 High-Pegel erzeuge ich den kurzen Ein-Impuls und rufe dann
SLEEP_MODE_PWR_DOWN mit
1
attachInterrupt(interruptNumber,wakeUpNow,LOW)
auf, damit sich der Arduino bis zum LOW an Pin2 schlafen legt. Das
klappt soweit.
Hat Pin2 LOW-Pegel erzeuge ich den kurzen AUS Impuls und rufe dann
SLEEP_MODE_IDLE auf, weil ich ja nur im IDLE Mode die nächste Flanke
Triggern kann.
Klapp auch soweit.
In meiner Loop() hab ich so ein bisschen Debug Code um das ganze zu
testen.
Da steht dann u.a.
Dabei stelle ich fest, dass im SLEEP_MODE_IDLE die Loop() permanent
durchlaufen werden, natürlich mit konstantem zaehler (der wird in der
ISR inkrementiert).
Aber wieso loopt er weiter ?? Der sollte doch nach sleepNow() stoppen?
Hoffe, ich hab mich einigermaßen verständlich ausgedrückt und jemand
kann helfen
Danke Reiner
Reiner W. schrieb:> ist nur ein Auszug
Sorry, aber ohne vollständigem Code können wir dir nicht richtig helfen.
BTW: Du kannst den Controller übrigens auch die ganze Zeit lang im
Powerdown lassen, wenn Du Pin-Change-Interrupts benutzt. Und manche
Interrupts auf Low-Level werden die ganze Zeit lang durchgehend
getriggert (-> ISR wird dauernd aufgerufen + µC wird dauernd
aufgeweckt).
Gruß
Jonathan
//Taster braucht gar nicht mehr abgefragt werden, weil er ja ohne tasterdruck gar nicht hier landet
81
zaehler++;// Zähler inkrementieren (+1)
82
}
Offenbar geht er gar nicht in den Sleep_Mode, weil die beiden
Debugausgaben aus sleepNow() permanent im Monitor kommen:
ich geh schlafenJupp, da bin ich wieder
?? Was mach ich falsch ? hat jemand einen Tipp?
Reiner
Du kannst übrigens anstatt dem IDLE-Modus auch den POWER-DOWN-Modus
nehmen. Außerdem hasse ich solche vorgebastelten
Konfigurations-Funktionen, weil man nie weiß, wie die Funktion die
Register jetzt wirklich setzt. Da ist mir ein klares, einfaches "SBI
DDRA, 2" doch lieber als ein "PinMode(2, OUTPUT)"...
Außerdem wird dein Code ganz schön Overhead haben, wenn Du "tasterPin",
"ledPin" und "interruptNumber" als Variablen deklarierst - falls dein
Compiler das nicht wegoptimiert. Falls er's nicht wegoptimiert, besteht
übrigens auch die Wahrscheinlichkeit, dass der Compiler da
durcheinanderkommt und totalen Müll produziert. Benutz' doch Konstanten
für solche Konfigurationssachen - dazu wurden sie doch gemacht!
Ja, es ist ein Atmega328P.
Mit deinen Bemerkungen hast du natürlich recht. Im endgültigen Code
sollen nur noch Konstanten drin sein.
Lese mich grad intensiver in die AVR Programmierung ein um direkter
programmieren zu können.
Den POWER-DOWN Modus hab ich ja problemlos hinbekommen. Das Problem ist,
dass ich mich da nur per LOW am Eingang wecken lassen kann.
Ich muss aber bei jeder Flanke einen Ausgangsimpuls erzeugen, die auch
noch unterschiedliche Länge haben.
Dazwischen liegen 0,5-2h, deshalb will ich ihn dazwischen in den Sleep
Mode schicken.
Wie komme ich beim POWER-DOWN mit ner positiven Flanke wieder zurück?
Deshalb dachte ich, ich Wechsel je nach Eingangslevel den SLEEP-MODE.
Wenn Pin2==HIGH -> aktiviere POWER-DOWN und weckmich mit LOW
Wenn Pin2==LOW -> aktiviere IDLE Sleep Mode und wecke mich bei der
nächsten Flanke (CHANGE)
Oder gibt es dafür einfacherer Lösungen?
Reiner
Hallo Reiner,
ich habe nur ueberflogen.
- idle wacht auf bei allem moeglichen und die instruction danach wird
noch ausgefuehrt. Alles moegliche sind z.b. interrupts von timern oder
rs232 oder pinchange.
- in c muss man erst den modus einstellen, dann sleep_enable();
aufrufen.
- theoretisch kannst du auch pollen: watchdog timeout auf 250ms
einstellen. In der watchdog ISR
* watchdog interrupt reaktivieren
* taster abfragen
* je nach ergebnis in der main wieder schlafen schicken
* oder wach bleiben und wichtiges tun
Das kannst du alles im power down modus. Der braucht vergleichsweise
lange zum wachwerden. Das ist aber egal, weil er danach nur sehr wenig
Strom verbraucht.
- Diese ganzen Stromsparsachen sind sehr frickelig. Aktivier unbedingt
den brownout. Statische Elektrizitaet reicht sonst schon aus, um den
ausgeschalteten controller zu starten und im power down bleiben zu
lassen. Und dort natuerlich abgestuerzt.
- Teste den Stromverbrauch. ADC verbraucht z.b. 200uA. Steht auch im
Datenblatt, nur sehr versteckt. Strom teste ich ueber einen 1k ohm shunt
in Reihe. D.h. booten, idlen, 1k in Versorgungsspannung parallel
einschleifen, Versorgungsspannung trennen.
Man macht zuerst nur die Applikation.
Und wenn alles einwandfrei läuft, erst dann fügt man den Sleepmode
hinzu:
Beitrag "AVR Sleep Mode / Knight Rider"
Peter
Reiner W. schrieb:> Den POWER-DOWN Modus hab ich ja problemlos hinbekommen. Das Problem ist,> dass ich mich da nur per LOW am Eingang wecken lassen kann.
Stimmt, hatte die Fußnote im Datenblatt nicht gelesen.
Reiner W. schrieb:> Oder gibt es dafür einfacherer Lösungen?
Per Monoflop bei jedem Wechsel einen kurzen Low-Impuls auf den Int-Pin
geben? Oder das Signal auf einen Int-Pin nichtinvertiert und auf einen
anderen invertiert geben?
Oder vielleicht die Arduino-Entwicklungsumgebung in die Tonne treten und
was gescheites nehmen? ^^
Nimm doch einfach den GCC, such dir die entsprechenden
Konfigurations-Register aus dem Datenblatt zusammen und schreib das
alles ohne diese ganzen Black Boxes von Konfigurationsroutinen. Das kann
man viel besser debuggen und man weiß wenigstens, was der Controller
denn jetzt wirklich macht.
Und wie Peter Dannegger schon schrieb: Erst das Programm, danach die
Stromsparmaßnahmen.
Gruß
Jonathan
Jonathan Strobl schrieb:> Per Monoflop bei jedem Wechsel einen kurzen Low-Impuls auf den Int-Pin> geben?
Ja, daran hab ich gedacht, obwohl es mir widerstrebt, Hardware zu
nehmen, wenn es Software auch tun könnte.
Oder das Signal auf einen Int-Pin nichtinvertiert und auf einen
> anderen invertiert geben?
Ja, genug Pins sind ja da. Ich könnte im POWER_DOWN bleiben und müßte
mit jedem Impuls nur den Int-Pin wechseln. Bleibt ein Inverter übrig,
den ich basteln muss.
>Oder vielleicht die Arduino-Entwicklungsumgebung in die Tonne treten und>was gescheites nehmen? ^^
Ja, da hätte ich noch einige andere Teile rumliegen;-) Aber so leicht
aufgeben wollte ich auch nicht.
>Nimm doch einfach den GCC, such dir die entsprechenden>Konfigurations-Register aus dem Datenblatt zusammen und schreib das>alles ohne diese ganzen Black Boxes von Konfigurationsroutinen. Das kann>man viel besser debuggen und man weiß wenigstens, was der Controller>denn jetzt wirklich macht.
An dem Punkt bin ich gerade;-)
@Peter
Na ja, das läuft eigentlich ganz gut. Halt nur mit Pin_Change_Int.
Der Link ist klasse. Das acker ich gleich mal durch.
Reiner