PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : getadc() - auffallendes 'muster'



what?
17.03.2008, 10:01
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





$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



- 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

Hubert.G
17.03.2008, 10:52
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.

uffi
17.03.2008, 13:56
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.

what?
17.03.2008, 14:50
hm...

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

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?

uffi
17.03.2008, 15:51
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.

what?
17.03.2008, 15:55
also nix zu machen?

uffi
17.03.2008, 15:57
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.

what?
17.03.2008, 15:59
ok...danke für die info.

Olle_Filzlaus
18.03.2008, 13:33
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

what?
18.03.2008, 13:43
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.