Tabelle im Rom?????

Gast #13082
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
Gast
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
Gast
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
Admin Persönliche Seite
"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
Gast
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
Gast
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
Gast
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
Gast
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
Gast
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
Gast
Hi Christian,

Punktrechnung vor Strichrechnung ;-)

ganz eindeutig (mit Klammern) geschrieben:

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

(3500/(25))-10 = 130


Tschau,

Dirk
Gast
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
Gast
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 24 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.