Hallo, Ich möchte einen Würfel welcher mti einem Attiny2313 arbeitet möglichst energiesparsam realisieren. Da ich den IRQ0 als Ausgang für eine LED verwendet habe, scheine ich den Attiny lediglich in den Idle-Modus schicken zu können. Da er aus Power-Down/Standby nur durch den IRQ0 aufgeweckt werden kann. Ist dass soweit richtig? Ist es eventuell besser ihn in diesem fall in Standby zu schicken, alle 250ms hochzufahren und nachzusehen ob der Taster gedrückt wurde? Kann ich ausser Analog-Comparator, Brown-Out, Refferenz-Aus, WDT-Aus noch tun um Energie zu sparen? Danke
Wuerfler schrieb: > Da ich den IRQ0 als Ausgang für eine LED verwendet habe, scheine ich den > Attiny lediglich in den Idle-Modus schicken zu können. > Da er aus Power-Down/Standby nur durch den IRQ0 aufgeweckt werden kann. Wenn das so ist, dann wäre die einzig sinnvolle Maßnahme das umverdrahten dieses Pins.
Du kannst ihn einfach komplett ausschalten und mit dem Taster einschalten, der Attiny hält dann über einen Mosfet die Spannungsversorgung und schaltet sich danach wieder komplett ab.
Wuerfler schrieb: > Da er aus Power-Down/Standby nur durch den IRQ0 aufgeweckt werden kann. Nein. Er kann mit allen PCINT (PB0..7) aufwachen. Und der ATtiny2313A kann mit allen 18 IOs aufwachen.
:
Bearbeitet durch User
Peter Dannegger schrieb: > Wuerfler schrieb: >> Da er aus Power-Down/Standby nur durch den IRQ0 aufgeweckt werden kann. > > Nein. > > Er kann mit allen PCINT aufwachen. Und mit Reset auch!
Wie viele uA verbraucht er mehr? Was benötigt die restliche hardware?
Dann bedeutet: Seite 31 im Datenblatt "Note 2. For INT0, only level interrupt.", das er mit allen Interrupts (INT0,INT1,PinChange) aufwachen kann? Das würde ich mir wünschen, werde es nacher ausprobieren.
Wuerfler schrieb: > Dann bedeutet: > Seite 31 im Datenblatt > "Note 2. For INT0, only level interrupt.", > das er mit allen Interrupts (INT0,INT1,PinChange) aufwachen kann? > > Das würde ich mir wünschen Nun, ich würde mir wünschen daß du lernst, Datenblätter zu lesen. In meinem PDF für den ATtiny2313 gibt es auf Seite 34 eine Tabelle "Active Clock Domains and Wake-up Sources in the Different Sleep Modes." Die ist doch wohl eindeutig, oder? XL
Wuerfler schrieb: > Ich möchte einen Würfel welcher mti einem Attiny2313 arbeitet möglichst > energiesparsam realisieren. Hmm, ich überlege gerade, wie mann ein solches Gerät wohl auf Sparsamkeit trimmt??? http://www.jassshop.ch/shop/KategorienBilder/wuerfel.jpg
Ja es ist ein Attiny2313a, Er sollte aufwachen können, tut er aber nicht, ich kann ihn Power-Down schicken, jedoch nicht wider aufwecken. habe gelesen dass man sofort nach aufwachen externe Interrupts seperen soll und dass es einen Low-Level-Interrupt braucht um ihn zu wecken. Zum Low-Level Interrupt find ich im Datenblatt leider nichts. Kann ihn scheibar nicht mit Pinchange-Interrupt wecken:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <stdlib.h> |
4 | #include <avr/sleep.h> |
5 | |
6 | inline void Init() |
7 | {
|
8 | //------------PORTS------------------------------------
|
9 | DDRB&=0xE0; //Port B auf Eingabe |
10 | |
11 | PORTB&=0xE0;//Kein Pull-Up |
12 | |
13 | DDRD|=0x7F; //Port D auf Ausgabe |
14 | |
15 | PORTD|=0x7F;//LED-Quelle, Kein Pull-Up |
16 | //-------------TIMER0------------------------------------
|
17 | TCCR0A|=0x02; //CTC-Modus |
18 | |
19 | TIMSK&=0xf8; //Timer 0 IRQ nicht möglich |
20 | |
21 | TIFR|=0x07; //IRQ Flags löschen |
22 | //------------Timer1--------------------------------------
|
23 | TCCR1A&=0x0C; //CTC-Mode |
24 | |
25 | TCCR1C&=0x3F; //Kein Output-Compare |
26 | |
27 | TCNT1=0x0000; //Startwert |
28 | |
29 | OCR1A=0x2000; //Bis-Zählwert |
30 | |
31 | OCR1B=0x0000; //Nicht genutzt |
32 | |
33 | ICR1=0x0000; //Nicht genutzt |
34 | |
35 | TIMSK|=0x40; //Compare Match A-IRQ |
36 | TIMSK&=0x57; |
37 | |
38 | TIFR|=0xE8; //Interrupts löschen |
39 | |
40 | //----------PIN-CHANGE-IRQ------------------------------
|
41 | GIMSK|=0x20; //PIN Change IRQ-Enable |
42 | |
43 | GIFR |=0x20; //IRQ nicht löschen |
44 | |
45 | PCMSK0 |= 0x01; //Pin-Change IRQ für PB0 auswählen |
46 | |
47 | //----------Sparsamkeit-------------------
|
48 | //5,13mA
|
49 | ACSR|=0x80; //Analog-Comparator abschalten |
50 | //5,10mA
|
51 | //Brown-Out-Off hfuse = 0xD1:m
|
52 | //5,06mA
|
53 | ACSR&=0xFB; //Keine BG-Refferenz nutzen |
54 | //5,1mA
|
55 | //Watchdog über Fuses Ausschalten?
|
56 | |
57 | //Digital input disable register
|
58 | |
59 | //---------System Starten-------------------
|
60 | |
61 | sei(); //Globale IRQ Enable |
62 | }
|
63 | |
64 | int main(void) |
65 | {
|
66 | //-------Initialisierung------------------------------
|
67 | Init(); |
68 | while(1) |
69 | {
|
70 | if(TIMSK==0x00) //Interrupts wieder enablen, falls Disabled |
71 | {
|
72 | TIMSK|=0x41; |
73 | GIMSK|=0x20; |
74 | }
|
75 | }
|
76 | }
|
77 | |
78 | ISR (PCINT0_vect) //Jemand hat auf den Knopf gedrückt |
79 | {
|
80 | GIMSK=0x00; //Alle Externen Interrupts Disable |
81 | TIMSK=0x00; //alle Timer-Interrupts Disable |
82 | uint8_t wertneu=0; |
83 | uint8_t wertalt=0; |
84 | //Schnelles Würfeln während gedrücktem Taster
|
85 | while (PINB & (1<<PINB0) ) |
86 | {
|
87 | switch (rand()%6) |
88 | {
|
89 | case 0: PORTD = 0x08; break; |
90 | case 1: PORTD = 0x41; break; |
91 | case 2: PORTD = 0x49; break; |
92 | case 3: PORTD = 0x55; break; |
93 | case 4: PORTD = 0x5d; break; |
94 | case 5: PORTD = 0x77; break; |
95 | }
|
96 | }
|
97 | //langsames Ausrollieren
|
98 | do{ |
99 | wertneu=rand(); |
100 | if(wertneu>wertalt) //Der würfel läuft immer langsamer |
101 | {
|
102 | wertalt=wertneu; |
103 | TCNT0=0x00; //Startzeit = 0 |
104 | OCR0A=wertneu; //Zeit für neuen Zufallswert längere Zeit |
105 | TCCR0B|=0x05; //Prescaler=1024, Timer-Start |
106 | do{ |
107 | ;
|
108 | }while(!(TIFR&(1<<OCF0A)));//Warten bis Timer abgelaufen |
109 | TCCR0B&=0x30; //Timer Anhalten |
110 | TIFR|=(1<<OCF0A); //Flag löschen durch 1-Schreiben |
111 | }
|
112 | switch (rand()%6) |
113 | {
|
114 | case 0: PORTD = 0x08; break; |
115 | case 1: PORTD = 0x41; break; |
116 | case 2: PORTD = 0x49; break; |
117 | case 3: PORTD = 0x55; break; |
118 | case 4: PORTD = 0x5d; break; |
119 | case 5: PORTD = 0x77; break; |
120 | }
|
121 | }while(wertalt<200); //So oft neu würfeln bis Zufallswert >200 |
122 | //-------------------Endgültiger Wert-----------------------------
|
123 | |
124 | //-------------------10 Sek Wert anzeigen-----------------------
|
125 | |
126 | TCCR1B|=0x0D; //CTC / Prescaler = 1024 , Timer Starten |
127 | }
|
128 | |
129 | ISR (TIMER1_COMPA_vect) //Energiesparen..... |
130 | {
|
131 | PORTD = 0x00; |
132 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
133 | sleep_mode(); |
134 | GIMSK=0x00; //Alle Externen Interrupts Disable |
135 | TIMSK=0x00; //alle Timer-Interrupts Disable |
136 | }
|
Der Power-Down Mode wird in der ISR von T1 Aktiviert, ich komm jedoch nicht mehr raus.
Wuerfler schrieb: > Der Power-Down Mode wird in der ISR von T1 Aktiviert, ich komm jedoch > nicht mehr raus. Das ist völlig korrektes Verhalten. Um Sleep zu beenden muß ein Interrupt ausgeführt werden. Blöd nur, wenn man bereits in einem Interrupt ist. Der AVR kann ja keine nested Interrupts.
:
Bearbeitet durch User
Generell ist das Programm maximal dämlich^Wungeschickt. Nix von dem was da in den ISR steht, gehört auch dahin. Das sollte alles nach main() und die ISR sollten gerade mal ein Flag setzen (Timer) bzw. gar nix tun (Pin Change). Außerdem würde ich darüber nachdenken, den µC per Reset aufzuwecken. Dann ist seine erste (und einzige) Funktion, zu zählen bis die Taste losgelassen wird. Dann das Ergebnis anzuzeigen und den Timer zu starten. Und wenn der Timer den Timeout signalisiert, die LEDs abzuschalten und sich schlafen zu legen. Noch besser aus Sicht der Verbrauchsminimierung wäre, den µC per Einschalter zu starten. Dann überbrückt er den Einschalter mit einem Transistor oder MOSFET und schaltet sich am Ende komplett aus. XL
Axel Schwenke schrieb: > Außerdem würde ich darüber nachdenken, den µC per Reset aufzuwecken. Das ist ziemlich tricky. Der Würfel soll ja nicht dunkel bleiben, solange man drückt, also braucht man zusätzlichen Schaltungsaufwand. Auch soll er nicht durch Prellen beim Loslassen wieder resetten. Also besser sein lassen. Der PCINT funktioniert einwandfrei, wenn man es richtig programmiert. Z.B.: Beitrag "AVR Sleep Mode / Knight Rider"
Wuerfler schrieb: > Ich möchte einen Würfel welcher mti einem Attiny2313 arbeitet möglichst > energiesparsam realisieren. > > Da ich den IRQ0 als Ausgang für eine LED verwendet Häh? Eine LED (vermutlich 7 LEDs in 4 Gruppen) für ein "möglichst energiesparsames" Gerät ? Du hast da irgendwas missverstanden. Dafür verwendet man passive LCD, und falls du keins mit 7 Punkten findest, kannst du es ähnlich einer Platine selbst machen: http://fluessigkristalle.com/selbstbau.htm Falls du unbedingt bei den LEDs bleiben willst für einen Würfel den man nur im dunklen ablesen kann, und aus irgendwelchen Gründen einen ATTiny10 mit nur 6 Pins verwenden willst, und trotz der nur insgesamt 6 Pins nicht mit 4 sondern mit 3 auskommen willst, geht das dank Charlyplexing, und hast deinen Aufwachpin für den Taster übrig. http://ww1.microchip.com/downloads/en/AppNotes/91029a.pdf Aber wie ich höre, bist du nur zu faul zum umlöten, und das mangelnde Aufwachen nur ein Programmierfehler.
Ich habe ebenfalls Eindruck, dass der TO bei den LEDs viel Strom "verbraucht". Der Strom, den er durch das "Schlafen legen" des uC, einspart ist da marginal. Weiterhin ist von einem Taster die Rede; wahrscheinlich ein dauerhafter Pull-Up dran?
Coder schrieb: > Ich habe ebenfalls Eindruck, dass der TO bei den LEDs viel Strom > "verbraucht". Der Stromverbrauch ist überhaupt kein Problem, die LEDs müssen ja nicht ewig leuchten. Ich schalte sie nach 25s aus. Hier mal mein Würfel mit AT89C2051: Beitrag "Re: Problem Zufallsgenerator" Da mußte ich den Reset nehmen, der hatte leider keinen PCINT. Kostet dann eben 4 Bauteile zusätzlich.
Peter Dannegger schrieb: > Coder schrieb: >> Ich habe ebenfalls Eindruck, dass der TO bei den LEDs viel Strom >> "verbraucht". > > Der Stromverbrauch ist überhaupt kein Problem, die LEDs müssen ja nicht > ewig leuchten. In der Tat. Obligatorische Anekdote: ein solcher "elektronischer Würfel" war das erste meiner Elektronikprojekte mit IC. TTL. Richtiges TTL. 74 ohne irgendwelche Buchstaben in der Typbezeichnung (also im Prinzip, real waren es D174, D100 & Co). Die größte Herausforderung war ein Oszillator, der nach und nach langsamer wurde. So konnte man den Würfel "austrudeln" sehen. Das Problem des Stromverbrauchs war ganz einfach gelöst: der "Würfeln" Taster war der Einschalter. Nach dem Einschalten lief das Ding los, wurde langsamer, blieb stehen. Und wenn man seine Zahl abgelesen hatte, ließ man den Taster los und der Stromverbrauch war wieder 0. XL
Ich denke das Stromsparen bezieht sich auf den Zeitraum, wenn der Würfel nicht gebraucht wird. Also einfach POWER_DOWN und vorher die LED's ausschalten reicht vollkommen. Und Ja, man kann mit jedem Pin ein Interrupt zu Aufwecken auslösen. Ich habe selbst einen Würfel konstruiert und gebaut, der mit Charly-Plexing arbeitet. Als Versorgung werden zwei Mignon-Zellen verwendet. Es leuchten dann maximal 2 LED's gleichzeitig. Bei Low-Power LEDs sind das 4mA. Nach 30 Sekunden geht das Ganze auf "Power Down". Berechnen wir doch mal die Haltbarkeit der beiden Zellen wenn wir ein Stunde am Tag Dauerwürfeln. Die LEDs brauchen in Schnitt durch das 4-fache Plexing 1,75 mA. Eine Mignonzelle hat eine Kapazität vom ca. 2800 mAh. 2800 mAh / 1,75 mA sind 1600 Stunden. Bei einer Stunde am Tag sin das 1600 Tage oder fast 4,5 Jahre. Das finde ich Sparsam genug. Für eine passive LCD-Anzeige sehe ich keinen Bedarf. P.S.: Ich bin mit einem ATtiny13A, 7 LEDs, 1 Taster und 3 Widerständen (zwei für die gleichzeitigen LEDs und einen Widerstand für den Reset-Pullup) ausgekommen.
Zur Schaltung: Hardware: Normalerweise reicht auch ein ATTiny13A, wenn man die beiden LEDs die sowieso immer zusammen leuchten über einen PIN schaltet. Durch Charly-Plexing ist sogar ein zweifarbiger Doppel-Würfel möglich. Software - Programm in Interrupt-Routine: Es wird empfohlen sich in einer Interrupt-Routine so kurz wie möglich aufzuhalten. Bei dir sehe ich das Hauptprogramm in der Interrupt-Routine. Tobe dich lieber in der Main-Schleife aus. Für das Auslösen des Würfelns geht es auch problemlos ohne Interrupt. Der Interrupt wird dann nur noch zum Aufwecken gebraucht. Software - Zufallszahl: Die "rand()" Funktion ist nicht optimal für eine Zufallszahl. Besser man benutzt die Dauer des Tastendrucks um einen echten Zufall zu bekommen. Dafür einfach eine Zähler schnell hochzählen, solange eine Taste gedrückt wird. Dabei aber nicht beim Hochzählen zurücksetzten, wenn es mehr als 6 ist. Das kostet Zeit und macht den Zufall "unwuchtig". Besser beim Loslassen durch 6 teilen und sich den Rest angucken. P.S.: Wer hätte gedacht, das so ein bisschen Würfeln eine Wissenschaft ist ;-)
Uwe K. schrieb: > Dabei aber nicht beim Hochzählen zurücksetzten, wenn es > mehr als 6 ist. Das kostet Zeit und macht den Zufall "unwuchtig". Besser > beim Loslassen durch 6 teilen und sich den Rest angucken. Allerdings geht 256 durch 6 nicht auf. D.h. es gibt auch hier eine Verteilung, die nicht rein zufällig ist. Die Zahlen 1-4 werden so um gut 2% bevorzugt.
Uwe K. schrieb: > Dabei aber nicht beim Hochzählen zurücksetzten, wenn es > mehr als 6 ist. Das kostet Zeit und macht den Zufall "unwuchtig". Man kann die Taste auch in einem Timerinterrupt abtasten und hochzählen, dann ist jeder Wurf gleich warscheinlich. Eine kleine Unwucht ergibt sich durch die Latenz von 1..4 Zyklen. Wen das stört, der kann den Interrupt in Assembler schreiben und die Latenz kompensieren. Die menschliche Drückdauer liefert einen sehr guten echten Zufall, da das Gehirn völlig asynchron zum CPU-Takt ist.
Alexander Schmidt schrieb: > Allerdings geht 256 durch 6 nicht auf. Stimmt. Das ist bei einem Integer aber kein Problem mehr. Einen Integer zu füllen dauert ein wenig. Das ist auch nicht perfekt, da die 5 und die 6 zu kurz kommen. Da es aber nur alle 10922 Durchläufe passiert, sollte der Fehler (0,01%) tolerierbar sein.
:
Bearbeitet durch User
Uwe K. schrieb: > Stimmt. Das ist bei einem Integer aber kein Problem mehr. Einen Integer > zu füllen dauert ein wenig. Das ist auch nicht perfekt, da die 5 und die > 6 zu kurz kommen. Da es aber nur alle 10922 Durchläufe passiert, sollte > der Fehler (0,01%) tolerierbar sein. Also eine 16-Bit-Variable. Ein ATmega oder ATtiny muss Operationen mit 16-Bit-Variablen in mehreren Takten rechnen. Ich bin mir nicht sicher, ob bei einem Überlauf des unteren Bytes mehr Takte gebraucht werden, dann würde es wieder eine "Unwucht" geben.
Alexander Schmidt schrieb: > Allerdings geht 256 durch 6 nicht auf. D.h. es gibt auch hier eine > Verteilung, die nicht rein zufällig ist. Die Zahlen 1-4 werden so um gut > 2% bevorzugt. Ich muss mich zuerst entschuldigen, ich hab den Thread nicht ganz durchgelesen. Das genannte Problem hatte ich aber schon mal und dann so gelöst, dass Ergebnisse zwischen 252 und 255 einfach verworfen werden. In diesen Fällen wird "neu gewürfelt".
Markus Weber schrieb: > Das genannte Problem hatte ich aber schon mal und dann so gelöst, dass > Ergebnisse zwischen 252 und 255 einfach verworfen werden. In diesen > Fällen wird "neu gewürfelt". Und den Zufall holst du über eine c-Funktion? Oder bittest du den Benutzer nochmal die Würfeltaste zu drücken? Woher holst du im ersten Fall den Seed?
Alexander Schmidt schrieb: > Also eine 16-Bit-Variable. Ein ATmega oder ATtiny muss Operationen mit > 16-Bit-Variablen in mehreren Takten rechnen. > Ich bin mir nicht sicher, ob bei einem Überlauf des unteren Bytes mehr > Takte gebraucht werden, dann würde es wieder eine "Unwucht" geben. Das ist ein berechtigter Einwand. Ich habe deshalb ein Testprogramm geschrieben (GCC) um die Zeit beim Überlauf zu messen. Deine Befürchtung hat sich nicht bestätig. Sowohl der 8-Bit überlauf (255->256) noch der Gesamtüberlauf (65535->0) hat keine längere Bearbeitungszeit benötig. Die Zeit die zum hochzählen benötigt wird ist immer gleich.
:
Bearbeitet durch User
Uwe K. schrieb: >> Ich bin mir nicht sicher, ob bei einem Überlauf des unteren Bytes mehr >> Takte gebraucht werden, dann würde es wieder eine "Unwucht" geben. > Das ist ein berechtigter Einwand. Ich habe deshalb ein Testprogramm > geschrieben (GCC) um die Zeit beim Überlauf zu messen. > Deine Befürchtung hat sich nicht bestätig. > Sowohl der 8-Bit überlauf (255->256) noch der Gesamtüberlauf (65535->0) > hat keine längere Bearbeitungszeit benötig. Die Zeit die zum hochzählen > benötigt wird ist immer gleich. Alles klar, dann ist es tatsächlich eine gute Lösung.
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.