Forum: Mikrocontroller und Digitale Elektronik Tabelle im Rom?????


von Christian (Gast)


Lesenswert?

Hallo,

ich mcöhte mit einem analogen Distanzsensor von sharp:
http://www.sharp.co.jp/ecg/opto/products/pdf/en/osd/optical_sd/gp2y0a02_e.pdf
die Entfernung zu Gegenständen bestimmen. Das Problem ist die 
nichtlineare Ausgangsspannung der Sensoren (Datenblatt S.3).
Ich möchte das Sensorsignal mit einem AVR einlesen - der soll dann die 
Entfernung in cm wissen - aber woher????
Sollte ich besser versuchen eine Tabelle im Rom anzulegen (kann mir dazu 
jemand Tips geben) oder kann man da irgendeine Formel hernehmen????

Vielen Dank für eure Antworten!!

Christian

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Du könntest ein paar Punkte in einer Tabelle speichern und dazwischen 
linear interpolieren. Falls du das in Assembler machen willst kann ich 
dich nur bemitleiden, in C wäre es wahrscheinlich kein Problem.

von Christian (Gast)


Lesenswert?

Das hört sich gut an - vielen dank für die Antwort!!!!

Ich möchte es in C machen - kannst du mir sagen wie das gehen soll??? 
Ist es sehr aufwendig für einen MC in einer Tabelle rumzusuchen????

Vielen Dank

Christian

von Dirk Kramer (Gast)


Lesenswert?

Hallo Christian,

es gibt auch noch eine andere Alternative:

folgende Funktion wandelt den Spannungswert um, und gibt die Entfernung 
in cm laut Kennlinie (näherungsweise) zurück:

double get_distance(double spannung)
{
return (3100)/(62*spannung-10);
}

Allerdings wird hierbei nur der nichtlineare Verlauf der Kennlinie 
berücksichtigt (rechts vom Hochpunkt). Setze einfach mal ein paar Werte 
aus dem Datenblatt ein, es ist relativ genau am Verlauf.

Da dir der ADC jedoch einen 10-Bit-Wert zurückliefert, musst du die 
Funktion noch abändern.

Ich geb dir einfach mal ein Beispiel für Vref=5V und eine Auflösung von 
8 bit (also 10 Bit um zwei Bit nach rechts geschoben):

long get_distance(long spannung_in_8bit)
{
return (620)/((spannung_in_8bit >> 2)-2);
}

Ich hoffe, mir sind beim Umformen nicht zuviele Fehler passiert. :-)

Falls du noch Fragen/Kommentare zu dem Vorschlag hast, meld dich einfach 
...

Dirk

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

"Tabelle" ist wohl etwas übertrieben, "Liste" passt eher. Ich würde das 
ungefähr so machen (Pseudo-C):

int liste[9] = {0,5,10,20,35,55,80,110,145,185,230};
mess_grob = floor(mess);
mess_rest = mess - mess_grob;
entf_grob = liste[mess_grob];
entf_rest = (liste[mess_grob+1] - liste[mess_grob]) * mess_rest;
entf = entf_grob + entf_rest;

Annahmen:
Messwert: 0<=mess<10
Entfernung: 0<=entf<270

Ich hab das jetzt nur mal so ohne zu testen hingeschrieben, kann sein 
dass irgendwo ein Fehler ist.
Die Zahlenwerte sind alle frei erfunden.

Gruß
Andreas

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wenn man wie in diesem Fall eine Näherungsfunktion für die Kennlinie hat 
ist das natürlich schöner ;-)

von Christian (Gast)


Lesenswert?

Halli Hallo,

zunächst mal das obligatorische: Vielen Dank euch beiden für die 
Antworten!!!!

@Dirk
Irgendwie funktioniert deine Lsg nicht so ganz bei mir - kanns sein, 
dass du das ganze für einen anderen Sensor gemacht hast - wie kommst du 
eigentlich auf diese lustigen Formeln?????
 Hier mal ein kleines Rechnbeispiel - vielleicht weiß dann jemand warums 
bei mir nicht hinhaut:
bei 1,5 V ist die Entfernung laut Datenblatt 40cm

return (3100)/(62*spannung-10);
Vref = 5V 1bit = 20mV

--> 1,5V = 75 dez.

62*75-10 = 4640
3100/4640 = 0.66

@Andreas
hört sich ganz interessant an, aber wenn ich ehrlich bin kann ich dir 
noch nicht ganz folgen, obwohl ich dein Posting mehrmals gelesen habe 
(bin ich wirklich so hohl???) - ich würd aber wohl auch lieber die 
Methode vom Dirk nehmen, wenn's hinhaut....ansonsten bombardiere ich 
dich wieder mit Fragen....

Vielen Dank

Viele Grüße

Christian

von Dirk Kramer (Gast)


Lesenswert?

Hallo Christian,


die erste Funktion bekommt den Parameter in VOLT. Dann klappt das auch 
mit der Näherung ....

Allerdings bei der zweiten Formel ist mir wohl ein Fehler passiert. Ich 
habs nochmal nachgerechnet und bekomme jetzt:

long get_distance(long spannung_in_8bit)
{
return (15500)/((6*spannung_in_8bit)-50);
}

Bei 75 erhältst du dann z.B. 39 cm ... und diese Abweichung ist doch im 
grünen Bereich oder?


Wie man auf solche lustigen Formeln kommt?

Ein "geschultes mathematisches Auge" ;-) und ein bisschen Gleichungen 
lösen:

Die Funktion sah halt ungefähr wie y=1/x aus.

Dann hab ich mir die Gleichung y=a/(x-b) aufgestellt. Für x und y 
jeweils Werte aus dem Datenblatt eingesetzt und nach a und b umgestellt. 
Der Rest war dann nur ein bisschen anpassen der Parameter a und b um 
einen guten Verlauf zu erhalten.

Das mit dem auf 8-bit-Werte umstellen ist dann nur noch einfacher 
Dreisatz.

Ich hoffe, dass dir das mehr geholfen, als es dich verwirrt hat!

Viel Spaß noch

Dirk

von Christian (Gast)


Lesenswert?

Hey jetzt versteh' ich's glaub ich - is ja echt toll.....

Nur wenn ich dass jetzt richtig gemacht habe dann funktioniert das nur 
im Bereich von 1,5 Volt so richtig genau.

Beispiel:
bei 0,5 Volt (entspricht 130cm) kommen aus der Formel ca. 155 raus

Vielleicht fällt dir noch was kreative ein was den Fehler in den höheren 
Bereichen auch noch etwas kompensiert - ist aber so schon eine gute 
Lösung (find ich)

Vielen lieben Dank nochmal

Christian

von Dirk Kramer (Gast)


Lesenswert?

Hallo Christian,


auf ein neues .....

Distanz_in_cm=281/(spannung_in_volt * 4)-10;

Das ganze mit 8bit - Auflösung (Vref 5V):

Distanz_in_cm=3500/(spannung_mit_8bit)-10;

Falls du wieder nen paar Fehler entdeckst, meld dich einfach ;-)
Aber ich hoffe, dass ich dem Endergebnis diesmal relativ nahe bin.

Du hast leider nicht angegeben, in welchem Bereich der Kennlinie es dir 
besonders auf die Genauigkeit ankommt (Einsatzgebiet) ... sonst geht da 
bestimmt noch was ... fg

Also denn,
Tschau

Dirk

von Christian (Gast)


Lesenswert?

Hallo Dirk,
nochmals Danke für deine Mühen - aber irgendwie hatu's doch schon wieder 
nicht hin????

Beispiel:
Distanz_in_cm=3500/(spannung_mit_8bit)-10;
bei 0,5 Volt (entspricht 130cm) kommen aus der Formel ca. 233 raus
 (0,5 Volt = 25 dez.)

Welcher Bereich besonders wichtig ist kann ich nicht so genau sagen - im 
Prinzip alles - ich hab' mir sogar noch einen Sensor für den Bereich von 
4 - 30cm besorgt um den Messbereich auch noch abzudecken.

Viele Grüße

Christian

von Dirk Kramer (Gast)


Lesenswert?

Hi Christian,

Punktrechnung vor Strichrechnung ;-)

ganz eindeutig (mit Klammern) geschrieben:

Distanz_in_cm=(3500/(spannung_mit_8bit))-10;

(3500/(25))-10 = 130


Tschau,

Dirk

von Christian (Gast)


Lesenswert?

uuuuuups - da hab' ich in der Grundschule wohl nicht ganz aufgepasst - 
tschuldigung...

Vielen lieben Dank nochmals!!!!!

Christian

von Dirk Kramer (Gast)


Lesenswert?

hehe, brauchst dich doch nicht entschuldigen.

aber, egal ... wird langsam sowieso off-topic .... mit "Tabelle im Rom" 
hat das ja alles nicht mehr viel zu tun.

Also nochmal viel Erfolg beim Basteln

Dirk

von Thomas O. (Gast)


Lesenswert?

Hallo,

selbst in Assembler ist es nicht schwer.

.eseg
Tabelle1: 255, 253, 248, 238, 220, 195, 150(nicht linear)

Angenommen du erhölst vom A/D-Wandler den Wert 3
dann setzt du den ersten Zähler auf Tabelle1 und den 2ten auf 3, danach 
lpm und du hast den Wert im Register.

Geht auch 3dimensional. Der erste Zähler wird dann z.b. bei einen 
Lastwert von 3/10 auf Tabelle3 gestellt. und dort stehen wieder andere 
Daten.

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.