-         

Ergebnis 1 bis 7 von 7

Thema: Akku messen ohne ext. Spannungsteiler

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255

    Akku messen ohne ext. Spannungsteiler

    Anzeige

    Eine Methode, mit der ein AVR seine eigene Betriebsspannung messen kann, ohne einen externen Spannungsteiler zu benötigen.

    Ich baue gerne besonders kleine Roboter. Mein aktuelles Projekt wiegt nur etwa 25g.

    Dafür braucht man natürlich auch sehr kleine Akkus.
    Mittlerweile sind aber kleine LiPos recht günstig zu haben. Man muss bei ihnen jedoch aufpassen, sie nicht zu tief zu entladen, sonst gehen sie schenll kaputt. Also muss eine Überwachung der Akkuspannung her!

    Die übliche Methode ist es nun, die Akkuspannung über einen Spannungsteiler herunterzuteilen und sie dann mit dem ADC zu messen, der mit der internen Referenzspannung betrieben wird. Der Nachteil dabei ist natürlich, dass man zwei Widerstände braucht, und wenn man auf 3,5x2,5cm einen Mega8, einen Motortreiber, diverse Steckverbinder, Elkos und andere Teile unterbringen muss, ist man für jedes Teil weniger dankbar.

    Nun habe ich eine Methode gefunden, wie ein AVR seine Betriebsspannung messen kann, und zwar ohne externe Bauteile.
    Die interne Referenzspannung von 2,56V im Mega8 wird aus der sogenannten "Bandgap-Referenz" mit einer Spannung von 1,23V erzeugt. Diese Spannung kann man als Eingang für den ADC auswählen. Und wenn man jetzt AVCC als Referenz für den ADC wählt, hat man folgende Situation am ADC:
    -> Eingangsspannung bekannt, 1,23V
    -> AVCC unbekannt, Betriebsspannung des AVR= Akkuspannung

    Also die umgekehrte Situation wie bei einer normalen ADC-Messung, wo die Eingangsspannung unbekannt und die Referenz bekannt ist.
    Das ist aber letztendlich nur ein mathematisches Problem, das leicht zu lösen ist. Man erhält für den ADC-Messwert zu einer gegebenen Akkusspannung:
    ADCval= (1,23V/Uakku)*1024
    Damit kann man sich nun zu einem Spannungs-Grenzwert den ADC-Wert berechen, um bei Überschreitung dieses Wertes Alarm auszulösen.
    Überschreitung, weil die Zuordnung ADC-Wert->Spannung eine Antiproportionalität ist:
    Uakku= (1,23V/ACDval)*1024

    Die Umsetzung ist nicht weiter schwierig. Man muss bloß bei der Wahl des ADC-Kanals die MUX..-Kombination für Vbg (Siehe Tabelle der ADC-Eingänge im Datenblatt) auswählen. Beim Mega8 entspricht das Kanal 14. Außerdem muss natürlich die Referenz auf AVCC eingestellt sein. Und natürlich klappt es nur, wenn der AVR direkt vom Akku gespeist wird.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hallo,

    das ist genial! Vielen Dank für die Publikation Deiner Idee!

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.254
    Hallo uwegw,

    ja, die Idee hat was

    Die interne Referenzspannung von 2,56V im Mega8 wird aus der sogenannten "Bandgap-Referenz" mit einer Spannung von 1,23V erzeugt. Diese Spannung kann man als Eingang für den ADC auswählen.
    Per Software? Oder per Leiterbahn von Aref auf einen AD-Eingang?

    -> Eingangsspannung bekannt, 1,23V
    Welchen AVR meinst du dabei?
    Ich kenne nur welche mit 2,56V oder 1,1V als interne Referenz.

    Gruß, Michael

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Es wird alles intern geschaltet. Extern wird nur AVCC an VCC gelegt, der AREF-Pin bleibt frei bzw bekommt nen 100n nach GND.

    Die 1,23V kann man über das ADMUX-Register auf den ADC-Eingang legen. Im Datenblatt ist ein Tabelle, die die Zuordnung ADMUX-Wert->ADC-Pin angibt. Darin steht neben den "normalen" Eingängen auch die Codes für Vbg. Beim Mega8 ist das die 0b1110. Meine ADC-Routine bekommt als Parameter die Kanalnummer übergeben. Normalerweise also 0 bis 7. Nun bekommt sie einfach die 14, und dann wird die Bandgap-Spannung gemessen.

    Die 1,23V sind nur ein interne Zwischenspannung, die man sonst kaum zu Gesicht bekommt. Sie wird noch mal verstärkt, um die 2,56V zu erzeugen.

    Getestet hab ich mit einem Mega8 und einem Mega32.

    Code für den M8:
    Code:
    uint16_t ReadChannel(uint8_t mux)
    {
      uint8_t i;
      uint16_t result = 0;     
      ADMUX = mux;       // Kanal waehlen
      ADMUX|=(1<<REFS0); //Referenz: AVCC
      //ADMUX|=(1<<REFS1)|(1<<REFS0); //interne Referenz
    
      /*"Dummy-Readout"*/
      ADCSR |= (1<<ADSC);              // eine ADC-Wandlung 
      while ( ADCSR & (1<<ADSC) );     // auf Abschluss der Konvertierung warten 
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
      for(i=0;i<4;i++)
      {
        ADCSR |= (1<<ADSC);            // eine Wandlung "single conversion"
        while ( ADCSR & (1<<ADSC) );   // auf Abschluss der Konvertierung warten
        result += ADCW;		    // Wandlungsergebnisse aufaddieren
      }
      result /= 4;     // Summe durch vier teilen = arithm. Mittelwert
      return result;
    } //end.ReadChannel
    
    
    void akkutest(void)
    {
    uint16_t akkumess;
    
    //Bandgap messen, Ref= AVCC = Akkuspannung
    akkumess=ReadChannel(14);
    if(akkumess<350) {/*...*/} //mehr als 3,5V
    else if(akkumess<410) {/*...*/} //mehr als 3V
    		else {/*...*/} //weniger als 3V
    
    }
    Beim M32 ist der Code die 0b11110, also ReadChannel(30);

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.254
    Hallo uwegw,

    ah, ja, und als "Voltage Referenz Selections" setzt du RefS0 für "AVCC with external capacitor at AREF pin"
    Das nenn ich mal tricky

    So ein Roboter hat ja so manche Analog-Sensorik an Board.
    Wenn du jetzt aber noch andere AD-Kanäle lesen willst, schaltest du dann eine andere Spannung auf Aref?

    Gruß, Michael

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Geplant sind fünf Liniensensoren. Dafür werde ich die Referenz auf AVCC lassen. Die Sensoren (TCRT1000) arbeiten als Spannungsteiler aus Fototransistor und Widerstand, der ebenfalls direkt vom Akku gespeist wird. Und wenn ich nun AVCC als Ref nutze, ändert sich der Messwert bei schwankender Spannung nicht.

    Sollten mal Sensoren hinzukommen (ich kann die Sensorplatine einfach aufstecken), wo die absolute Spannung gebraucht wird, würde ich die interne Referenz nutzen.

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Methode ist gut, aber nicht wirklich neu.

    Wenn für andere Messungen von AVCC auf die 2,56 V umschaltet muß man etwas Aufpassen. Es dauert relativ lange bis die Spannung am Kondensator am AREF Pin sinkt. Also entweder eine paar ms Warten oder den Kondensator eher klein (z.B. 10 nF) wählen.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •