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
Wenn man wie in diesem Fall eine Näherungsfunktion für die Kennlinie hat ist das natürlich schöner ;-)
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
Hi Christian, Punktrechnung vor Strichrechnung ;-) ganz eindeutig (mit Klammern) geschrieben: Distanz_in_cm=(3500/(spannung_mit_8bit))-10; (3500/(25))-10 = 130 Tschau, Dirk
uuuuuups - da hab' ich in der Grundschule wohl nicht ganz aufgepasst - tschuldigung... Vielen lieben Dank nochmals!!!!! 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.