This is an old revision of the document!
Necessary knowledge: [HW] Sensors Module, [HW] lcd, [AVR] Analog-to-digital Converter, [LIB] Analog to Digital Converter, [LIB] Alphanumeric LCD, [LIB] Sensors
Um die Distanz zu einem Objekt zu messen,nutzen optische Sensoren Triangulation als Messmethode. Die Firma “Sharp” produziert die verbreitetsten Infrarot (IR) Entfernungsmesser mit einem analogen Spannungs-Output. Die “Sharp” Sensoren haben eine IR-LED mit einer Linse, welchen einen engen Lichtstrahl aussenden. Nach der Reflektion an einem Objekt, wird der Strahl durch einer zweiten Linse, auf einen positions-sensiblen Photodetektor (PSD) gelekt. Die Leitfähigkeit des PSD hängt von der Position ab, auf der der Strahl fällt. Die Leitfähigkeit wird in Spannung konvertiert, und wenn die Spannung digitalisiert wird, durch einen ADC, kann die Entfernung berechnet werden. Die Strecke der Strahlen die aus verschiedenen Entfernungen reflektiert werden, werden auf der Zeichnung dargestellt.
Der Output der Entfernungssensoren von “Sharp” ist anti-proportional, das heißt, dass wenn die Entfernung steigt wird der Output weniger (und der Abfall der Spannung wird linear weniger). Der exakte Graph vom Verhältnis zwischen Entfernung und Output ist normalerweise auf dem Datenblatt des Sensors zu finden. Jeder Sensor hat seinen spezifischen Messbereich, in denen die gemessenen Ergebnisse glaubhaft sind, und dieser Bereich hängt vom Sensor ab. Die maximale Messdistanz wird von zwei Aspekten gegeben: Die Menge des reflektierten Lichts wird weniger und der PSD kann die Reflektion nicht mehr messen und das der PSD die kleinen Änderungen von reflektierenden Strahl nicht registriert. Wenn man ein Objekt misst, welchen zu weit entfernt ist, bleibt der Output etwa der gleiche , als würde das Objekt bei der maximalen Distanz sein. Die minimale Entfernung wird durch die Eigenschaften der Sharp Sensoren eingeschränkt, d.h. der Output fällt steil ab, wenn die Entfernung einen bestimmten Punkt unterschreitet. (je nach Modell 4-20cm) Das heisst, das zu einem Output Wert, zwei Entfernungswerte gibt. Dieses Problem kann man verhindern, wenn man darauf achtet, dass das Objekt nicht zu nahe am Sensor ist.
Das HomeLab Sensor-Set hat den IR-Entfernungsmesser SHARP GP2Y0A21YK. Der Messbereich des Sensors ist 10 cm – 80 cm. Die Output-Spannung des Sensors hängt von der Entfernung ab und erreicht bis zu 3 V. Der Entfernungssensor ist am Sensormodul angeschlossen. Die Output-Spannung wird über Kanal 0 zum ADC des AVR gesendet. Aufbauend auf die vorherigen Übungen zu den Sensoren, ist es einfach ein Programm zu schreiben, welches die Output-Spannung des Entfernungsmessers misst, aber zusätzlich wird diese Aufgabe die Spannung in eine Entfernung konvertieren.
Auf dem Datenblatt des GP2Y0A21YK ist ein Graph von der Relation der Output-Spannung zur gemessenen Entfernung. Der Graph ist nicht linear, aber der Graph der inversen Werte ist fast linear, und damit kann man sehr einfach eine Formel finden um die Spannung in eine Entfernung zu konvertieren. Um die Formel zu finden müssen die Punkte des Graphs in eine Tabellenkalkulation eingefügt werden, und einen neuen Graphen generieren. In den meisten Programmen ist es möglich automatisch eine Trendline zu berechnen. Folgend ist der Graph des GP2Y0A21YK mit den korrigierten inversen Werten der Outputspannung, zu den korrigierten inversen Werten der gemessenen Distanz, mit einer linearen Trendlinie. Um es zu vereinfachen wurde die Output-Spannung schon zu 10 Bit +5 V Werten des ADC mit Vergleichspannung konvertiert.
Wie man am Graph sehen kann, überlappt die blaue Trendlinie recht genau mit den Punkten des Graphs. Diese Überlappung wird durch die Hilfe einer Korrektur-Konstante erreicht. Diese Konstante wird mit der “trail-and-error”-Methode gefunden - viele Variablen wurden getestet, bis eine gefunden wurde, die den Graph mit der Trendlinie überlappen lies. Die Korrektur-Konstante des gezeigten Graph ist +2; das heisst, das zu allen realen Entfernungen +2 hinzuaddiert werden muss. Daruch ist der Graph zur Trendline ähnlich und man kann verallgemeinern und sagen, dass die Relation zwischen Entfernung und Spannung folgende ist:
1 / (d + k) = a * ADC + b
wobei
Die Entfernung d kann durch folgende Formel dargestellt werden:
d = (1 / (a * ADC + B)) - k
Nun ist es möglich die Entfernung mit der Formel zu berechnen, aber dies benötigt Gleitkomma-Berechnungen, da Divisionen von Brüchen vorkommen. Da aber Microcontroller mit Integer arbeiten, muss die Formel vereinfacht werden. Durch die Division des Quotienten mit einem linearen Element wird die Formel wir folgt:
d = (1 / a) / (ADC + B / a) - k
Durch das Einführern der Korrekturkonstante in die Formel und die des linearen und freies Elements der Trendlinien Gleichung, wird die Formel für die Entfernungsberechnung wie folgt:
d = 5461 / (ADC - 17) - 2
Diese Formel kann man mit 16-Bit Integer berechnen und ist daher für den AVR. Vor der Berechnung muss man sichergehen, dass der Wert des ADC über 17 ist, sonst würde man durch 0 teilen (und dabei ggf. das Universum vernichten) oder es kommt eine negative Distanz raus.
Es folgt die Funktion um die Werte des ADC in cm zu konvertieren, sie steht in der Library von HomeLab. Lineare- und freie Elemente und die Korrektur-Konstante, sind nicht fest in die Funktion geschrieben, sondern werden mit Objektparametern des IR-Entfernungsmessers eingegeben. Da diese Parameter separate konstanten sind, ist es sehr einfach neue IR-Entfernungsmesser in das Programm zu integrieren.
// // The structure of the parameters of the IR distance sensors // typedef const struct { const signed short a; const signed short b; const signed short k; } ir_distance_sensor; // // The object of the parameters of GP2Y0A21YK sensor // const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; // // Converting the values of the IR distance sensor to centimeters // Returns -1, if the conversion did not succeed // signed short ir_distance_calculate_cm(ir_distance_sensor sensor, unsigned short adc_value) { if (adc_value + sensor.b <= 0) { return -1; } return sensor.a / (adc_value + sensor.b) - sensor.k; }
Um eine Konversion zu machen muss die Funktion ir_distance_calculate_cm genutzt werden. Der erste Paramter dieser Funktion ist das Objekt der Parameter der IR-Entfernungsmesser, das zweite der ADC-Wert. Die Funktion gibt dann die berechnete Entfernung in cm aus. Falls die Operation falsch ist (unzulässige ADC Werte) wird der Wert -1 ausgegeben. das folgende Programm veranschaulicht die Benutzung des IR-Entfernungsmessers und der Konversions-Funktion. Es wird das Alphanumerische LCD genutzt, auf dem die gemessenen Werte dargestellt werden. Falls die Distanz unnatürlich ist wird ein “?” dargestellt.
// // The example program of the IR distance sensor of the HomeLab // Measured results in centimeters is displayed on the LCD // #include <stdio.h> #include <homelab/adc.h> #include <homelab/delay.h> #include <homelab/module/sensors.h> #include <homelab/module/lcd_alpha.h> // // Main program // int main(void) { unsigned short value; signed short distance; char text[16]; // Initialization of LCD lcd_alpha_init(LCD_ALPHA_DISP_ON); // Clearing the LCD lcd_alpha_clear(); // Name of the program lcd_alpha_write_string("Distance sensor"); // Setup of the ADC adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Endless loop while (true) { // Reading the 4 times rounded value of the output voltage of the sensor value = adc_get_average_value(0, 4); // Conversing ADC value to distance distance = ir_distance_calculate_cm(GP2Y0A21YK, value); // Was the calculation successful? if (distance >= 0) { // Conversing distance to text sprintf(text, "%d cm ", distance); } else { // Creating the text for unknown distance sprintf(text, "? cm "); } // Displaying the text in the beginning of the second row on the LCD lcd_alpha_goto_xy(0, 1); lcd_alpha_write_string(text); // Break sw_delay_ms(500); } }