Forum: Mikrocontroller und Digitale Elektronik 10bit auf 6bit Skalieren?


von Maruu ;. (maruu)


Lesenswert?

Hallo,

ich frag von meinem A/D Wandler regelmäßig Werte ab. Der A/D Wandler
liefert 10bit Werte im Spannungsbereich von 0-5V.
1.) Ich benötige aber nur den Spannungsbereich 0.4-2.4V
2.) und zweitens muss ich diesen Bereich dann auf 6bit runterskalieren,
da ich diese 6 bit über einen Bus übertragen muss.

Wie bekomm ich das also hin das ich meinen 10bit Wert der aber Werte
von 0-5V abdeckt auf einen 6bit Wert bekomme der aber nur den Bereich
von 0.4-2.4V abdecken soll.

Gruß

Hannes

von Marko (Gast)


Lesenswert?

also die 2,4V lassen sich über die Referenzspannung des ADC
realisieren, also diese einfach über Spannungsteiler
auf 2,4V legen oder z.B. bei AVRs die interne Referenzspannung,
sie dann 2,5V ist benutzen.
Die 10 auf 6 Bit kann man einfach shiften ... also das
Datenwort, das man als Ergebniss bekommt (2 x 8Bit)
4 mal nach rechts shiften und dann das Lowbyte nehmen.

Das wars schon

von vorbeigeschlendert (Gast)


Lesenswert?

hmm... erst mal würde ich dem AD-Wandler eine Referenzspannung von 2.5V
geben, dann hast das schon mal erschlagen, die Werte unterhalb von 0.4V
und oberhalb von 2.4V wirfst einfach weg, die anderen kannst dann ja
umrechnen um eine halbwegs akzeptable Genauigkeit zu erhalten...

so oder so ähnlich?

von Uwe Nagel (Gast)


Lesenswert?

wie wär's mit:

x=((ADC-82)*63)/410;

Diese Funktion bildet den Spannungsbereich von etwa 0,4..2,4V auf 0..63
ab.
Als Referenz die 5V Versorgung.

von sch_michael (Gast)


Lesenswert?

mit der Formel von Uwe hört sich dass doch ziemlich gut an,
hast dann eine Auflösung von 31,7mV/digit.

von Maruu ;. (maruu)


Lesenswert?

Hi,

danke für die Antworten, ok die Formel sieht super aus,
da muss ich dann keine extra Referenzspannung hinbasteln.
Nur ist die Frage wie ich auf nem PIC dividieren und multiplizieren
kann? Weiss das jemand?

Gruß

Hannes

von Manos (Gast)


Lesenswert?

In "C" oder Assembler?

von Maruu ;. (maruu)


Lesenswert?

Assembler leider da ich den I2C Bus als Slave brauch und dazu noch nix
in C gefunden hab.

Gruß

Hannes

von Uwe Nagel (Gast)


Lesenswert?

Eigentlich dachte ich an WinAVR ;)

Wäre jetzt etwas ungenauer:
x=((ADC-82)*40)/256

82 subtrahieren ist einfach, noch einfacher ist wohl -82 addieren.
mal 40 lässt sich leicht durch schieben und addieren lösen.
durch 256 ist einfach das untere Byte vom Ergebnis vergessen.
Oder man nimmt die Mathematikfunktionen aus den Application-Notes von
Microchip...

von Marko (Gast)


Lesenswert?

Man kann auch mit Gewalt den µC ausbremsen, z.B.
mit Formelsammlung im Code

von Maruu ;. (maruu)


Lesenswert?

Ahh ok hört sich gut an, da ich noch bissle anfänger bin wäre es super
wenn Du mir kurz sagen könntest wie ich die *40 hinbekomm.
Das /256 is kein Thema und addieren und subtrahieren auch ned.
Danke nochmals.

Gruß

Hannes

von Johannes Raschke (Gast)


Lesenswert?

40 = (32 + 8) = (2^5 + 2^3)

von D. W. (dave) Benutzerseite


Lesenswert?

5x nach links shiften, dann 3x nochmal 3x geshifted addieren:

int temp1;
int result;

result = ADC-82;
result = result << 3;  // geht da result <<= 3; ?
temp1 = result;
temp1 = temp1 << 2

result += temp1;

Wenn ich mich nicht irre.

von MichaelP. (Gast)


Lesenswert?

Schiebt doch gleich nach Rechts, dann müßt ihr nur 8 bit Schieben.

Mfg Michael

von Maruu ;. (maruu)


Lesenswert?

Ahh Klasse, hab jetzt auch mal nachgerechnet und dabei festgestellt,
wenn ich den Maximalen Eingangswert von 1023 nehm
und das nachrechne:

x=((1023-82)*40)/256=147

dann kommt 147 raus, das liegt aber nicht mehr in meinem 6bit bereich.
Ist da was falsch?

gruß

Hannes

von Hagen (Gast)


Lesenswert?

0-5V = 1024
0.4V ist ein Offset in diese 1024

0.4V / 5 * 1024 = 81.92 == 82 als Offset
2.4V - 0.4V = 2.0V als Wertebereich des Ausschnitts
2.0V / 5.0V = 0.4 als Skalierungsfaktor des Ausschnitts
(1024 - 82) * 0.4 = 376.8 == 377 als oberster Wertebereich

Das ist der Wertebereich der nun noch auf 6 Bit skaliert werden muß.

6Bit = 2^6 = 64 als Wertebereich bei 6 Bits
64 / 377 = 0.16976 als Skalierungsfaktor nach 6 Bits
0.16976 * 0.4 = 0.0679 Skalierungsfaktor des Ausschnitts und auf 6
Bits
1/0.679 = 14.72 == 15 als Reziprok

(1024 - 82) / 15 = 62.8 == 63.

heist also

x = (Meßwert - 82) / 15

Gruß Hagen

von D. W. (dave) Benutzerseite


Lesenswert?

0,4V bei 5V sind bei 10bit 82.
2,4V ... 491

D.h. 491 - 82 = 409
409 / 63 = 6,5

==> result = ((ADC-82)/6,5) && 63)

Man, das ist kompliziert... ist das richtig?

von D. W. (dave) Benutzerseite


Lesenswert?

Hagen, hast du nicht den Wertebereich von 0,4 - 5V auf 6bit skaliert?

von Maruu ;. (maruu)


Lesenswert?

Wo wir aber wieder beim Problem sind, /15 is so einfach nicht zu
realisieren.
Das /6,5 schon gleich garnicht.
Mhhm is es mit Referenzspannung vielleicht doch einfacher?

Gruß

Hannes

von Hagen (Gast)


Lesenswert?

@David:

ähm, da hast du Recht ;)

Die 1023 von Hannes in

x=((1023-82)*40)/256=147

haben mich in die Irre gleitet, denn die sind ja falsch.

2.4V vor dem Offset und der Skalierung entsprechen einem Meßwert von
491

(491 - 82) * 40 / 256 = 64.
(491 - 82) / 6.4 = 64.

Ich würde also Uwe Nagels Vorschlag nehmen, der ist richtig.

(491 - 82) * 5 / 32 ginge auch. *5 wäre x << 2 + x. Allerdings dürfte
ein Rightshift mit 256 == 2^8 noch einfacher und schneller sein.

Gruß Hagen

von Uwe Nagel (Gast)


Lesenswert?

Aber hier kommt jetzt die Ungenauigkeit, denn der Wertebereich von 6 Bit
geht nur bis 63 und nicht bis 64.
Rechnen wir rückwärts:
U= (x*256/40+82)*5Volt/1023  (oder /1024 ???)
x=0  -> U=0,40078V
x=63 -> U=2,37V
Ich denke aber, dass das hier nicht weiter schadet, oder?

von Maruu ;. (maruu)


Lesenswert?

Ahh war ich dann der Bösewicht?
Sorry das tut mir leid,
Das bedeutet ich muss erst die 5V-2,4V=2,6V abziehen,
also (1024*2,6)/5=532
bevor ich weiterrechne? Also bzw. alles was über 491 ist wird einfach
auf 491 gesetzt?

Stimmts dann?

Gruß

Hannes

PS: Sorry nochmal wenn cih jemanden verwirrt hab

von Maruu ;. (maruu)


Lesenswert?

Sorry den vorherigen Beitrag hab ich zu spät gesehen.
Diese Ungenauigkeit ist nicht so extrem schlimm. Bei dem Analogsignal
handelt es sich um einen Abstandmesse der zwischen 80cm und 10cm
misst.
Das ist jetzt zwar ca 1,5 cm Fehlmessung ist aber nicht so extrem
bedeutend , da die Genauigkeit des Sensors generell nicht so überragend
ist.
Und durch das Skalieren auf 6bit geht ohnehin auch ein bisschen was
flöten.

Gruß

Hannes

von Hagen (Gast)


Lesenswert?

Ja, du berücksichtigst nur Meßwerte zwischen 0 bis 491. Alles was da
drüber ist ist größer 2.4 Volt und interessiert dich ja nicht mehr.
Das geht dann aber zu Lasten der Auflösung, aber auch das ist unwichtig
da du ja eh auf 6 Bit Genauigkeit reduzieren möchtest.

Wäre das nicht so dann ist der Vorschlag mit einer 2.5V VRef im ADC zu
arbeiten weit besser.

die 491 sind 1024 / 5V * 2.4V = 491. Sie kommen also von deinem
Zielbereich von 0.4V bis 2.4V. Du musst da nichts weiter mit 2.6V
subtrahieren oder so.

Würdest du VRef im ADC mit 2.5V betreiben so misst du ja 0 bis 2.5V in
0 bis 1023. Ein downscaling auf 6 Bit wäre dann möglich mit einer
Division durch 10-6 = 4 == 2^4 == 16. Deine 64 möglichen Meßwerte gehen
dann von 0 bis 2.5V. Die Formel reduziert sich auf

x = Meßwert / 16.

Die höhere Auflösung erreichst du aber mit 1. Methode.

Gruß Hagen

von Maruu ;. (maruu)


Lesenswert?

OK ich glaub ich habs jetzt geschnallt.
Dannw erd ich mich mal ans Programmieren machen.
Nochmals danke an Alle hat mir sehr geholfen.

Gruß

Hannes

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.