Forum: Mikrocontroller und Digitale Elektronik ATTiny13 interne Batterie kontrolle


von Stefan A. (ripper121)


Lesenswert?

Hallo,
ich würde gern die LiPo batterie welche an meinem Tiny13 hängt 
überwachen damit sie nicht unter 3V kommt.
Dazu möchte ich die interne 1.1V quelle gegen VCC messe.
Es soll ohne extra Komponenten funktionieren (geht bei tiny85 auch)

ist das so möglich?
1
void setup()
2
{
3
}
4
5
void loop()
6
{  
7
  // Read 1.1V reference against AVcc
8
  // set the reference to Vcc and the measurement to the internal 1.1V reference
9
  if (ADMUX != (1<<REFS0))
10
  {
11
    ADMUX = (1<<REFS0);
12
13
    // Bandgap reference start-up time: max 70us
14
    // Wait for Vref to settle.
15
    delayMicroseconds(350); 
16
  }
17
  
18
  // Start conversion and wait for it to finish.
19
  ADCSRA |= _BV(ADSC);
20
  while (bit_is_set(ADCSRA,ADSC)) {};
21
    
22
  // Result is now stored in ADC.
23
  
24
  // Calculate Vcc (in V)
25
  float vcc = 1.1*1023.0 / ADC;
26
27
  // Apply compensation
28
  vcc *= 1.0;
29
  
30
}

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Stefan A. schrieb:
> Dazu möchte ich die interne 1.1V quelle gegen VCC messe.
> Es soll ohne extra Komponenten funktionieren (geht bei tiny85 auch)

Das nennt sich Bandgap.
Ist eine tolle Sache. Der 13er hat das aber leider nicht.

mfg.

von Johannes O. (jojo_2)


Lesenswert?

1. Warum probierst du das nicht einfach aus? Häng den Attiny an ein 
Labornetzteil und stell einfach die Spannung ein.

2. Ich denke nicht dass das SO läuft wie es aktuell da steht: Was machst 
du denn mit dem Ergebnis?

3. "float" auf einem AVR mit 1KB FLASH ist nicht sinnvoll bzw. 
vermutlich auch gar nicht möglich. Du brauchst hier kein Float. Du 
brauchst den Wert auch nicht in Volt. Rechne doch einfach mit Integer 
weiter und du weißt dann, dass der Wert von 123 z.B. 3V entspricht (nur 
ein Beispiel, keine korrekten Zahlen!).

von Thomas E. (thomase)


Lesenswert?

Johannes O. schrieb:
> Warum probierst du das nicht einfach aus?

Was soll er denn ausprobieren? Der Tiny13 hat diese Funktion nicht.

mfg.

von Stefan A. (ripper121)


Lesenswert?

Also muss ich den Tiny85 nehmen :(

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Das nennt sich Bandgap.
> Ist eine tolle Sache. Der 13er hat das aber leider nicht.

Doch, natürlich hat der ATtiny13 eine Bandgap-Referenz, eben die
1,1 V.  Allerdings kann man diese nicht an einen Eingang des ADC
legen und gegen Vcc relativ messen damit.

Stefan A. schrieb:
> Also muss ich den Tiny85 nehmen :(

Naja, ein ATtiny25 würde es auch tun, große Mengen an Code oder RAM
wirst du ja wohl nicht brauchen, wenn es bislang alles in den 13er
gepasst hat.

Da er ansonsten pinkompatibel ist, was spricht denn dagegen?  Wirklich
teurer ist er ja auch erst, wenn du davon einige 10000 Stück kaufen
willst.

von Thomas E. (thomase)


Lesenswert?

Jörg W. schrieb:
> Allerdings kann man diese nicht an einen Eingang des ADC
> legen und gegen Vcc relativ messen damit.

Ja eben. Und darum geht es, das man diese nicht über den Mux schalten 
kann.
Und die heisst meistens VBG. Manchmal kann man die Korinthen auch da 
lassen, wo sie sind.

mfg.

: Bearbeitet durch User
von Stefan A. (ripper121)


Lesenswert?

Jörg W. schrieb:
> Stefan A. schrieb:
>> Also muss ich den Tiny85 nehmen :(
>
> Naja, ein ATtiny25 würde es auch tun, große Mengen an Code oder RAM
> wirst du ja wohl nicht brauchen, wenn es bislang alles in den 13er
> gepasst hat.
>
> Da er ansonsten pinkompatibel ist, was spricht denn dagegen?  Wirklich
> teurer ist er ja auch erst, wenn du davon einige 10000 Stück kaufen
> willst.

Wegen dem Verbrauch. Der tiny85 braucht 10µA und der tiny13 4µA.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan A. schrieb:
> Der tiny85 braucht 10µA und der tiny13 4µA.

Unter welchen Randbedingungen denn?

Und nochmal: ATtiny25 genügt.

von Thomas E. (thomase)


Lesenswert?

Stefan A. schrieb:
> Wegen dem Verbrauch. Der tiny85 braucht 10µA und der tiny13 4µA.

Unter welcher Bedingung?

mfg.

von Stefan A. (ripper121)


Lesenswert?

Der tiny13 misst alle 10 Sec einen LDR über ADC.
Wenn es dunkel wird blinkt er alle 2 Sec für 500 ms (3-4Leds).
Danach geht er in Schlafmodus.
1
#include <avr/interrupt.h>
2
#include <avr/sleep.h>
3
byte power_counter=0;
4
byte adc_counter=0;
5
int adc_in=1024;
6
7
//Light 15, Dark 1000;
8
9
ISR(WDT_vect) {
10
  power_counter++;
11
  adc_counter++;
12
}
13
14
void setup(){
15
  // set timer to 0.016s
16
  // WDTCR |= (0<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);
17
  // set timer to 0.032s
18
  // WDTCR |= (0<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
19
  // set timer to 0.064s
20
  // WDTCR |= (0<<WDP3) | (0<<WDP2) | (1<<WDP1) | (0<<WDP0);
21
  // set timer to 0.125s
22
  // WDTCR |= (0<<WDP3) | (0<<WDP2) | (1<<WDP1) | (1<<WDP0);
23
  // set timer to 0.250s
24
  // WDTCR |= (0<<WDP3) | (1<<WDP2) | (0<<WDP1) | (0<<WDP0);
25
  // set timer to 0.5s
26
  // WDTCR |= (0<<WDP3) | (1<<WDP2) | (0<<WDP1) | (1<<WDP0);
27
  //set timer to 1 sec
28
  WDTCR |= (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0);
29
  //set timer to 2 sec
30
  //WDTCR |= (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
31
  //set timer to 4 sec
32
  //WDTCR |= (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);
33
  //set timer to 8 sec
34
  //WDTCR |= (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP1);
35
36
37
  ADCSRA &= ~(1<<ADEN);     //Turn off ADC
38
  ACSR |= _BV(ACD);         //Disable analog comparator
39
40
  // Set watchdog timer in interrupt mode
41
  WDTCR |= (1<<WDTIE);
42
  WDTCR |= (0<<WDE);
43
44
  sei(); // Enable global interrupts
45
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
46
}
47
48
49
void loop() {
50
  sleep_mode();
51
  if(power_counter >= 2)
52
  {    
53
    power_counter = 0;
54
    if(adc_counter >= 10){ //every 10 Seconds Read ADC
55
      adc_counter=0;
56
      adc_setup();
57
      adc_in=adc_read();
58
    }
59
    if(adc_in>15){ //Higher Value = Darker
60
      pinMode(PB0,OUTPUT);
61
      pinMode(PB1,OUTPUT);
62
      pinMode(PB3,OUTPUT);
63
      pinMode(PB4,OUTPUT);
64
      digitalWrite(PB0,HIGH);
65
      digitalWrite(PB1,HIGH);
66
      digitalWrite(PB3,HIGH);
67
      digitalWrite(PB4,HIGH);
68
      delay(250);
69
    }
70
    power_off();
71
  }
72
}
73
74
75
void adc_setup (void)
76
{
77
  pinMode(PB2,INPUT);
78
  digitalWrite(PB2,HIGH);
79
  // Set the ADC input to PB2/ADC1
80
  ADMUX |= (1 << MUX0);
81
  ADMUX |= (1 << ADLAR);
82
  // Set the prescaler to clock/128 & enable ADC
83
  ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
84
85
}
86
87
int adc_read (void)
88
{
89
  int adc_val = 0;
90
  for(byte i=0;i<3;i++){
91
    // Start the conversion
92
    ADCSRA |= (1 << ADSC);
93
    // Wait for it to finish
94
    while (ADCSRA & (1 << ADSC));
95
    adc_val += ADCH;
96
  }
97
  adc_val = adc_val / 3;
98
  return adc_val;
99
}
100
101
void power_off(){
102
  pinMode(PB0,INPUT);
103
  pinMode(PB1,INPUT);
104
  pinMode(PB2,INPUT);
105
  pinMode(PB3,INPUT);
106
  pinMode(PB4,INPUT);
107
  digitalWrite(PB0,LOW);
108
  digitalWrite(PB1,LOW);
109
  digitalWrite(PB2,LOW);
110
  digitalWrite(PB3,LOW);
111
  digitalWrite(PB4,LOW);
112
  ADCSRA &= ~(1<<ADEN);     //Turn off ADC
113
  ACSR |= _BV(ACD);         //Disable analog comparator
114
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Trotzdem unverständlich, warum ein ATtiny25 damit mehr Energie
verbrauchen sollte als ein 13er.  Die Kurven für den typischen
Stromverbrauch sind bei beiden ziemlich ähnlich.

Ich habe in einer vergleichbaren Anwendung einen ATmega128RFA1 laufen,
der braucht im Mittel irgendwas um 1 µA herum.  Ist ein Wettersensor,
der wie bei dir jede Sekunde vom Watchdog aufwacht, und dann aller
5 Minuten eine Messung eines SHT-21 anwirft und das Ergebnis zur
Basisstation innerhalb der Wohnung funkt.

: Bearbeitet durch Moderator
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Beim Tiny25/45/85 lohnt es sich, mal das PRR Register anzuschauen. Dort 
kann man beide Timer Module, das USI und den ADC abschalten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Matthias S. schrieb:
> Dort kann man beide Timer Module, das USI und den ADC abschalten.

Interessiert aber nur im idle oder active mode.

Wenn ich den (offenbar) Arduino-Code richtig deute, dümpelt der aber
möglicherweise wirklich nur im idle mode herum, statt den Controller
ordentlich schlafen zu legen (power-down mode).

Dort ist natürlich noch viel Einsparungspotenzial.

: Bearbeitet durch Moderator
von abc@def.de (Gast)


Lesenswert?

Matthias S. schrieb:
> Beim Tiny25/45/85 lohnt es sich, mal das PRR Register anzuschauen. Dort
> kann man beide Timer Module, das USI und den ADC abschalten.
Was m.E. kaum was ausmacht, messbar ja, aber Auswirkungen z.B. beim 
Batteriebetrieb vernachlässigbar. Ob der jetzt 5µA mehr verbraucht das 
juckt doch keinen, da hat z.B. die Temperatur bei Outdooreinsatz viel 
grösseren Einfluss.

von Holger L. (max5v)


Lesenswert?

Eventuell könnte man es mit dem Brownoutdetector versuchen. Den sollte 
man eigentlich vor dem Schlafmodus deaktivieren können damit er nicht 
unnötig Energie verpulvert.
Da der Brownout nur 2,7 Volt erkennen kann, könnte man mit einer Diode 
die gleichzeitig noch als Verpolschutz dient auf ~ 3,0 Volt kommen.
Das ist allerdings nur graue Theorie.

von Peter D. (peda)


Lesenswert?

Stefan A. schrieb:
> Wegen dem Verbrauch. Der tiny85 braucht 10µA und der tiny13 4µA.

Was soll denn das Programm machen?
Wenn da LEDs dranhängen, sollten die 10µA mehr doch nichts ausmachen.
Und ansonsten gehe in Power-Down ohne Watchdog (0,5µA @5V) und laß ihn 
per PCINT aufwachen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Was soll denn das Programm machen?

Er hat's doch oben gepostet.

von Holger L. (max5v)


Lesenswert?

Mir ist gerade noch was aufgefallen. Von den 5 verfügbaren Pins werden 4 
dazu verwendet die Led's zu steuern, und zwar werden alle gleichzeitig 
ein bzw. ausgeschaltet. Das heißt man könnte die 4 Led's mit einem 
Transistor schalten und hätte somit noch genügend Pins für eine ADC 
Messung frei.

Das Blinken sollte wenigstens mit dem Watchdog realisiert werden, der 
delay kostet nur unnötig Energie.

von Stefan A. (ripper121)


Lesenswert?

Holger L. schrieb:
> Mir ist gerade noch was aufgefallen. Von den 5 verfügbaren Pins
> werden 4
> dazu verwendet die Led's zu steuern, und zwar werden alle gleichzeitig
> ein bzw. ausgeschaltet. Das heißt man könnte die 4 Led's mit einem
> Transistor schalten und hätte somit noch genügend Pins für eine ADC
> Messung frei.
>
> Das Blinken sollte wenigstens mit dem Watchdog realisiert werden, der
> delay kostet nur unnötig Energie.

Ich habe noch ein ADC pin frei, verwende nur 3 Leds.
Ich wollte so wenig wie möglich extra teile.
Weis leider nicht wie das mit dem WDT geht.

von Holger L. (max5v)


Lesenswert?

Wenn die Bedingung das es Blinken soll erfüllt ist wird der Watchdog auf 
0,25 Sekunden konfiguriert, die Leds werden eingeschaltet.

In der loop Schleife wird vorher geprüft ob die entsprechenden LED Pins 
high sind, wenn das der Fall ist wird der Watchdog wider auf 2 Sekunden 
konfiguriert, die Led's werden ausgeschaltet.

Allerdings ergeben sich dadurch andere Zeiten, da eine Watchdogauslösung 
die Counter statt nach 2 Sekunen nach 0,25 Sekunden erhöht, die könnte 
man allerdings um eins erniedrigen wodurch sich dann nur noch ein plus 
von 0,25 Sekunden ergeben würde.

von Hannes (Gast)


Lesenswert?

Stefan A. schrieb:
> Ich habe noch ein ADC pin frei, verwende nur 3 Leds.

Falls Du eine der LEDs an einem ADC-tauglichen Pin hast, dann kannst Du 
auch indirekt die Akkuspannung ermitteln.

Dazu schaltest Du den Pin mit der LED auf Eingang und auf H. Der interne 
PullUp-Widerstand wird aktiv, es fließt ein sehr geringer Strom durch 
die LED. Der ist so gering, dass der Spannungsabfall am LED-Widerstand 
vernachlässigbar klein ist.

Nun misst Du die Spannung, die an der LED (incl. Vorwiderstand) abfällt 
gegen Vcc als Referenz. Da dürftest Du je nach LED-Typ etwa 1,8 V bis 3 
V erwarten.

Und schon hast Du genau das, was Du mit der Bandgap-Spannung machen 
wolltest, nur mit etwas mehr Auflösung, da die Spannung an der LED höher 
ist.

Und es kostet Dich nichts, denn die LED ist ja schon da und kann in 
einem kurzen Teil der Dunkelphase mal nebenher als Spannungsreferenz 
missbraucht werden.

;-)

Natürlich gelten weiterhin alle bereits gegebenen Hinweise zum 
Sleepmode.

...

von Stefan A. (ripper121)


Lesenswert?

cool danke werde ich mal probieren :)

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.