Forum: Mikrocontroller und Digitale Elektronik Würfel auf Sparsamkeit trimmen


von Wuerfler (Gast)


Lesenswert?

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

von Alexander S. (esko) Benutzerseite


Lesenswert?

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.

von Frank M. (frank_m35)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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
von Route_66 H. (route_66)


Lesenswert?

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!

von Coder (Gast)


Lesenswert?

Wie viele uA verbraucht er mehr? Was benötigt die restliche hardware?

von Wuerfler (Gast)


Lesenswert?

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.

von Axel S. (a-za-z0-9)


Lesenswert?

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

von Harald W. (wilhelms)


Lesenswert?

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

von Wuerfler (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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
von Axel S. (a-za-z0-9)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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"

von MaWin (Gast)


Lesenswert?

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.

von Coder (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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.

von Axel S. (a-za-z0-9)


Lesenswert?

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

von Uwe K. (ukhl)


Lesenswert?

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.

von Uwe K. (ukhl)


Lesenswert?

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 ;-)

von Alexander S. (esko) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Uwe K. (ukhl)


Lesenswert?

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
von Alexander S. (esko) Benutzerseite


Lesenswert?

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.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

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".

von Alexander Schmidt (esko) (Gast)


Lesenswert?

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?

von Uwe K. (ukhl)


Lesenswert?

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
von Alexander Schmidt (esko) (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.