| Next revision | Previous revision |
| de:examples:sensor:ir_distance [2010/11/29 18:13] – angelegt Wember | de:examples:sensor:ir_distance [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
|---|
| ====== Infrarot-Entfernungsmesser ====== | ====== Infrarot-Entfernungsmesser ====== |
| |
| //Necessary knowledge: [HW] [[en:hardware:homelab:sensor]], [HW] [[en:hardware:homelab:lcd]], [AVR] [[en:avr:adc]], [LIB] [[en:software:homelab:library:adc]], [LIB] [[en:software:homelab:library:module:lcd_alphanumeric]], [LIB] [[en:software:homelab:library:module:sensor]]// | //Notwendiges Wissen: [HW] [[en:hardware:homelab:sensor]], [HW] [[en:hardware:homelab:lcd]], [AVR] [[en:avr:adc]], [LIB] [[en:software:homelab:library:adc]], [LIB] [[en:software:homelab:library:module:lcd_alphanumeric]], [LIB] [[en:software:homelab:library:module:sensor]]// |
| |
| ===== Theorie ===== | ===== Theorie ===== |
| [{{ :examples:sensor:ir_distance:sensor_ir_distance_gp2y0a21yk_picture.jpg?240|Sharp GP2Y0A21YK}}] | [{{ :examples:sensor:ir_distance:sensor_ir_distance_gp2y0a21yk_picture.jpg?240|Sharp GP2Y0A21YK}}] |
| |
| 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. | Um die Distanz zu einem Objekt zu messen, gibt es optische Sensoren, welche die Triangulation als Messmethode nutzen. Die am häufigsten verwendeten Infrarot-Entfernungsmesser werden von der Firma "Sharp" produziert und verfügen über einen analogen Spannungs-Output. Diese Sensoren besitzen eine Infrarot-LED mit einer Linse, welchen einen schmalen Lichtstrahl aussendet. Dieser wird von dem Objekt, zu welchem die Distanz gemessen werden soll, reflektiert und dann durch die zweite Linse zu einem optischen Positionssensor (OPS) gelenkt. Die Leitfähigkeit dieses OPS ist abhängig davon, an welcher Stelle der Lichtstrahl einfällt. Sie wird in Spannung umgewandelt, die Spannung wird mittels eines Analog-Digital-Konverters digitalisiert und daraufhin kann die Entfernung berechnet werden. Die Zeichnung auf der rechten Seite zeigt die Wege von Strahlen, die aus unterschiedlichen Entfernungen reflektiert werden. |
| 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. | |
| |
| [{{ :examples:sensor:ir_distance:sensor_ir_distance_principle.png?240|The route of the light beam from an IR distance sensor}}] | [{{ :examples:sensor:ir_distance:sensor_ir_distance_principle.png?240|Wege der Lichtstrahlen eines Infrarot-Entfernungsmessers}}] |
| |
| [{{ :examples:sensor:ir_distance:sensor_ir_distance_graph.png?240|Diagram of voltage-distance of IR distance sensor}}] | [{{ :examples:sensor:ir_distance:sensor_ir_distance_graph.png?240|Das Verhältnis von Spannung und Entfernung eines Infrarot-Entfernungsmessers}}] |
| |
| 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. | Der Output der Infrarot-Entfernungsmesser von "Sharp" ist anti-proportional. Das meint, mit größer werdender Entfernung verringert sich der Output (die Abnahme des Outputs, also der Spannung, wird jedoch nach und nach schwächer). Der Graph mit dem exakten Verhältnis zwischen Entfernung und Spannung ist gewöhnlich im Datenblatt des Sensors abgebildet. |
| 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. | Jeder Sensor-Typ hat seinen spezifischen Messbereich, innerhalb welchem die gemessenen Ergebnisse verlässlich sind. Die maximale Messdistanz wird von zwei Aspekten beschränkt: Zum Einen von der Abnahme der Menge des reflektierten Lichts, zum Anderen vom Unvermögen des OPS, kleine Positonsänderungen des reflektierten Strahls zu registrieren. Misst man die Entfernung zu Objekten, welche zu weit entfernt sind, entspricht der Output nahezu dem, bei der Messung zur maximalen Distanz. |
| 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. | Die minimale Entfernung wird durch die Besonderheit der Sharp Sensoren eingeschränkt. So fällt der Output steil ab, sobald die Entfernung einen bestimmten Punkt unterschreitet (je nach Baureihe liegt dieser bei 4 bis 20 cm) Das hat zur Folge, dass zu einem Outputwert zwei korrespondierende Entfernungswerte existieren. |
| Dieses Problem kann man verhindern, wenn man darauf achtet, dass das Objekt nicht zu nahe am Sensor ist. | Dieses Problem kann vermieden werden, indem beachtet wird, dass die Distanz zwischen Objekt und Sensor nicht zu gering ist. |
| | |
| ===== Übung ===== | ===== Übung ===== |
| |
| Das HomeLab Sensor-Set hat den IR-Entfernungsmesser SHARP GP2Y0A21YK. | Das HomeLab Sensor-Kit enthält den Infrarot-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. | Der Messbereich dieses Sensors liegt zwischen 10 cm und 80 cm. Seine Output-Spannung 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 den vorangehenden Übungen zu Sensoren, ist es einfach ein Programm zu schreiben, welches die Output-Spannung des Entfernungsmessers misst. Zusätzlich dazu behandelt diese Aufgabe die Umwandlung der Spannung in eine Entfernung. |
| |
| 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. | Das Datenblatt des GP2Y0A21YK beinhaltet einen Graphen welcher die Relation von Output-Spannung und gemessener Entfernung darstellt. Dieser Graph verläuft nicht linear. Der Graph der inversen Werte ist jedoch annähernd linear, wodurch relativ einfach die Formel zur Umwandlung von Spannung in Entfernung gefunden werden kann. Hierzu werden Punkte des Graphens in ein Tabellenkalkulationsprogramm eingefügt und so ein neuer Graph generiert. Die meisten Programme berechnen automatisch eine Trendlinie. |
| 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. | Nachfolgend ist der Graph des GP2Y0A21YK mit der Relation der korrigierten inversen Werte der Outputspannung zu den korrigierten inversen Werten der gemessenen Distanz, inklusive einer Trendlinie abgebildet. Zur Vereinfachung wurde die Output-Spannung schon in 10-Bit +5 V Werte des ADC mit Vergleichspannung konvertiert. |
| |
| [{{ :examples:sensor:ir_distance:sensor_ir_distance_gp2y0a21yk_graph_calculation.png?580 |The graph of linearizing ADC value and distance}}] | [{{ :examples:sensor:ir_distance:sensor_ir_distance_gp2y0a21yk_graph_calculation.png?580 |Graph zur linearen Darstellung von ADC Wert und Entfernung}}] |
| |
| 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. | Wie der Graph zeigt, überschneiden sich die blaue Trendlinie und die Punkte des Graphen fast genau. Dieses wird durch die Nutzung einer Korrektur-Konstante erreicht. Diese Konstante wird mit der "trail-and-error"-Methode gefunden - es werden dabei viele Variablen getestet, bis diejenige gefunden ist, die den Graph mit der Trendlinie überlappen lässt. |
| 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: | Im abgebildeten Graph ist die Korrektur-Konstantet +2; das bedeutet, zu allen realen Entfernungen muss +2 hinzuaddiert werden. Daruch verläuft der Graph nahezu gleich der Trendline und es kann für die Relation zwischen Entfernung und Spannung verallgemeinert folgende Formel angenommen werden: |
| |
| 1 / (d + k) = a * ADC + b | 1 / (d + k) = a * ADC + b |
| |
| * d - Entfernung in cm. | * d - Entfernung in cm. |
| * k - Korrektur-Konstante (gefunden mithilfe tial-and-error Methode) | * k - Korrektur-Konstante (gefunden mittels trial-and-error Methode) |
| * ADC - digitalisierter Wert der Spannung. | * ADC - digitalisierter Wert der Spannung. |
| * a - lineares Element (Wert wird durch die Trendlinien-Gleichung bestimmt) | * a - lineares Element (Wert wird durch die Trendlinien-Gleichung bestimmt) |
| * b - Freies Element (Wert wird durch die Trendlinien-Gleichung bestimmt) | * b - freies Element (Wert wird durch die Trendlinien-Gleichung bestimmt) |
| |
| Die Entfernung d kann durch folgende Formel dargestellt werden: | Die Entfernung d kann durch folgende Formel dargestellt werden: |
| d = (1 / (a * ADC + B)) - k | 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: | Nun ist es generell möglich die Entfernung mit der Formel zu berechnen. Da jedoch Brüche dividiert werden, sind zudem Gleitkomma-Berechnungen nötig. Weiterhin muss die Formel vereinfacht und auf größere Quotienten ausgeweitet werden, da Microcontroller mit Ganzzahlen arbeiten. Durch die Division des Quotienten mit einem linearen Element erhält man folgende Formel: |
| |
| d = (1 / a) / (ADC + B / a) - k | 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: | Durch Aufnahme der Korrekturkonstante sowie des linearen und freien Elements der Trendlinien-Gleichung, ergibt sich folgende Formel zur Berechnung der Entfernung: |
| |
| d = 5461 / (ADC - 17) - 2 | 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. | Diese Formel kann mit 16-Bit Zahlen berechnet werden und ist daher vollständig für den AVR geeignet. Vor der Berechnung muss sicher gestellt sein, dass der Wert des ADC größer als 17 ist, ansonsten kann der Fall eintreten, dass durch 0 geteilt werden muss oder eine negative Distanz ausgegeben wird. |
| |
| 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. | Nachfolgend ist die Funktion dargestellt, die dazu dient, ADC-Werte in Centimeter zu konvertieren. Sie ist in der HomeLab Library enthalten. Lineare und freie Elemente sowie die Korrektur-Konstante, sind nicht fest in die Funktion integriert, sondern werden mittels der Objektparameter des Infrarot-Entfernungsmessers eingespeist. Dadurch, dass diese Parameter als separate Konstanten verwendet werden, ist es sehr einfach, neue Infrarot-Entfernungsmesser in das Programm zu integrieren. |
| |
| |
| <code c> | <code c> |
| // | // |
| // The structure of the parameters of the IR distance sensors | // Die Struktur der Parameter des Infrarot-Entfernungsmessers |
| // | // |
| typedef const struct | typedef const struct |
| |
| // | // |
| // The object of the parameters of GP2Y0A21YK sensor | // Die Parametereigenschaften des GP2Y0A21YK Sensors |
| // | // |
| const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; | const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; |
| |
| // | // |
| // Converting the values of the IR distance sensor to centimeters | // Konvertieren der Werte des Infrarot-Entfernungsmessers in Centimeter |
| // Returns -1, if the conversion did not succeed | // Gibt -1 aus, wenn die Konvertierung nicht erfolgreich war |
| // | // |
| signed short ir_distance_calculate_cm(ir_distance_sensor sensor, | signed short ir_distance_calculate_cm(ir_distance_sensor sensor, |
| </code> | </code> |
| |
| 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. | Zur Durchführung der Konvertierung muss die Funktion //ir_distance_calculate_cm// genutzt werden. Der erste Funktionsparameter gibt die Eigenschaften der Parameter des Infrarot-Entfernungsmessers an, der zweite den ADC-Wert. Die Funktion gibt dann die berechnete Entfernung in Centimetern aus. Schlägt die Konvertierung fehl (unzulässige ADC-Werte), wird der Wert -1 ausgegeben. Das folgende Programm veranschaulicht die Verwendung des Infrarot-Entfernungsmessers und der Konvertierungsfunktion. Es wird das alphanumerische LCD genutzt, auf welchem die gemessenen Werte dargestellt werden. Falls die Distanz unzulässig ist, wird ein "?" angezeigt. |
| |
| <code c> | <code c> |
| // | // |
| // The example program of the IR distance sensor of the HomeLab | // Beispielprogramm des Infrarot-Entfernungsmessers des HomeLab |
| // Measured results in centimeters is displayed on the LCD | // Die in Centimetern gemessenen Ergebnisse werden auf dem LCD abgebildet |
| // | // |
| #include <stdio.h> | #include <stdio.h> |
| |
| // | // |
| // Main program | // Hauptprogramm |
| // | // |
| int main(void) | int main(void) |
| char text[16]; | char text[16]; |
| | |
| // Initialization of LCD | // External sensor selection |
| | pin ex_sensors = PIN(G, 0); |
| | pin_setup_output(ex_sensors); |
| | pin_set(ex_sensors); |
| | |
| | // Initialisierung des LCD |
| lcd_alpha_init(LCD_ALPHA_DISP_ON); | lcd_alpha_init(LCD_ALPHA_DISP_ON); |
| | |
| // Clearing the LCD | // Löschen des LCD |
| lcd_alpha_clear(); | lcd_alpha_clear(); |
| | |
| // Name of the program | // Name des Programms |
| lcd_alpha_write_string("Distance sensor"); | lcd_alpha_write_string("Distance sensor"); |
| | |
| // Setup of the ADC | // Installation des ADC |
| adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); | adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); |
| | |
| // Endless loop | // Endlosschleife |
| while (true) | while (true) |
| { | { |
| // Reading the 4 times rounded value of the output voltage of the sensor | // Auslesen des viermal gerundeten Wertes der Outputspannung des Sensors |
| value = adc_get_average_value(0, 4); | value = adc_get_average_value(0, 4); |
| |
| // Conversing ADC value to distance | // Konvertieren des ADC-Wertes in Entfernung |
| distance = ir_distance_calculate_cm(GP2Y0A21YK, value); | distance = ir_distance_calculate_cm(GP2Y0A21YK, value); |
| |
| // Was the calculation successful? | // War die Berechnung erfolgreich? |
| if (distance >= 0) | if (distance >= 0) |
| { | { |
| // Conversing distance to text | // Konvertieren von Entfernung in Text |
| sprintf(text, "%d cm ", distance); | sprintf(text, "%d cm ", distance); |
| } | } |
| else | else |
| { | { |
| // Creating the text for unknown distance | // Text für eine unbekannte Entfernung erzeugen |
| sprintf(text, "? cm "); | sprintf(text, "? cm "); |
| } | } |
| |
| // Displaying the text in the beginning of the second row on the LCD | // Anzeige des Textes am Anfang der zweiten Zeile auf dem LCD |
| lcd_alpha_goto_xy(0, 1); | lcd_alpha_goto_xy(0, 1); |
| lcd_alpha_write_string(text); | lcd_alpha_write_string(text); |
| </code> | </code> |
| |
| ===== Extra materials ===== | ===== Zusätzliches Material ===== |
| |
| * {{:examples:sensor:ir_distance:ir_distance.ods|Graph of the Sharp GP2Y0A21YK sensor}} | * {{:examples:sensor:ir_distance:ir_distance.ods|Graph des Sharp GP2Y0A21YK Sensors}} |
| * [[http://www.acroname.com/robotics/info/articles/irlinear/irlinear.html|Linearizing Sharp Ranger Data]] | * [[http://www.acroname.com/robotics/info/articles/irlinear/irlinear.html|Linearisierung der Sharp Entfernungsdaten]] |
| |