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
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.
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
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
"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
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
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
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
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
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
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
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.
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.