Ich möchte gerne meinen IRMP Decoder in den Schlafmodus schicken und
wenn ein IR-Signal erkannt wird wieder aufwecken.
Das ganze sieht momentan so aus:
1
#include<avr/interrupt.h>
2
#include<avr/sleep.h>
3
#include<util/delay.h>
4
#include<stdlib.h>
5
#include<string.h>
6
#include"dogm.h"
7
#include"irmp.h"
8
9
voidtimer_init(void)
10
{
11
OCR1A=(F_CPU/F_INTERRUPTS)-1;// Vergleichswert: 1/15000 der CPU-Frequenz
12
TCCR1B=(1<<WGM12)|(1<<CS10);// schalte CTC-Modus ein, setze Vorteiler auf 1
// irmp_data.protocol ist das protokoll, siehe irmp.h
71
// irmp_data.address ist die Adresse / Hersteller Code des IR Sender
72
// irmp_data.command ist der Befehlscode
73
74
dogm_cursor(0,0);
75
dogm_puts("IRMP Decoder");
76
77
dogm_cursor(0,1);
78
dogm_puts("R: Code: ");
79
dogm_puts(Proto[irmp_data.protocol-1]);
80
81
dogm_cursor(0,2);
82
dogm_puts("A: ");
83
itoh(s,4,irmp_data.address);
84
dogm_puts(s);
85
dogm_puts(" C: ");
86
itoh(s,4,irmp_data.command);
87
dogm_puts(s);
88
89
_delay_ms(2000);
90
}
91
}
92
}
93
94
ISR(INT0_vect)
95
{
96
97
}
Ich denke der Ansatz ist schon in die richtige Richtung, nur
funktioniert das ganze noch nicht.
Die andere Frage die sich stellt ist, benötige ich dafür den Watch-dog
Timer?
Nachdem es leider keine brauchbare Anleitung im Netz gibt, hab ich nun
noch ein paar andere Varianten versucht.
Das Aufwecken funktioniert zwar, allerdings möchte ich gerne das die CPU
nach 2 Sekunden wieder in den Schlafmodus wechselt, wenn kein IR-Signal
empfangen wird.
Kann mir da jemand weiterhelfen?
Lokus Pokus schrieb:> allerdings möchte ich gerne das die CPU> nach 2 Sekunden wieder in den Schlafmodus wechselt, wenn kein IR-Signal> empfangen wird.
Dazu lässt du in dem IRMP Interrupt einen Zähler mitlaufen.
Wenn der bei 2s * (Anzahl der ints pro sekunde) angekommen ist, dann
wird wieder geschalfen....
Das Problem hier ist, dass wenn ein ungültiger IR-Puls kommt dein µC via
INT0 aufwacht und loslegt ohne den Timer wieder "scharf zu schalten" =>
er läuft so lange weiter bis ein gültiger Puls kommt.
Ok, ich denke ich bin schon einen Schritt naher.
Der Timer läuft und schaltet den AVR nach 2 Sekunden in den Schlafmodus,
leider lässt er sich davon nicht mehr aufwecken.
Interrupts sollten aktiv sein.
Wo liegt jetzt noch der Fehler?
Lokus Pokus schrieb:> Wo liegt jetzt noch der Fehler?
Sehe ich jetzt auch nicht direkt, sorry.
Aber eine kleine Bemerkung zu den volatiles: Die benutzt Du nur als
Flag, oder?
Dann verwende statt:
unsigned int
besser
unsigned char
Vorteil: Die Zugriffe ausserhalb der ISR sind dann atomar. Im Moment
sind sie es jedoch nicht. So könnte ein Konflikt entstehen.
Lokus Pokus schrieb:> Interrupts sollten aktiv sein.> Wo liegt jetzt noch der Fehler?
Erst kuckst Du hier:
1
MCUCR&=~((1<<ISC01)|(1<<ISC00));// Interrupt bei LOW an INT0
Da passt schon mal die Realität nicht zum Kommentar.
Dann schaust Du in's Datenblatt und erkennst, dass aus dem Power Down
nur ein Level Interrupt aufweckt.
Das Problem mit dem Aufwachen:
Dein µC wacht auf und rennt los.
Nach kurzer Zeit fragt dein Hauptprogramm beim IRMP nach ob neue Daten
da sind. Der sagt "Nein" (weil noch kein ganzes Packet da ist), also
geht das ganze Konstrukt wieder schlafen.
Lösung: Wenn du "frisch aufgewacht" bist (d.h. in der INT0 Routine)
musst du den Timer ebenfalls mit der Wartezeit aufladen (und die ganzen
Flag-Variablen zurechtstellen, da war ich ehrlichgesagt zu faul
nachzuvollziehen wozu jede Flag gut ist).
Was an deiner Config für MCUCR falsch ist versteh ich auch nicht....
Lokus Pokus schrieb:> Interrupts sollten aktiv sein.> Wo liegt jetzt noch der Fehler?
warum so umständlich?
du nutzt IRMP, dort sind die IRQ konstant um 60µs (bei 15k)
du willst nur 2s on sein, egal ob IR erkannt oder nicht
also eine Zählvariable vor dem Aufruf von IRMP in der ISR hochzählen
lassen
und 2s / angenommen 64µs (F_CPU/INTERRUPTS) -> das weisst nur du wieviel
INTERRUPTS du benutzt
also 2s / 64µs gibt 31250 als Zählerstand da darf der MC wieder schlafen
gehen.
schon nur dann wenn ein IR erkannt wird.
Was mich noch interessieren würde, ob man das ganze noch optimieren
könnte.
Die Schaltung benötigt im Schlafmodus 1,43mA
Im Betrieb 4,86mA
Werden die 1,4mA einzig alleine vom IR Empfänger verbraten?
Auch wenn kein Signal erkannt wird?
Den das LCD ist ja quasi inaktiv.
Ich verwende einen TSOP4836
Lokus Pokus schrieb:> schon nur dann wenn ein IR erkannt wird.
schreib noch mal verständlicher.....
aufwecken willst du den Tiny immer wenn IR Sighnal kommt, also mit der
fallenden Flanke vom TSOP evtl. mit pin change INT, der TSOP muss immer
an der Batterie nuckeln, ist leider so.
schlafen gehen soll er nach 2s deine Worte,
was ist wenn er keinen Code erkennt weil fremder Code kommt und den AVR
immer aufweckt aber nie ein Code erkannt wird?
denk über deine Aufgabenstellung noch mal nach, eventuell ist das alles
sinnlos, was sparst du denn an Batterie wenn jedes IR Signal den weckt?
und wenn er nix erkennt nie wieder schlafen geht?
Lokus Pokus schrieb:> Was stimmt daran nicht?
Doch, stimmt, mein Fehler.
Verfolge den Codeablauf: sleep_on wird nur einmal mit 0 initialisiert,
ist dann aber in Folge immer 1. Wenn nun CompA auslöst, sleep_timer beim
vorherigen Durchlauf bereits auf 0 herunter zählte, dann ist sleep_timer
immer noch 0, sleep_start wird sofort wieder auf 1 gesetzt, mit der
Folge, dass sofort wieder sleep() aufgerufen wird. Dieser Kreislauf
könnte nur durchbrochen werden, wenn irmp_get_data gültige Daten hätte
und sleep_timer erneut setzen würde. IRMP hat aber nie gültige Daten,
wenn der µC dauernd im Sleep ist.
Lokus Pokus schrieb:> Werden die 1,4mA einzig alleine vom IR Empfänger verbraten?
Kommt auf den TSOP an. Welchen hast Du denn? Die alten TSOP17xx
verbraten soviel - ja. Die neueren TSOP312xx sind zwar genügsamer, aber
auch nicht wirklich sparsam. Schau mal ins Datenblatt.
In
http://www.mikrocontroller.net/articles/DIY_Lernf%C3%A4hige_Fernbedienung_mit_IRMP
schalte ich die Versorgungsspannung des TSOP einfach ab - besser gesagt,
ich versorge diesen über einen ATmega-Pin. Ich weiß aber nicht, ob das
für Dich eine Lösung wäre. Der TSOP kann Deinen ATtiny dann jedenfalls
nicht mehr aufwecken... ;-)
Lokus Pokus schrieb:> Werden die 1,4mA einzig alleine vom IR Empfänger verbraten?
Ja.
Ich hab auch noch nie ein Batteriegerät mit FB gesehen.
Was soll denn das werden?
Lokus Pokus schrieb:> Werden die 1,4mA einzig alleine vom IR Empfänger verbraten?
Da gibt's Sparsameres, z.B. Sharp GP1UD26XK.
Man kann alle 2 Sekunden den IR-Empfänger gerade so lange eine
IR-Sequenz (plus ggf. Einschwingzeit des IR-Empfängers) einschalten.
Dann muss man eben 2+ Sekunden die Fernbedienung betätigen.
Ich werde mal einen TSOP34836 versuchen. Der soll laut Datenblatt nur
0,45mA verbrauchen. Das Teil ist von den Abmessungen her nur etwas
größer.
Bezüglich dem Zähler: Wenn ichr ichtig verstanden habe soll ich den AVR
immer alle 2 Sekunden wenn ein Signal (egal ob echtes oder keines)
erkannt wird schlafen geht.
Aber das macht er doch sowieso.
Verstehe nicht ganz worin der Unterschied nun zwischen einem Zähler der
bis 32250 zählen soll oder 2 Sekunden zählen soll ist.
Lokus Pokus schrieb:> Der Timer läuft und schaltet den AVR nach 2 Sekunden in den Schlafmodus,> leider lässt er sich davon nicht mehr aufwecken.Lokus Pokus schrieb:> Verstehe nicht ganz worin der Unterschied nun zwischen einem Zähler der> bis 32250 zählen soll oder 2 Sekunden zählen soll ist.
ja irgendwas muss bei deiner Programmierung ja faul sein
vielleicht doch eine Interaktion der beiden?
wenn ein IR Signal den AVR aufweckt du sowieso alle paar µs in die ISR
springst, warum dort nicht gleich auf 2s zählen? warum 2 Timer?
Lokus Pokus schrieb:> Wie kommst du auf 2 Timer?
weil ich aus deinem Text nicht schlau wurde?
Lokus Pokus schrieb:> Der Timer läuft und schaltet den AVR nach 2 Sekunden in den Schlafmodus,> leider lässt er sich davon nicht mehr aufwecken.
und wie soll der AVR aufwachen?
hat du einen PCINT auf low aktiviert?
OK soll auch mit INT0 gehen.
nur muss der auf falling edge initialisiert werden und die MC wakeup
time sollte nicht zu lang eingestellt sein sonst bekommt er ja nie einen
gültigen IR Code mit.
Beitrag "Re: ATtiny44 über IR-Signal aufwecken"
hast du dir das hier noch mal angesehen?
Das Problem mit dem aufwachen ist schon gelöst.
Hab die Aufwachroutine wie Max D. vorgeschlagen hat in den INT0_vect
kopiert.
Was mich allerdings mehr stört ist das selbst mit einem TSOP31236 der
laut Datenblatt, wenn ich das richtig gelesen habe, "nur" 0,35mA bei
3,3V verbrauchen sollte, die Schaltung immer noch 1,3mA im Schlafmodus
zieht.
Ich vermute mal das LCD hier als Ursache.
Mir ist noch nicht klar wie ich den Kontrast noch weiter herunterregeln
kann.
Normalerweise sind dafür ja C3, C2, C1 zuständig.
Die habe ich allerdings schon auf 0 gesetzt und trotzdem seh ich noch
schwarze Balken im Display.
Je nach Ausführung hat das LCD einen dedizierten Power-Down den man
ansprechen kann oder man muss einfach die Versorgung abschalten (über
einen weiteren AVR-Pin).
Welchen genauen Typ hast du denn ?
Lokus Pokus schrieb:> Nur Versorgungsspannung weg, hatte ich auch im Gedanken, allerdings> verbraucht die Schaltung dann minimal weniger.
Hast Du vorher auch alle Pins zum LCD auf low gesetzt?
nicht gezielt. Aber bis auf D4 sind automatisch alle auf LOW.
Allerdings kann ich das eher knicken. Denn bei 3,3V nimmt mir ein
Transistor zum Schalten zuviel Spannung weg.
Und die Versorgung einfach auf éinem AVR Pin zu legen funktioniert auch
nicht.
Lokus Pokus schrieb:> Allerdings kann ich das eher knicken. Denn bei 3,3V nimmt mir ein> Transistor zum Schalten zuviel Spannung weg.
falsch beschaltet, bei richtiger Beschaltung verlierst du nur 0,1V
welches DOG hast du, die paar mA kann auch der Port.
die Beschaltung war schon richtig, allerdings sieht es so aus als würde
das LCD beim Einschalten nicht schnell genug initialisiert werden, weil
da die Spannung noch fehlt, obwohl ich den Port direkt nach dem
Einschalten auf HI setze.
Habe nun auch testweise ein paar Verzögerungen eingebaut.
Funktioniert aber nicht.
Hab mal Schaltung und Code angehängt.
Lokus Pokus schrieb:> die Beschaltung war schon richtig,
woher soll ich das wissen wenn du schreibst:
Lokus Pokus schrieb:> Allerdings kann ich das eher knicken. Denn bei 3,3V nimmt mir ein> Transistor zum Schalten zuviel Spannung weg.
wozu Transistor und an welche Beschaltung denkst du das dir ein
Transistor zuviel wegnimmt?
lese doch das Datenblatt:
SPANNUNGSVERSORGUNG +3,3V ODER +5V SINGLE SUPPLY (typ. 250μA)
KEINE ZUS. SPANNUNGEN ERFORDERLICH
wenn dein Atmel die 250µA nicht bringt schmeiss ihn weg.
Lokus Pokus schrieb:> Und die Versorgung einfach auf éinem AVR Pin zu legen funktioniert auch> nicht.
warum?
Lokus Pokus schrieb:> allerdings sieht es so aus als würde> das LCD beim Einschalten nicht schnell genug initialisiert werden, weil> da die Spannung noch fehlt, obwohl ich den Port direkt nach dem> Einschalten auf HI setze.> Habe nun auch testweise ein paar Verzögerungen eingebaut.> Funktioniert aber nicht.
da musst du wohl weitersuchen, nach VCC auf high liegt es doch an dir
wann du die Intialisierung startest.
Keine Ahnung wo ich da jetzt noch suchen soll.
Sobald man dem LCD die Spannung weg nimmt und wieder anlegt, reagiert es
nicht mehr.
Obwohl ich jetzt im INTO sogar nochmal initialisiere:
Lokus Pokus schrieb:> Keine Ahnung wo ich da jetzt noch suchen soll.
keine Ahnung warum ich noch antworten soll, wenn du nicht antwortest:
Beitrag "Re: ATtiny44 über IR-Signal aufwecken"
und warum nennst du die VCC Light Port?
Lokus Pokus schrieb:> DOGM_LIGHT_PORT
an der VCC werden maximal 250µA gesaugt für die LED der Beleuchtung bis
zu 80mA das schafft ein Port evt. nicht.
und dann gibt es noch diesen Hinweis:
http://www.lcd-module.de/pdf/doma/dog-m.pdf
"Bitte beachten Sie, dass aufgrund der COG-Technik die
Strombelastbarkeit der Ausgänge begrenzt ist. Es kann dadurch bei
größerer Buslast zu Signalverschleifungen und unsauberen Pegeln kommen.
Im Zweifelsfall sind zusätzliche Pull-Down Widerstände (8051)
erforderlich, oder es
müssen zusätzliche Waits/NOP's eingefügt werden"
Dein Plan Schaldbild ist schlecht lesbar.
DOGM_LIGHT_PORT heißt es nur deshalb so, weil es ursprünglich für die
Hintergrundbeleuchtung des LCD gedacht war. (habe das jetzt auch im Code
korrigiert)
Aufgrund des hohen Stromverbrauchs und da ich die Schaltung gerne mit
einer 3,6V Lithiumzelle betreiben möchte, habe ich die dann weg gelassen
und möchte das ganze so stromsparend wie möglich betreiben.
Aktuell zieht die Schaltung im Betrieb ca. 7,3mA.
Im Schlafmodus ca. 1,9mA
Vergiss das mit dem Transistor, ich hab die Versorgung jetzt mal direkt
an den AVR Ausgang gelegt.
Und das funktioniert leider nur bedingt.
Aufwecken geht sogar, nur erhalte ich dann verstümmelte Zeichenausgaben.
Ich glaube das kann ich mir sowieso sparen.
Ich lese hier gerade:
"nur typ. 250μA Stromverbrauch in vollem Betrieb (LED-Beleuchtung weiss
ab 3mA)"
Bei 250µA brauch ich das LCD wohl kaum außer Betrieb nehmen.
Dann muß wo anders die Ursache an dem "hohen" Stromverbrauch liegen.
Der IR-Empfänger kann es auch nicht sein. Der benötigt laut Datenblatt
nur 0,35mA
Also dürfte die Schaltung im Schlaf-Modus auch kaum mehr als das ziehen.
Schaltung ist übrigents problemlos erkennbar im IE .
Lokus Pokus schrieb:> Ich glaube das kann ich mir sowieso sparen.
jedenfalls sparst du reichlich an Infos..........
manno, ist es so schwer verständlich zu schreiben, alle Infos vorher auf
den Tisch zu bringen und nicht hinterher krus zu stammeln?
Lokus Pokus schrieb:> Ich lese hier gerade:> "nur typ. 250μA Stromverbrauch in vollem Betrieb (LED-Beleuchtung weiss> ab 3mA)">> Bei 250µA brauch ich das LCD wohl kaum außer Betrieb nehmen.> Dann muß wo anders die Ursache an dem "hohen" Stromverbrauch liegen.
hättest das mal vorher gelesen
Lokus Pokus schrieb:> Schaltung ist übrigents problemlos erkennbar im IE .
ach was, auch im IE ist das unleserlich
Lokus Pokus schrieb:> Aktuell zieht die Schaltung im Betrieb ca. 7,3mA.> Im Schlafmodus ca. 1,9mA
Poste endlich mal einen kompletten und stimmenden Schaltplan, inklusive
der Meßstelle.
Wo mißt Du die Stromaufnahme?
Klemm mal nacheinander alle ICs ab, auch den MC.
Schreib mal ein Programm, was nur Power-Down setzt und dann sleep, aber
ohne sei(), d.h. sleep forever.
Habe ich ejtzt mal.
Dabei bin ich auf den ATtiny44A ausgewichen, der laut Datenblatt
überhaupt nur mehr 0,1µA bei 1,8V zieht. Also bei 3,3V ca. 0,18µA
1
#include<avr/interrupt.h>
2
#include<avr/sleep.h>
3
4
intmain(void)
5
{
6
MCUCR&=~((1<<ISC01)|(1<<ISC00));
7
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
8
9
for(;;)
10
{
11
ACSR|=(1<<ACD);// Analogcomparator deaktivieren
12
ADCSRA&=~(1<<ADEN);// ADC deaktivieren
13
14
sleep_mode();
15
}
16
}
17
18
ISR(INT0_vect)
19
{
20
21
}
Mein Messgerät zeigt in dem Falle nichts mehr an. Also quasi 0.
Wenn ich also davon ausgehe das dass Programm richtig arbeitet, passt
das schon mal.
Als nächsten Schritt werde ich mal das LCD dazu hängen.
Die Schaltung verbraucht nun 0,21mA. Und dabei ist es egal ob etwas auf
dem LCD ausgegeben wird oder nicht.
Das würde sich auch mit den Angaben im Datenblatt decken:
"nur typ. 250μA Stromverbrauch in vollem Betrieb"
Wobei hier "voller Betrieb" wohl bedeutet, egal ob Anzeige oder nicht.
Das nächste wäre dann der IR-Empfänger.
Um den IR-Empfänger ergänzt, zieht die Schaltung nun 0.57mA im
Schlaf-Modus.
Auch das würde mit dem Datenblatt übereinstimmen:
"Typ. 0.35mA bei Vs=3.3V"
Ich glaube weniger wird's wohl auch nicht werden.
Jetzt möchte ich das ganze im Betrieb testen.
Dazu wäre allerdings hilfreich, wenn ich Tipps bekomme. wie ich das
Programm so anpasse damit so wenig wie möglich der AVR belastet wird.
Ich möchte gerne das während dem Sleep am LCD ein Text angezeigt wird.
Nur leider klappt das irgendwie nicht.
Ich dachte mir beim erkennen des Protokolls wäre der richtige Zeitpunkt,
nur funktioniert das nicht.
Ebenso wenn ich den Text in die Schlafroutine setze.
Lokus Pokus schrieb:> Das würde sich auch mit den Angaben im Datenblatt decken:> "nur typ. 250μA Stromverbrauch in vollem Betrieb"
könntest du über einen Port noch abschalten, aber....
Lokus Pokus schrieb:> Ich möchte gerne das während dem Sleep am LCD ein Text angezeigt wird.> Nur leider klappt das irgendwie nicht.
so langsam gebe ich auf, bekommst du keinen verständlichen Satz
zusammen?
WAS KLAPPT NICHT? sorry für Schreien aber das geht hier schon den ganzen
Thread so......
Text anzeigen?
Text anzeigen der im sleep stehen bleibt?
Sleep?