-         

Ergebnis 1 bis 10 von 10

Thema: getadc() - auffallendes 'muster'

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    17.02.2008
    Beiträge
    30

    getadc() - auffallendes 'muster'

    Anzeige

    hallo,

    ich bräuchte mal etwas anschubs bei der auswertung von 'getadc()'...bitte.
    ich habe den beschleunigungssensor sca610 an einem mega2560 und erhalte
    über den adc werte von 0 - 5V entsprechenden -30° bis +30° horizontaler neigung.

    die werte werden im code auf integer scaliert und jeweils eine bestimmte anzahl von werten gemittelt. den winkel errechne ich mit
    adc * 5 / 1024.

    das klappt soweit schon.
    allerdings fällt bei der ausgabe im bascom-terminal auf, dass trotz ruhendem sensor die werte unregelmässig wechseln.
    dadurch erhalte ich trotz mittelung (habs schon mit 100 schritten und mehr versucht) immer zwei verschiedene werte für den winkel.
    das ist in soweit erstmal nicht so tragisch, weil sich die abweichungen auf die dritte dezimalstelle beschränken.
    ich hätte es aber gerne noch genauer.
    da mittelung nichts bringt, vermute ich den fehlerverursacher in der spannung.

    so, jetzt wage ich mich auf noch dünneres eis, denn das ist alles absolutes neuland für mich, und weiss auch noch nicht, wie ich korrekt formulieren müsste.

    könnten das wechseln der werte mit 'schwingungen' im gleichstrom zu tun haben? seit ein paar tagen taste ich mich an die bedienung eines oszilloskops (dso) ran. beim messen der spannung habe ich sowas ähnliches wie eine sinuskurve gesehen. daher die vermutung..=_0


    Code:
    $prog , 255 , &B11011001 ,                                  'Quarz an / Teiler aus / Jtag aus
    
    $regfile = "m2560def.dat"
    $hwstack = 82                                               '80
    $framesize = 68                                             '64
    $swstack = 68                                               '44
    
    $crystal = 16000000
    
    'led (onboard)
    Config Pind.5 = Output
    
    'usb
    Config Pine.5 = Input
    USB Alias Pine.5
    Config Com4 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
    Open "com4:" For Binary As #4
    
    'lcd
    Config Lcd = 24 * 2
    Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.6 , Rs = Porta.4
    
    'adc
    
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc
    
    
    Dim W As Word
    Dim Scale As Single
    Dim Ref As Single
    Dim Tmp As Single
    Dim Grad As Single
    Dim Tmp_long_1 As Long
    Dim Tmp_long_2 As Long
    Dim Degr As Integer
    Dim I As Integer
    Dim A As Integer
    Dim Zeropos As Single
    Dim Zeropos_long As Long
    Dim Average As Long
    
    
    Scale = 100000000
    Ref = 5 * Scale
    Ref = Ref / 1024
    Zeropos = 2.5 * Scale
    Zeropos_long = Zeropos
    Average = 10
    Degr = 60
    
    Cursor Off
    Initlcd
    Wait 1
    
    
    ''''''
    'main
    ''''''
    
    For A = 1 To 3 Step 1
    
       'mittelung
    
       Tmp_long_2 = 0
       Print #4 , ""
       Print #4 , ""
       Print #4 , "- schleife auf getadc()"
       Print #4 , "- " ; Average ; " durchläufe alle 5ms"
    
       For I = 1 To Average Step 1
    
          W = Getadc(0)
          Tmp = W * Ref
          Tmp_long_1 = Tmp
    
          Tmp_long_1 = Tmp_long_1 - Zeropos_long
          Print # 4 , Tmp_long_1
          Tmp_long_2 = Tmp_long_2 + Tmp_long_1
    
          Waitms 5
    
       Next I
    
       'durchschnitt
       Tmp_long_1 = Tmp_long_2 / Average
    
       Print #4 , "---------"
       Print #4 , Tmp_long_1 ; "  <- errechneter durchschnitt"
    
       'winkel
       Tmp_long_2 = Tmp_long_1 * Degr
       Grad = Tmp_long_2 / 5000000000
    
    
       Cls
       Waitms 10
       Locate 1 , 1
       Lcd "winkel ---> " ; Fusing(grad , "#.&##")
       Print #4 , Fusing(grad , "#.&##") ; "  <- winkel"
    
    
    
    Next A
    
    
    End
    und hier die werte aus dem terminalfenster
    Code:
    - schleife auf getadc()
    - 10 durchläufe mit 5ms pause
    -3906256
    -4394544
    -4394544
    -3906256
    -3906256
    -4394544
    -3906256
    -4394544
    -3906256
    -3906256
    ---------
    -4101571  <- errechneter durchschnitt
    -0.049  <- winkel
    
    
    - schleife auf getadc()
    - 10 durchläufe mit 5ms pause
    -3906256
    -3906256
    -4394544
    -3906256
    -3906256
    -3906256
    -4394544
    -3906256
    -4394544
    -3906256
    ---------
    -4052742  <- errechneter durchschnitt
    -0.048  <- winkel
    vielen dank für jeden tip.
    ciao, edgar

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    Zu der Software kann ich nichts sagen, aber man kann bei der Stromversorgung und AREF usw einiges falsch machen, was sich dann auf die niederwertigsten Bits auswirkt.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    54
    Beiträge
    198
    Das scheint mir ein Digitalisierungs-Problem zu sein.

    Der Wert schwankt immer genau um
    4394544 - 3906256 = 488288, d.h. um 0,00568°

    Das entspricht wahrscheinlich genau einem Bit Deines Wertes nach dem AD-Wandeln.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    17.02.2008
    Beiträge
    30
    hm...

    @uff
    meinst du mit 'digitalisierungsproblem' den controller oder meinen code?

    die spannungsversorgung kommt aus einem stab. netzgerät (7.5V)
    der controller und der sca610 werden über einen spannungsregler (78s05 2 A 5V) versorgt. scheint recht stabil zu sein
    kondensatoren hab ich nur einen vorgeschriebenen am sensor.
    an aref liegt nichts an.

    wie schnell hintereinander kann ich eigentlich den adc abrufen?
    hab da so ne zahl von 100/s im kopf.
    liege ich da richtig?

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    54
    Beiträge
    198
    Also, Du hast einen 10 bit-Wert, der in der letzten Stelle schwankt (das ist normal!). Das ist das Digitalisierungsproblem!
    Wenn Du diesen Wert in Deinem Code mit 10 Mio * 5 /1024 multiplizierst, schwankt der Wert dann eben um 488281.

    Das ist Dein "Problem".

    Wie oft man den ADC auslesen kann, hängt von den Konfigurationswerten ab (ADC-clock bzw. prescaler, Kanalwechsel etc). Beim AVR braucht es 13 (ohne Kanalwechsel) bzw. 26 (mit Kanalwechsel oder Erstmessung) ADC clocks bis das Ergebnis vorliegt. Dafür gibt es einen Interrupt ADC ready.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    17.02.2008
    Beiträge
    30
    also nix zu machen?

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    54
    Beiträge
    198
    Du wirst keine bessere Auflösung als die 10 bit des ADC bekommen können!

    Es sei denn, Du nimmst einen externen ADC (z.B. von Analog Devices oder Maxim), der 12 bit Uflösung hat.

    Du kannst auch einfach die 10 bit ADC -Werte 16 mal aufsummieren, dann erhälst Du theoretisch 14 bit.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    17.02.2008
    Beiträge
    30
    ok...danke für die info.

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    17.11.2005
    Beiträge
    272
    kann uffi nur zustimmen.

    du nimmst eigentlich den Fehler und multiplizierst ihn. Mache doch "einfach" erst mit den AD werten die Mittelwertbildung und den "gesäuberten" Wert multiplizierst du. Damit dürfte dein fehler auch kleiner werden.

    Sonst kannst du nur auf nen externen ADC umsteigen.

    cu Arno
    Unser Wissen ist ein Tropfen, unser Unwissen ist wie ein Ozean.
    Sir Isaac Newton

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    17.02.2008
    Beiträge
    30
    du meinst den direkt ankommenden wert? 0...1023

    die scalierung habe ich gemacht, weil laut meinem informationsstand
    fliesskommarechnungen nicht gut gemeistert werden vom controller.

    ginge das auch mit den direkten werten, wäre es ja integer zu bewältigen.

Berechtigungen

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