- LiFePO4 Speicher Test         
Ergebnis 1 bis 8 von 8

Thema: Atmega48 + ADC + PWM

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    11.03.2005
    Ort
    Kissing bei Augsburg
    Alter
    34
    Beiträge
    443

    Atmega48 + ADC + PWM

    Anzeige

    Powerstation Test
    Hallo,

    habe mir ein Programm geschrieben, mit dem ich 4 Akku laden kann.
    Allerdings zickt das Progrämmchen noch. Ab und zu kommen vom ADC-Wandler Werte, die um 20-40 zu hoch / zu niedrig sind. Bis jetzt habe ich noch keine wiederholbarkeit festellen können.

    Jetzt mein Frage:
    Da ich ja auch gleichzeitig PWM nutze, kann es sein, dass das PWM dort reinspuckt und den ADC dadurch dureinander bringt?
    Ich nutze Hardware PWM.
    Dann habe ich noch einen Timer, um alle 10s den ADC zu messen, musste aber dort auch eine Variable einfügen, die hochgezählt wird. Kann es am Interrupt liegen? Das der dann den ADC stört?

    Naja, ich hoffe ihr könnt helfen.

    Hier noch der Code:

    Code:
    '########################################
    '######### Akkulader 2009.2.25 ##########
    '######### c Michael Brambach ###########
    '########################################
    '# Ein vervielfältigung ohne die        #
    '# Zustimmung des Autors ist verboten.  #
    '# Es darf nur für private Zwecke       #
    '# genutzt werden.                      #
    '# Wer diese Programm nutzen möchte,    #
    '# sollte beim Autor eine Nachricht     #
    '# hinterlassen. Es steht grundsätzlich #
    '# einer privaten Nutzung nichts im     #
    '# Wege.                                #
    '########################################
    $regfile = "m48def.dat"                                     ' specify the used micro
    
    $crystal = 4000000                                          ' used crystal frequency
    
    $baud = 19200                                               ' use baud rate
    
    $hwstack = 32                                               ' default use 32 for the hardware stack
    
    $swstack = 10                                               ' default use 10 for the SW stack
    
    $framesize = 40                                             ' default use 40 for the frame space
    
    Config Portd = Output
    
    
    '----- L C D ----
    
    Config Lcdpin = Pin , Db4 = Portd.6 , Db5 = Portd.7 , Db6 = Portd.4 , Db7 = Portd.2 , E = Portb.0 , Rs = Portd.5
    Config Lcdbus = 4
    Config Lcd = 16 * 2
    
    '---- E I N G Ä N G E ----
    
    Config Portb.5 = Input
    Config Portc.5 = Input
    Config Portc.4 = Input
    Config Portb.4 = Output
    
    
    'Sonderzeichen
    Deflcdchar 0 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 31
    Deflcdchar 1 , 32 , 32 , 32 , 32 , 32 , 31 , 31 , 31
    Deflcdchar 2 , 32 , 32 , 32 , 31 , 31 , 31 , 31 , 31
    Deflcdchar 3 , 32 , 31 , 31 , 31 , 31 , 31 , 31 , 31
    Deflcdchar 4 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31
    Deflcdchar 5 , 31 , 17 , 23 , 19 , 23 , 23 , 31 , 31
    Deflcdchar 6 , 32 , 4 , 8 , 31 , 8 , 4 , 32 , 32
    
    
    '---- T I M E R ----
    Config Timer0 = Timer , Prescale = 1024
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
    Config Timer2 = Pwm , Pwm = On , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
    
    Enable Timer0
    
    
    '---- A D C ----
    Config Adc = Single , Prescaler = Auto
    Start Adc
    
    
    '---- I N T E R R U P T S ----
    On Timer0 Isr_tim0
    Enable Interrupts
    
    
    
    '---- V A R I A B L E N ----
    'Fir-Regler
    Dim Fir1(40) As Integer
    Dim Fir2(40) As Integer
    Dim Fir3(40) As Integer
    Dim Fir4(40) As Integer
    'Dim Fir(4) As Integer
    
    
    'Fir Rechen Variablen
    Dim Ende1_1 As Integer
    Dim Ende2_1 As Integer
    Dim Ende3_1 As Integer
    Dim Ende4_1 As Integer
    Dim Ende1_2 As Integer
    Dim Ende2_2 As Integer
    Dim Ende3_2 As Integer
    Dim Ende4_2 As Integer
    Dim Ende(4) As Integer
    
    'PWM Speicherwerte
    Dim Akku(4) As Integer
    
    'Timerkorrektur + Doppeldurchläufe vermeiden
    Dim Durchlauf As Byte                                       'akkuladen
    Dim G As Bit                                                'akkuladen
    
    Dim Durchlauf1 As Byte                                      'Taster
    Dim G1 As Bit                                               'Taster
    
    'vitueller Akku
    Dim Wert(4) As Byte
    
    'Ladeschluss Variable
    Dim Ladeschlu(4) As Byte
    
    'Schleifenwerte
    Dim M As Byte
    Dim Z As Byte
    Dim N As Byte
    
    'Taster
    Dim T1 As Bit                                               'rauf
    Dim T2 As Bit                                               'runter
    Dim T3 As Bit                                               'rechts
    Dim T4 As Bit                                               'links
    Dim T5 As Bit                                               'OK
    
    'Sonstiges
    Dim Akt As Byte                                             'Courserposition
    Dim C As Byte                                               'Akkuladebalken
    Dim Pwm(4) As Integer                                       'PWM Wert
    
    
    '---- A L I A S E ----
    E1 Alias Pinb.5
    E2 Alias Pinc.5
    E3 Alias Pinc.4
    Led1 Alias Portb.4
    
    
    'Wert(1) = 1
    'Wert(2) = 1
    'Wert(3) = 1
    'Wert(4) = 1
    
    Akt = 1
    
    Locate 1 , 6
    Lcd "mA      mA"
    Locate 2 , 6
    Lcd "mA      mA"
    
    Do
    
       If Durchlauf = 76 Then                                   '~ alle 10s eimal Durchlaufen (Akkulade Kontrolle)
          If G = 0 Then
    
             G = 1
             'Led1 = 1
             'Virtuell alles auf "1" setzen
    
             'Wert(1) = 1
             'Wert(2) = 1
             'Wert(3) = 1
             'Wert(4) = 1
    
    
             'Ladeschaltung auf "0" setzen
    
             Pwm1a = 0
             Pwm1b = 0
             Pwm2a = 0
             Pwm2b = 0
    
    
             'Fir Werte um 1 nach "vorne" verschieben
    
             For M = 1 To 39
    
                Fir1(m) = Fir1(m + 1)
                Fir2(m) = Fir2(m + 1)
                Fir3(m) = Fir3(m + 1)
                Fir4(m) = Fir4(m + 1)
    
             Next
    
    
             'Regler auswertungsvariablen nullen
    
             Ende1_1 = 0
             Ende2_1 = 0
             Ende3_1 = 0
             Ende4_1 = 0
    
             Ende1_2 = 0
             Ende2_2 = 0
             Ende3_2 = 0
             Ende4_2 = 0
    
    
             'ADC Werte auslesen und im "letzten" Fir Wert speichern.
    
             If Ladeschlu(1) = 1 Then
                Fir1(40) = Getadc(0)
             End If
    
             If Ladeschlu(2) = 1 Then
                Fir2(40) = Getadc(1)
             End If
    
             If Ladeschlu(3) = 1 Then
                Fir3(40) = Getadc(2)
             End If
    
             If Ladeschlu(4) = 1 Then
                Fir4(40) = Getadc(3)
             End If
    
             Print Fir1(40)
             'Regler auswerten.
             'Die Ersten 20 und die zweiten 20 Werten addiert und anschließend die ersten 20 von den 2ten 20 abgezogen.
    
             For M = 1 To 20
                Ende1_1 = Ende1_1 + Fir1(m)
                Ende2_1 = Ende2_1 + Fir2(m)
                Ende3_1 = Ende3_1 + Fir3(m)
                Ende4_1 = Ende4_1 + Fir4(m)
    
                Z = M + 20
    
                Ende1_2 = Ende1_2 + Fir1(z)
                Ende2_2 = Ende2_2 + Fir2(z)
                Ende3_2 = Ende3_2 + Fir3(z)
                Ende4_2 = Ende4_2 + Fir4(z)
             Next
    
             Ende(1) = Ende1_2 - Ende1_1
             Ende(2) = Ende2_2 - Ende2_1
             Ende(3) = Ende3_2 - Ende3_1
             Ende(4) = Ende4_2 - Ende4_1
    
    
             'Akkus virtuell wieder laden lassen
    
             For M = 1 To 4
                If Ende(m) < 0 Then
                   Wert(m) = 0
                   Ladeschlu(m) = 0
                Else
                   If Ladeschlu(m) = 1 Then
                      Wert(m) = 1
                   End If
                End If
    
             Next
    
    
             'Akkus offiziel wieder laden lassen, fals notwendig
    
             If Wert(1) = 0 Then Pwm1a = 0 Else Pwm1a = Pwm(1)
             If Wert(4) = 0 Then Pwm1b = 0 Else Pwm1b = Pwm(4)
             If Wert(3) = 0 Then Pwm2a = 0 Else Pwm2a = Pwm(3)
             If Wert(2) = 0 Then Pwm2b = 0 Else Pwm2b = Pwm(2)
    
          End If
       End If
    
    
    
    
       If Durchlauf1 = 3 Then
    
          If G1 = 0 Then                                        '~ alle 0,3s eimal Durchlaufen (Taster Auswertung)
    
             G1 = 1
    
    
             T1 = 0                                             '"rauf"
             T2 = 0                                             '"runter"
             T3 = 0                                             '"rechts"
             T4 = 0                                             '"links"
             T5 = 0                                             '"OK"
    
             If E1 = 1 Then                                     'Taster 1
    
                If E2 = 1 Then
                   T1 = 1
                   Goto Tasterende
                End If
    
                If E3 = 1 Then                                  'Taster 4
                   T4 = 1
                   Goto Tasterende
                End If
                                                            'Taster 5
                T5 = 1
                Goto Tasterende
             End If
    
             If E2 = 1 Then                                     'Taster 2
                T2 = 1
                Goto Tasterende
             End If
    
             If E3 = 1 Then                                     'Taster 3
                T3 = 1
                Goto Tasterende
             End If
    
             Tasterende:
    
             If T1 = 1 Then                                     '"Strom" erhöhen
                If Akku(akt) < 6000 Then
                   Akku(akt) = Akku(akt) + 100
                End If
             End If
    
             If T2 = 1 Then                                     '"Strom" verrringern
                If Akku(akt) > 1 Then
                   Akku(akt) = Akku(akt) - 100
                End If
             End If
    
             If T3 = 1 Then                                     'Position verschieben
                If Akt < 4 Then
                   Akt = Akt + 1
                End If
             End If
    
             If T4 = 1 Then                                     'Position in andere Richtung
                If Akt > 1 Then
                   Akt = Akt - 1
                End If
             End If
    
             If T5 = 1 Then                                     '"OK" Taster
    
                   Ladeschlu(akt) = 1                           'Ladeschluss aufheben
    
                   Pwm(akt) = Akku(akt) / 25
    
                   If Akt = 1 Then                              'Fir Regler leeren
                      For N = 1 To 40
                         Fir1(n) = 0
                      Next
                   End If
    
                   If Akt = 2 Then                              ' --"--"--
                      For N = 1 To 40
                         Fir2(n) = 0
                      Next
                   End If
    
                   If Akt = 3 Then                              ' --"--"--
                      For N = 1 To 40
                         Fir3(n) = 0
                      Next
                   End If
    
                   If Akt = 4 Then                              ' --"--"--
                      For N = 1 To 40
                         Fir4(n) = 0
                      Next
                   End If
    
                   Led1 = 1                                     'Visuell bestätigen durch LED ~0,3s an
             Else
                Led1 = 0
             End If
    
             'LCD Anzeige:
    
    
             For M = 1 To 2
    
                Locate M , 2
                Lcd "    "
                Locate M , 10
                Lcd "    "
                Locate M , 8
                Lcd " "
                Locate M , 16
                Lcd " "
    
             Next
    
    
             C = C + 1
    
             If C = 5 Then
                C = 0
             End If
    
             For N = 1 To 2
    
                   M = N * 2
                   Z = M - 1
    
                   If Akt = Z Then
                      Locate N , 8
                      Lcd Chr(6)
                   End If
    
                   If Akt = M Then
                      Locate N , 16
                      Lcd Chr(6)
                   End If
    
                   Locate N , 2
                   Lcd Akku(z)
    
                   Locate N , 10
                   Lcd Akku(m)
    
                   Locate N , 1
    
                   Lcd Chr(c)
                   Locate N , 1
                   If Ladeschlu(z) = 0 Then Lcd Chr(5)
    
                   Locate N , 9
    
                   Lcd Chr(c)
                   Locate N , 9
                   If Ladeschlu(m) = 0 Then Lcd Chr(5)
    
             Next
    
             Cursor Off
          End If
    
       End If
    
    Loop
    
    
    Isr_tim0:
    
       Durchlauf = Durchlauf + 1
    
       If Durchlauf = 77 Then
    
          Durchlauf = 0
          G = 0
    
       End If
    
       Durchlauf1 = Durchlauf1 + 1
    
       If Durchlauf1 = 4 Then
    
          Durchlauf1 = 0
          G1 = 0
    
       End If
    
    
    
    Return
    mfg
    Michael
    Besuch mal meine HP: www.highcurrent.de

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn das Layout nicht so besonders gut ist, könnte es schon Störungen geben. Die Ausgänge sollten nicht zu viel Strom schalten, die Masseführung sollte stimmen, und an VCC und AVcc sollten Abblockkondensatoren sein. Bei einem Brauchbaren Layout geht auch PWM während einer AD-wandlung. Der zu erwartende extra Fehler liegen mehr bei 1 LSB oder weniger.

    Der Interrupt sollte den ADC nicht stören. Es sei denn dort wird auch der AD Wandler ausgelesen oder die Ausgänge an PORT C geändert.

    Wenn die Störungen nur eher selten auftreten und man reichlich Zeit hat, könnte man mehrmals messen und dann mitteln bzw. die größten und kleinsten Werte verwerfen.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    11.03.2005
    Ort
    Kissing bei Augsburg
    Alter
    34
    Beiträge
    443
    Hallo,

    hmmm, das mit den Kondensatoren könnte sein, es sind ein paar wenige auf der Platine. (Hatte keine mehr da )
    Die Aussgänge schalten nur einmal eine LED, ansonsten über einen OP. Also da fließt kein Strom. Sie sind ja auch nicht immer an, auch nicht wenn der ADC misst.

    Die Störungen teten so alle 5-20 Messungen auf, dann stimmt es wieder ein paar und dann wieder so ein Aussreiser.
    Naja, Zeit hätte ich schon, aber der Mega48 ist voll . Es ist zwar ein Mega88 schon bestellt, aber der muss auch erst kommen.

    Aber eigentlich müsste es doch ohne die Krugz gehen, den AD Wandler auszulesne, ohne noch "nachrenen" zu müssen.

    Werde auf jeden Fall mal ein paar Kondensatoren noch einlöten.

    Danke schon mal

    mfg
    Michael
    Besuch mal meine HP: www.highcurrent.de

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Klingon77
    Registriert seit
    26.09.2006
    Ort
    Hunsrück
    Alter
    63
    Beiträge
    2.543
    hi,

    bin ja kein Elektroniker...


    Könnte man den Eingang des ADC´s ggf. mit einem kleinen Kondensator im nF oder gar im pF-Bereich gegen Masse nicht ein wenig "träger" machen?

    Evtl. nimmt der Kerko die Störungen raus.

    Der Ladevorgang der Akku´s geschieht ja langsam; sprich die Spannungsänderungen verlaufen recht langsam.

    Es würde auch genügen wenn man nur alle paar Sekunden eine Messung durchführt.


    liebe Grüße,

    Klingon77
    Der kürzeste Weg zwischen zwei Menschen ist ein Lächeln - http://www.ad-kunst.de

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.07.2008
    Ort
    Renkum
    Alter
    79
    Beiträge
    128
    Moin,

    Ich habe damals eine Akkulader gebaut mit eine 80C535 Controller. Vorbild war eine Reflexlader von Elektor. Es ist wichtig dass mann den Ladestrom abschaltet während eine Messung. Damit die Akkus sich einigermasse erholen können. Und noch wichtiger, mann keine Störungen bekommt. Nur eine halbe Sekunde genügt. Bitte bau dass in deine Programm ein.

    Gruss,

    Edblum

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ein Kondensator am Eingang des ADCs kann helfen höherfrequente Störungen zu vermeiden. Kondensatoren unter etwa 10 nF sollte man aber nur nehmen, wenn man eine relativ niederohmige Quelle hat. Die kleinen Kondensatoren reichen noch nicht aus ohne merklichen (1 LSB) Spannungsabfall den Kondensator der Sample und Hold Stufe des AD wandlers zu laden. Durch den zusätzlichen Kondesator verlängert sich dann die Zeit die es braucht bis sich der richtige Wert wieder Einstellt.

    Bei größeren Kondensatoren (> 10 nF) am Eingang bricht die Spannung kaum noch ein, und die Signalquelle darf auch über 10 kOhm impedanz haben, wenn man nicht zu oft den Kanal wechselt.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.07.2008
    Ort
    Renkum
    Alter
    79
    Beiträge
    128
    Moin,

    Von Atmel wird weiterhin empfohlen eine Spule am Aref auf zu nehmen. Aber ob dass so kritisch ist beim Akkuladen? Bitte Datenblatt lesen.

    Edblum

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    11.03.2005
    Ort
    Kissing bei Augsburg
    Alter
    34
    Beiträge
    443
    Hallo,

    es geht nun!

    Habe ein paar 47nF Caps eingebaut. Anschliesend noch die Zeit zwischen PWM aus und ADC auf 500 ms eingestellt. (hane ich auch ohne das hier zu lesen gemacht, da der adc ca. 100 zu vil anzeigte.

    Nun läuft alles.

    Danke

    Michael
    Besuch mal meine HP: www.highcurrent.de

Berechtigungen

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

LiFePO4 Speicher Test