Ich habe die Schlafoptionen des ATmega328 untersucht und ein paar Artikel darüber gelesen, und ich würde gerne verstehen, ob es weitere Optionen gibt.
Also möchte ich so wenig Strom wie möglich haben, damit alles, was unter 100 uA liegt, gut ist - solange ich auf uart hören kann und beim Aufwachen unterbricht.
Ich verwende eine benutzerdefinierte Platine (nicht die UNO) mit ATmega328p.
Versetzen des Chips in einen tiefen Schlaf:
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu ();
wäre es nicht aufwachen mit der seriellen Kommunikation auf, nach diesem .
Sie müssen es in den IDLE
Modus versetzen , um seriell zu hören, aber dies würde ein paar mA-Bad verbrauchen.
Ich habe diesen Link gefunden, über den Sie die serielle Schnittstelle der Hardware mit dem Interrupt verbinden können - was gefährlich ist, damit Sie Daten verlieren können. Außerdem benötige ich diese 2 Interrupt-Pins.
Ich habe auch diesen Artikel von Gammon gelesen , in dem Sie einige Dinge deaktivieren können, damit Sie mit viel weniger Energie LEERLAUF schlafen können - aber er hat nicht erwähnt, wie genau Sie davon profitieren:
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
Unterm Strich gibt es also eine Möglichkeit, weniger als 0,25 mA zu erhalten und auch den seriellen Anschluss ohne Hardwaremanipulation abzuhören? Zum Beispiel aufwachen mit langen seriellen Dateneingabe ?
Antworten:
Ein Board, das wir herstellen, macht das.
Im Ruhezustand ist der INT0-Interrupt mit niedrigem Pegel aktiviert
Die Interrupt-Serviceroutine INT0 setzt ein Flag und deaktiviert den Interrupt
Beim Aufwachen wird nach dem Flag gesucht (es gibt andere Interruptquellen)
Auf der Kommunikationsseite verwenden wir ein Nachrichtenprotokoll mit einem Start-
>
und einem Endzeichen\r
. zB>setrtc,2015,07,05,20,58,09\r
. Dies bietet einen grundlegenden Schutz vor Nachrichtenverlust, da eingehende Zeichen erst verarbeitet werden, wenn ein>
empfangen wird. Um das Gerät aufzuwecken, senden wir vor der Übertragung eine Dummy-Nachricht. Ein einzelner Charakter würde es tun, aber wir senden>wakeup\r
hehe.Das Gerät bleibt 30 Sekunden lang wach, nachdem die letzte Nachricht bei neuen Nachrichten eingegangen ist. Wenn eine neue Nachricht empfangen wird, wird der 30-Sekunden-Timer zurückgesetzt. Die PC-Schnittstellensoftware sendet jede Sekunde eine Dummy-Nachricht, um das Gerät wach zu halten, während der Benutzer es zur Konfiguration usw. angeschlossen hat.
Diese Methode gibt absolut keine Probleme. Das Board mit ein paar Peripheriegeräten verbraucht im Schlaf ca. 40uA. Der tatsächliche Stromverbrauch des ATMega328P liegt wahrscheinlich bei 4uA.
Aktualisieren
Ein Blick auf das Datenblatt zeigt, dass der RX-Pin auch Pin-Wechsel-Interrupt-Pin 16 (PCINT16) ist.
Somit kann eine andere Methode ohne Drähte sein
Vor dem Ruhezustand: Setzen Sie das Bit für die Portwechsel-Interrupt-Maske in PCMSK2 für PCINT16, löschen Sie das Flag für Pinwechsel-Port 2 in PCIFR und aktivieren Sie den Pinwechsel-Port 2-Interrupt (PCINT16-PCINT23), indem Sie PCIE2 in PCICR einstellen.
Richten Sie einen ISR für den Pinwechsel-Port 2-Interrupt ein und fahren Sie wie zuvor fort.
Die einzige Einschränkung beim Portwechsel-Interrupt besteht darin, dass der Interrupt von allen 8 Pins gemeinsam genutzt wird, die für diesen Port aktiviert sind. Wenn Sie also mehr als einen Pinwechsel für den Port aktiviert haben, müssen Sie feststellen, welcher den Interrupt im ISR ausgelöst hat. Dies ist kein Problem, wenn Sie keine anderen PIN-Wechsel-Interrupts an diesem Port verwenden (in diesem Fall PCINT16-PCINT23).
Im Idealfall hätte ich unser Board so entworfen, aber was wir haben, funktioniert.
quelle
Der folgende Code erreicht das, wonach Sie fragen:
Ich habe einen PIN-Wechsel-Interrupt am Rx-Pin verwendet, um festzustellen, wann serielle Daten ankommen. In diesem Test geht das Board in den Ruhezustand, wenn nach 5 Sekunden keine Aktivität stattfindet (die "Wake" -LED erlischt). Eingehende serielle Daten bewirken, dass der Pinwechsel-Interrupt die Karte aktiviert. Es sucht nach einer Nummer und blinkt die "grüne" LED so oft.
Gemessener Strom
Beim Betrieb mit 5 V habe ich im Schlaf einen Strom von ca. 120 nA gemessen (0,120 µA).
Nachricht erwecken
Ein Problem besteht jedoch darin, dass das erste ankommende Byte verloren geht, da die serielle Hardware einen fallenden Pegel auf Rx (dem Startbit) erwartet, der bereits eingetroffen ist, wenn es vollständig aktiviert ist.
Ich schlage vor (wie in der Antwort von geometrikal), dass Sie zuerst eine "Wach" -Nachricht senden und dann eine kurze Pause machen . Die Pause besteht darin, sicherzustellen, dass die Hardware das nächste Byte nicht als Teil der Aktivierungsnachricht interpretiert. Danach sollte es gut funktionieren.
Da hierbei ein PIN-Wechsel-Interrupt verwendet wird, ist keine weitere Hardware erforderlich.
Geänderte Version mit SoftwareSerial
In der folgenden Version wird das erste seriell empfangene Byte erfolgreich verarbeitet. Dies geschieht durch:
Verwenden von SoftwareSerial, das PIN-Wechsel-Interrupts verwendet. Der Interrupt, der durch das Startbit des ersten seriellen Bytes verursacht wird, weckt auch den Prozessor.
Stellen Sie die Sicherungen so ein, dass wir Folgendes verwenden:
Inspiriert von FarO in einem Kommentar, lässt dies den Prozessor in 6 Taktzyklen (750 ns) aufwachen. Bei 9600 Baud beträgt jede Bitzeit 1/9600 (104,2 µs), sodass die zusätzliche Verzögerung unbedeutend ist.
Der Stromverbrauch im Schlaf wurde mit 260 nA (0,260 µA) gemessen, was einen sehr geringen Verbrauch bedeutet, wenn er nicht benötigt wird.
Beachten Sie, dass der Prozessor mit den so eingestellten Sicherungen mit 8 MHz arbeitet. Dazu müssen Sie der IDE Bescheid geben (z. B. "Lilypad" als Kartentyp auswählen). Auf diese Weise arbeiten die Verzögerungen und SoftwareSerial mit der richtigen Geschwindigkeit.
quelle