This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| de:examples:sensor:ir_distance [2012/03/13 17:00] – wittkoepper | de:examples:sensor:ir_distance [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Infrarot-Entfernungsmesser ====== | ||
| + | |||
| + | // | ||
| + | |||
| + | ===== Theorie ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | 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 " | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Der Output der Infrarot-Entfernungsmesser von " | ||
| + | Jeder Sensor-Typ hat seinen spezifischen Messbereich, | ||
| + | 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 vermieden werden, indem beachtet wird, dass die Distanz zwischen Objekt und Sensor nicht zu gering ist. | ||
| + | |||
| + | ===== Übung | ||
| + | |||
| + | Das HomeLab Sensor-Kit enthält den Infrarot-Entfernungsmesser SHARP GP2Y0A21YK. | ||
| + | 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. | ||
| + | |||
| + | 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. | ||
| + | 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. | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | 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 " | ||
| + | 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 | ||
| + | |||
| + | wobei | ||
| + | |||
| + | * d - Entfernung in cm. | ||
| + | * k - Korrektur-Konstante (gefunden mittels trial-and-error Methode) | ||
| + | * ADC - digitalisierter Wert der Spannung. | ||
| + | * a - lineares 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: | ||
| + | |||
| + | d = (1 / (a * ADC + B)) - k | ||
| + | |||
| + | 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 | ||
| + | |||
| + | Durch Aufnahme der Korrekturkonstante sowie des linearen und freien Elements der Trendlinien-Gleichung, | ||
| + | |||
| + | d = 5461 / (ADC - 17) - 2 | ||
| + | |||
| + | 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. | ||
| + | |||
| + | Nachfolgend ist die Funktion dargestellt, | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // Die Struktur der Parameter des Infrarot-Entfernungsmessers | ||
| + | // | ||
| + | typedef const struct | ||
| + | { | ||
| + | const signed short a; | ||
| + | const signed short b; | ||
| + | const signed short k; | ||
| + | } | ||
| + | ir_distance_sensor; | ||
| + | |||
| + | // | ||
| + | // Die Parametereigenschaften des GP2Y0A21YK Sensors | ||
| + | // | ||
| + | const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; | ||
| + | |||
| + | // | ||
| + | // Konvertieren der Werte des Infrarot-Entfernungsmessers in Centimeter | ||
| + | // Gibt -1 aus, wenn die Konvertierung nicht erfolgreich war | ||
| + | // | ||
| + | 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; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Zur Durchführung der Konvertierung muss die Funktion // | ||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // Beispielprogramm des Infrarot-Entfernungsmessers des HomeLab | ||
| + | // Die in Centimetern gemessenen Ergebnisse werden auf dem LCD abgebildet | ||
| + | // | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // | ||
| + | // Hauptprogramm | ||
| + | // | ||
| + | int main(void) | ||
| + | { | ||
| + | unsigned short value; | ||
| + | signed short distance; | ||
| + | char text[16]; | ||
| + | |||
| + | // 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); | ||
| + | |||
| + | // Löschen des LCD | ||
| + | lcd_alpha_clear(); | ||
| + | |||
| + | // Name des Programms | ||
| + | lcd_alpha_write_string(" | ||
| + | |||
| + | // Installation des ADC | ||
| + | adc_init(ADC_REF_AVCC, | ||
| + | |||
| + | // Endlosschleife | ||
| + | while (true) | ||
| + | { | ||
| + | // Auslesen des viermal gerundeten Wertes der Outputspannung des Sensors | ||
| + | value = adc_get_average_value(0, | ||
| + | |||
| + | // Konvertieren des ADC-Wertes in Entfernung | ||
| + | distance = ir_distance_calculate_cm(GP2Y0A21YK, | ||
| + | |||
| + | // War die Berechnung erfolgreich? | ||
| + | if (distance >= 0) | ||
| + | { | ||
| + | // Konvertieren von Entfernung in Text | ||
| + | sprintf(text, | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | // Text für eine unbekannte Entfernung erzeugen | ||
| + | sprintf(text, | ||
| + | } | ||
| + | |||
| + | // Anzeige des Textes am Anfang der zweiten Zeile auf dem LCD | ||
| + | lcd_alpha_goto_xy(0, | ||
| + | lcd_alpha_write_string(text); | ||
| + | |||
| + | // Break | ||
| + | sw_delay_ms(500); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Zusätzliches Material ===== | ||
| + | |||
| + | * {{: | ||
| + | * [[http:// | ||