ATTiny13 2x ADC Gleicher Wert ?

OP #2011370
Lesenswert?

Moin!
Ich möchte einen LIPO-Akku mit zwei in Reihe geschalteten Zellen mit 
einem ATTiny 13 überwachen. Dafür verwende ich den Balancieranschluss 
des Akkus, welcher auch den Kontakt zwischen den Zellen aus dem Akku 
führt.
Der µC soll die Spannung der einzelnen Zellen auswerten und bei 
unterschreiten der 3,0 Volt/Zelle den Ausgang PB0 ausschalten.
Da die Eingänge nur 5 Volt vertragen, der Akku aber bis zu 8,4 Volt hat, 
sind eingestellte Potis davor, die die jeweilige Zellenspannung 
halbieren.
Die Zelle, die als erste die Mindestmarke erreicht, schaltet den Ausgang 
aus. Das Abschalten des Ausgang ist auch das Ende der 
while-Schleifenbedingung. Danach soll nur noch für 60 Sekunden die LED 
leuchten, die für die passende Zelle eingeschaltet wurde.

Mein Problem ist, das bei unterschreiten einer Zellenspannung beide 
LED's leuchten. Folglich beide Bedingungen auslösen. Das kann aber 
eigentlich nicht sein, da es immer einen kleinen Unterschied in den 
Zellen gibt.

Ich gehe davon aus, dass ADMUX für die ADC-Wandlung nicht richtig 
funktioniert. Schaut bitte einmal über das Programm und schreibt mir ob 
ich richtig liege oder irgend was übersehe.

Danke...
1
#define F_CPU 9600000
2
#include <avr/io.h>
3
#include <util/delay.h>
4

5
//******************************************* 
6

7
unsigned int Spannung   = 0;
8
unsigned int Zelle_1    = 0;
9
unsigned int Zelle_2    = 0;
10

11
//******************************************* 
12

13
void ADC_Wandlung()
14
{
15
  ADCSRA |=   (1 << ADSC);           // erste Wandlung
16
  while (ADCSRA & (1 << ADSC)){;}    // warte bis ADWdlg. fertig
17
  Spannung = ADCW;                  // Übergabe Wert 1
18
  Spannung = 0;            // Löschen des Ergebnisses
19
    
20
  for(int i=0; i<10; i++ )      // Abfrage X mal wiederholen
21
  {
22
    ADCSRA |=   (1 << ADSC);       // start Wandlung
23
    while (ADCSRA & (1 << ADSC)){;} // warte bis ADWdlg. fertig
24
    Spannung += ADCW;        // Aufaddieren der Werte
25
  } 
26
    
27
  Spannung /= 10;            // Mittelwert bilden
28
}
29

30
//******************************************* 
31

32
int main (void)
33
{
34
  DDRB |= (1<<PB0) | (1<<PB1)| (1<<PB2);     //  
35

36
  // Grundeinstellungen für ADC-Wandlung
37
  ACSR |= (1<<ACD);          // Ausschalten des Analog Comperator
38
  CLKPR = 0x40;            // Takt Vorteiler hier 1 Clock Prescale Register
39

40
  ADCSRA |=   (1 << ADEN);            // Analog-Digital einschalten
41
//  ADCSRA |=  (1 << ADPS2);      // set prescaler
42
  ADCSRA |=  (1 << ADPS1);           // set prescaler
43
//  ADCSRA |=  (1 << ADPS0);           // set prescaler (clock / 2)
44
   
45
//  ADMUX  |=  (1 << ADLAR);          // 8bit in ADCH   
46
//  ADMUX  |=  (1 << REFS0);      // Interne Referenzspannung einschalten 1,1 Volt
47

48
//******************************************* 
49

50
  _delay_ms(4900);
51
  PORTB |= (1<<PB0);
52
  
53
  while (( PORTB & 0x01 ) == 0x01 )
54
  {
55
    ADMUX  |=   (1 << MUX1);  // ADC3 einschalten
56
    ADMUX  |=   (1 << MUX0);
57
    ADC_Wandlung();
58
    Zelle_1 = Spannung;  // Übergabe Wert 1   4,2 Volt
59

60
    ADMUX  |=   (1 << MUX1);  // ADC2 einschalten
61
    ADMUX  &=  ~(1 << MUX0);
62
    ADC_Wandlung();
63
    Zelle_2 = Spannung;  // Übergabe Wert 2   8,4 Volt
64

65
    Zelle_2 -= Zelle_1;  // 8,4 Volt - 4,2 Volt
66

67
    if ( Zelle_1 < 307 ) { PORTB &= ~(1<<PB0); PORTB |= (1<<PB1); }
68
    if ( Zelle_2 < 307 ) { PORTB &= ~(1<<PB0); PORTB |= (1<<PB2); }
69

70
    _delay_ms(100);
71
    }
72
  
73
  for (unsigned int a = 0; a<60000; a++) { _delay_ms(1); }
74

75
  PORTB &= ~(1<<PB1);
76
  PORTB &= ~(1<<PB2);
77
  
78
return(0);
79
}
Gast #2011386
Lesenswert?

Hast Du deine beiden Spannungen direkt an den ADC-Eingängen selber 
nachgemessen ?
Ich vermute dass hier
1
   if ( Zelle_1 < 307 ) { PORTB &= ~(1<<PB0); PORTB |= (1<<PB1); }
 ein 'else' fehlt...

Nach 60 Sekunden gehen beide Pins eh auf 0 - das meinst Du nicht ?
#2011417
Lesenswert?

Bernd M. schrieb:

> Ich gehe davon aus, dass ADMUX für die ADC-Wandlung nicht richtig
> funktioniert.

Das müsste schon klappen.
Denn du machst ja hier

>     Zelle_2 -= Zelle_1;  // 8,4 Volt - 4,2 Volt

die Differenz, und wenn die beiden Messwert identisch wären, dann würde 
da immer 0 rauskommen und damit sofort die Überwachung anschlagen. Da 
dies aber deiner Beschreibung nach offenbar aber nicht passiert, heißt 
das, das die 2.te Messung ein höheres Ergebnis bringt als die erste.


Wie testest du?

Ich würde mir mit einem Poti eine variable Spannung erzeugen und die auf 
den ADC Eingang legen und den anderen mit einer fixen Spannung am 
auslösen hindern.


Deine jetzigen Spannungsteilerpoti sind sicher so verschaltet, dass sie 
die Eingangsspannung halbieren? Und zwar beide, jeder für sich (sonst 
kannst du nämlich die Messwerte nicht so einfach miteinander verrechnen)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren