www.mikrocontroller.net

Forum: Compiler & IDEs ATTiny13 2x ADC Gleicher Wert ?


Autor: Bernd M. (adventureman1972)
Datum:

Bewertung
0 lesenswert
nicht 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...

#define F_CPU 9600000
#include <avr/io.h>
#include <util/delay.h>

//******************************************* 

unsigned int Spannung   = 0;
unsigned int Zelle_1    = 0;
unsigned int Zelle_2    = 0;

//******************************************* 

void ADC_Wandlung()
{
  ADCSRA |=   (1 << ADSC);           // erste Wandlung
  while (ADCSRA & (1 << ADSC)){;}    // warte bis ADWdlg. fertig
  Spannung = ADCW;                  // Übergabe Wert 1
  Spannung = 0;            // Löschen des Ergebnisses
    
  for(int i=0; i<10; i++ )      // Abfrage X mal wiederholen
  {
    ADCSRA |=   (1 << ADSC);       // start Wandlung
    while (ADCSRA & (1 << ADSC)){;} // warte bis ADWdlg. fertig
    Spannung += ADCW;        // Aufaddieren der Werte
  } 
    
  Spannung /= 10;            // Mittelwert bilden
}

//******************************************* 

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

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

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

//******************************************* 

  _delay_ms(4900);
  PORTB |= (1<<PB0);
  
  while (( PORTB & 0x01 ) == 0x01 )
  {
    ADMUX  |=   (1 << MUX1);  // ADC3 einschalten
    ADMUX  |=   (1 << MUX0);
    ADC_Wandlung();
    Zelle_1 = Spannung;  // Übergabe Wert 1   4,2 Volt

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

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

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

    _delay_ms(100);
    }
  
  for (unsigned int a = 0; a<60000; a++) { _delay_ms(1); }

  PORTB &= ~(1<<PB1);
  PORTB &= ~(1<<PB2);
  
return(0);
}




Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du deine beiden Spannungen direkt an den ADC-Eingängen selber 
nachgemessen ?
Ich vermute dass hier
   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 ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: form (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd M. schrieb:
> und bei unterschreiten der 3,0 Volt/Zelle den Ausgang PB0 ausschalten

3 Volt sind aber schon etwas brutal...
Ich glaube bei ca. 3,2 Volt wird es kritisch. Lieber schon bei 3,3 Volt 
abschalten.

Autor: Bernd M. (adventureman1972)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es klappt !!!

Habe aber nichts mehr geändert im Programm!?

Der Lipo wird bei 6,3 Volt von der Last befreit. Die zwei LEDs zeigen 
mir an, welche von den beiden Zellen die Schaltschwelle erreicht hat. 
Genau was ich wollte!

Der Tip(p) mit der Festspannung war Klasse...


Danke !

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.