Hallo zusammen, ich habe ein kleines batteriebetriebenes Projekt, und zwar einen Datenlogger, der regelmäßig zwei Temperatursensoren (DS1820) ausliest und deren Temperatur samt Timestamp in einer CSV-Datei auf einer SD-Karte speichert. Das SD-Karten-Modul ist ein vorgefertigtes mit Tristates zum ein- und ausschalten. Mein Problem ist aber das Ein- bzw. Ausschalten des Displays. Ich habe festgestellt, dass bei der aktuellen Beschaltung, nachdem LCD-ON auf 0 geschaltet wurde, der Text noch lesbar ist, wenn man den Kontrast entsprechend einstellt. Meine Vermutung ist also, dass irgendwo noch ungewollt Strom fließt. Kann es daran liegen, dass ich die Transistoren an die GND Seite und nicht an die 5V Seite gesetzt habe? Oder ist es weil die Datenleitungen einen anderen Spannungsbereich haben als die Stromversorgung? Dummerweise ist die Hardware schon gelötet und ich komme jetzt nur noch schwer dran. Wird es helfen, wenn ich R/W und D0 bis D3 auch an den Kollektor anschließe, damit sie keinen Kontakt mehr zu GND haben, wenn der Transistor dicht macht? Ich würde am Aufbau nur ungern größere Änderungen machen... Da man den Text bei normalen Kontrasteinstellungen so gut wie nicht sieht ist meine andere Frage, ob man es vielleicht einfach dabei belassen kann, bzw. was das längere "ausgeschaltetsein" für Auswirkungen auf das Display haben kann. Danke schonmal und liebe Grüße Swen
Hallo, wenn du GND abschaltest, dann musst du am µC alle Daten-/Steuerleitungen auf High schalten oder als Eingang konfigurieren. Kannst auch +5V abschalten, dann eben die Signale auf Low. Den Transistor zum abschalten kannst du Dir warscheinlich sparen bei den paar mA die das Display braucht. Sascha
Tja, da muss man sich mögliche Strompfade überlegen: D0...D3 liegen an GND. Die haben bestimmt Schutzdioden, mit denen sich ungewollte Pfade gegen Masse ergeben. Nachdem alle Datenleitungen µC -> LCD beim µC auf Eingang gesetzt sind, kann man einen p-FET in der +5 V Speiseleitung zum LCD und zum Backlight abschalten. Dann fließt nichts mehr durch den Kontrast-Spannungsteiler. - Und auch nichts mehr durch die Schutzdioden an den Eingangs-Pins des Displays.
Bei sämtlichen Displays (zumindest die in meiner Sammlung) sind die Backlight-Anschlüsse elektrisch komplett separat vom Display herausgeführt, kann also auch separat betrachtet und geschaltet werden. Bleibt das Display selbst: HD44780-basierte Displays ziehen so 1 - 5 mA, da ist eine Versorgung direkt aus einem Portpin kein Problem, die meisten Controller, z.B. AVR, haben ein paar 20mA-fähige Portpins. Das Display einfach daraus versorgen. Der Transistor ist unnötig. 0V vom Display an GND, +5V-Anschluß vom Display an den Portpin. Einschalten: Alle Portpins auf 0V. Versorgungsportpin auf 5V schalten, die im Datenblatt vom Display angegebene Mindestwartezeit abwarten, dann normal initialisieren. Und zwar jedesmal nach dem Einschalten des Displays. Ausschalten: Alle Displayportpins einschließlich dem Versorgungspin gleichzeitig auf 0V setzen. Die Eingänge des Display-Kontrollers sind mit Dioden geschützt, deshalb müssen alle Pins auf 0V, bei 5V auf einer der Steuer- oder Datenleitungen würde bei abgeschalteter Versorgung der Display-Kontroller über die Schutzdioden versorgt, die machen das nicht unbedingt mit. Bei Displays, die eine negative Kontrastspannung benötigen, ist dieser Wandler mit abzuschalten. Gruß Jadeclaw.
moin moin, man kann das LCD auch per Befehl on/off schalten siehe P.5 of 17 4ter Befehl.
Swen Wenzel schrieb: > ich habe ein kleines batteriebetriebenes Projekt es ging aber darum, das Display stromlos zu schalten, um Energie zu sparen...
chris schrieb: > moin moin, > > man kann das LCD auch per Befehl on/off schalten siehe P.5 of 17 4ter > Befehl. sicher, dann zeigt es zwar nichts mehr an, aber der Stromverbrauch verringert sich nicht so weit wie man sich das für Batteriebetrieb wünschen würde. Sascha
Danke für die schnellen Antworten :) Jadeclaw Dinosaur schrieb: > 0V vom Display an GND, +5V-Anschluß vom Display an den Portpin. Gesagt, getan. Was mache ich mit den +5V vom Poti? Hab sie jetzt mal mit an den Portpin geschaltet. Scheint zu funktionieren. Der Text kam immer dann zum Vorschein, wenn ich den Abgreifer vom Poti richtung GND bewegt habe, und jetzt ist die Kontrastspannung nach dem Abschalten ja genau GND und es wird nix mehr angezeigt. Nun muss ich nur noch dieses garstige Modul komplett abschalten können, aber da frage ich mal den Support vom Hersteller. Mal was anderes. Wenn ich mir so die Diagramme mit Taktrate und Stromverbrauch vom atm168 anschaue, kommt es mir so vor, als würde ich bei hoher Taktung mehr Takte pro mAs bekommen als bei niedriger. Macht es also Sinn, den Controller auf 20Mhz zu takten oder hab ich mich da verrechnet? Während der Benutzereingabe braucht er dann zwar sicher mehr Strom, aber das ist ja nur ganz selten und nicht so lange. Er wäre dann halt beim loggen schneller und das Verhältnis active/pwrsave wäre kleiner.
Swen Wenzel schrieb: > Wird es helfen, wenn ich R/W und D0 bis D3 auch an den Kollektor > anschließe, damit sie keinen Kontakt mehr zu GND haben, wenn der > Transistor dicht macht? Ja, es würde aber auch schon helfen die Pins offen zu lassen oder gegen +5V zu legen. Das Display hat intern Pull-up-Widerstände an den Datenleitungen. Pro Pin fließen ca 33uA wenn man sie an 0V anschließt. Swen Wenzel schrieb: > es also Sinn, den Controller auf 20Mhz zu takten In der Regel: nein. Gruß Anja
Swen Wenzel schrieb: > Jadeclaw Dinosaur schrieb: >> 0V vom Display an GND, +5V-Anschluß vom Display an den Portpin. > Gesagt, getan. > Was mache ich mit den +5V vom Poti? Hab sie jetzt mal mit an den Portpin > geschaltet. Das ist korrekt so. Alle Anschlüsse müssen stromlos, d.h. auf 0V(GND) liegen, wenn das Display abgeschaltet wird. Gruß Jadeclaw.
Sascha Weber schrieb: > chris schrieb: >> moin moin, >> >> man kann das LCD auch per Befehl on/off schalten siehe P.5 of 17 4ter >> Befehl. > sicher, dann zeigt es zwar nichts mehr an, aber der Stromverbrauch > verringert sich nicht so weit wie man sich das für Batteriebetrieb > wünschen würde. > > Sascha Richtig erkannt, da veringert sich nichts. Und ist das Display größer als 1 x 16 oder 2 x 8 Zeichen, dann kommen zusätzliche Treiber (HD44100) dazu, die laufen ebenfalls weiter. Ergo ist Saft weg und alle Anschlüsse auf 0V die beste Lösung. Gruß Jadeclaw.
Anja schrieb: > Swen Wenzel schrieb: >> es also Sinn, den Controller auf 20Mhz zu takten > In der Regel: nein. Warum nicht?
Swen Wenzel schrieb: > Anja schrieb: > >> Swen Wenzel schrieb: >>> es also Sinn, den Controller auf 20Mhz zu takten >> In der Regel: nein. > > Warum nicht? Weil es sich nicht lohnt. Es gibt nur 2 Fälle, wo 20MHz angesagt sind: Mathematik, z.B. Grafikberechnung, sowie Zähleranwendung. Der Grund hier: Die controllerinternen Zähler sind nur bis zum Halben des CPU-Taktes nutzbar. Einen separaten taktunabhängigen Prescaler wie bei den PIC-Controllern gibt es hier nicht, bei 20MHz-Takt ist deshalb bei 10MHz Schluß. Bei anderen Anwendungen ist es wohl eher sinnvoller, erstmal den Programmcode zu optimieren, bevor man den Takt hochschraubt. Gruß Jadeclaw
Erläutere doch mal wie du dir das ganze Energiesparkonzept vorgestellt hast, da können wir bestimmt noch einiges optimieren ;)
Eumel schrieb: > Erläutere doch mal wie du dir das ganze Energiesparkonzept vorgestellt > hast, da können wir bestimmt noch einiges optimieren ;) Naja, das Konzept ist recht einfach: Der Controller ist aktiv, wenn der Benutzer Einstellungen vornimmt, wie zum Beispiel Datum/Uhrzeit oder Messintervall. Kommt länger als eine Minute keine Eingabe geht er in den Schlafmodus (geht auch per Tastendruck). Das SD-Kartenmodul wird unmittelbar vorm schreiben ein- und direkt danach auch wieder ausgeschaltet. Hier die zwei wichtigen Programmabläufe in Kurzform (Zugriffe auf Counter-Register sind über Update-Busy-Flags abgesichert) Die Methode Sleep:
1 | 1. OCI2A auf 1/8 Hz schalten (langsamer geht nicht) |
2 | 2. Nächste Messung in mehr als 8sec und kein Benutzer anwesend? |
3 | 2.1(Y) |
4 | 2.1.1 Power Save Mode antreten |
5 | 2.1.2 weiter bei 2 |
6 | |
7 | 3 Aufgewacht wegen Benutzer? |
8 | 3.1(N) |
9 | 3.1.1 nächster Messzeitpunkt in mehr als 1 sec? |
10 | 3.1.1(Y) |
11 | 3.1.1.1 OCI2A so einstellen dass uC 1sec vor messung aufwacht |
12 | 3.1.1.2 Power Save Mode antreten |
13 | |
14 | 3.2(Y) |
15 | 3.2.1 vergangene Zeit gutschreiben |
16 | 3.2.2 OCI2A auf 1Hz schalten |
17 | 3.2.3 LCD einschalten |
18 | 3.2.4 Festhalten, dass Benutzer anwesend |
Hauptroutine:
1 | 1. Jetzt messen? |
2 | 1.1(Y) |
3 | 1.1.1 Messung vornehmen |
4 | 1.1.2 SD-Modul einschalten |
5 | 1.1.3 Ergebnisse speichern |
6 | 1.1.4 SD-Modul ausschalten |
7 | 1.1.5 nächsten Messzeitpunkt berechnen |
8 | |
9 | 2. Benutzer anwesend? |
10 | 2.1(Y) |
11 | 2.1.1 Taster auslesen und Aktionen ausführen |
12 | |
13 | 3 Letzte Aktion mehr als 60sec her? |
14 | 3.1(Y) |
15 | 3.1.1 LCD aus |
16 | 3.1.2 festhalten, dass kein Benutzer anwesend |
17 | |
18 | 4.In mehr als 1 Sekunde messen und kein Benutzer anwesend? |
19 | 4.1(Y) |
20 | 4.1.1 sleep() |
21 | |
22 | 5. weiter bei 1 |
Ich hoffe, dass man daraus schlau wird. Hier ist auch noch der Quellcode von der sleep() Methode... da sind ein Paar Fragen drin, vielleicht kann die mir auch jemand beantworten.
1 | volatile uint32_t secCounter; |
2 | uint32_t nextMeasurement; |
3 | void sleep() { |
4 | |
5 | PCINT1_ON; //aufwachen über Tastendruck einschalten |
6 | OCR2A = 255;//8*32 = 256 Ticks da die 0 auch einer ist 255. -> im 8 Sekunden Intervall wacht er auf. |
7 | while((ASSR & (1 << OCR2AUB))); //Busyflag abwarten, damit er auch wieder aufwacht. |
8 | |
9 | uint16_t temp = nextMeasurement - secCounter; |
10 | while(lastAction != 0 && temp > 8){ |
11 | set_sleep_mode(SLEEP_MODE_PWR_SAVE); |
12 | sleep_mode(); |
13 | secCounter += 7; //Beim aufwachen wurde durch die Routine schon 1 addiert |
14 | |
15 | temp = nextMeasurement - secCounter; |
16 | //Vielleicht sparen die unteren beiden Codezeilen gegenüber der oberen ein bisschen Zeit?
|
17 | //if(temp1>8) temp1 -= 8;
|
18 | //else temp1 = nextMeasurement-secCounter;
|
19 | }
|
20 | |
21 | //Die PCINT Routine setzt lastAction auf 0.
|
22 | //Ist der Wert noch -1, bedeutet das, dass der Aufwachgrund
|
23 | //eine anstehende Messung und kein Benutzer war.
|
24 | if (lastAction == -1) { |
25 | //Steht die nächste Messung nicht unmittelbar bevor, warten wir noch so lange
|
26 | if (temp > 1) { |
27 | //Wir wachen eine Sekunde vor der Messung auf, damit wie den Zeitpunkt nicht verpassen
|
28 | temp--; |
29 | OCR2A = temp * 32 - 1;//-1 weil die 0 auch noch als Takt zählt |
30 | |
31 | //Warten bis OCR2A aktualisiert wurde und dann erst schlafen, damit wir auch wieder aufwachen
|
32 | while ((ASSR & (1 << OCR2AUB))); |
33 | set_sleep_mode(SLEEP_MODE_PWR_SAVE); |
34 | sleep_mode(); |
35 | secCounter += temp - 1; // auch hier wird wegen der Routine 1 weniger addiert. |
36 | }
|
37 | //dann wird der Counter wieder auf 1Hz gestellt.
|
38 | OCR2A = 31; |
39 | //while ((ASSR & (1 << OCR2AUB))); die anschließende Messung dauert samt Schreibvorgang ausreichend lange.
|
40 | //TCNT2 %= 32; steht ohnehin auf 0, sonst wäre er nicht aufgewacht
|
41 | |
42 | } else { |
43 | //Wurde der Controller vom Benutzer aufgeweckt, muss die vergangene Zeit berechnet werden.
|
44 | |
45 | //TCNT2 ist direkt nach dem Aufwachen nicht unbedingt aktuell, daher auch hier wieder
|
46 | //das Busyflag auslesen.
|
47 | OCR2A = 255; |
48 | while ((ASSR & (1 << OCR2AUB))); |
49 | temp = TCNT2; |
50 | |
51 | //!!!Bei den folgenden drei Rechnungen bin ich mir unsicher!!!
|
52 | TCNT2 = temp % 32; //Zählerstand auf die angefangene Sekunde setzen |
53 | OCR2A = 31; //1Hz Taktrate wieder einstellen |
54 | //Die 0 als Takt hinzufügen dann die vergangenden Takte durch 32 teilen,
|
55 | //um die vergangenen Sekunden zu bekommen.
|
56 | temp = (temp+1) / 32; |
57 | |
58 | //Die "Schlafschleife" hat schon 7 addiert, die dürfen hier nicht vergessen werden.
|
59 | secCounter += ((int16_t) temp)-7; |
60 | LCD_ON; |
61 | LIGHT_ON; |
62 | |
63 | //Warten bis alle Tasten losgelassen und debounced sind.
|
64 | //zum vermeiden von einer versehentlichen eingabe direkt nach dem aufwachen.
|
65 | //TODO funktioniert nicht.
|
66 | do{ |
67 | PCINT1_ON; //Die Routine schaltet sich selbst ab daher hier wieder einschalten. |
68 | lastAction=1; |
69 | _delay_ms(10); |
70 | |
71 | //lastAction==0 bedeutet Pinchange in den letzten 10ms und
|
72 | //(PINC & ALL_KEYS) != ALL_KEYS bedeutet, dass mindestens eine Taste gedrückt ist.
|
73 | //Ist eins von beiden der Fall, muss gewartet werden.
|
74 | }while(lastAction == 0 || (PINC & ALL_KEYS)!=ALL_KEYS); |
75 | }
|
76 | }
|
Was mir jetzt spontan zum Stromsparen einfällt wäre ein Bufferarray für die Temperaturen und Messzeitpunkte(2*2+4 = 8 Byte pro Feld). Dadurch müsste das SD-Modul nicht bei jeder Messung eingeschaltet werden. Allerdings weiß ich nicht wie viel Platz ich im Arbeitsspeicher noch habe...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.