Auf Wunsch beschreibe ich hier nochmal den Umbau der IR-Schnittstelle des Asuro zum IR-Hindernisdetektor. Es wurde zwar schon in diesem Thread
https://www.roboternetz.de/phpBB2/viewtopic.php?t=10026
vorgestellt, aber hier ist es jetzt in einem Beitrag zusammengefasst, im Detail beschrieben und mit Beispielcode.
Im Asuro ist bereits alles dafür vorhanden, die IR-Diode SFH415-U (D10) als Sender und der Baustein SFH5110-36 (IC2) als Detektor. Man muß nur die beiden Bauteile mechanisch nach vorne ausrichten. Vorsicht beim Auslöten von IC2, das geht nicht so ganz einfach. Man sollte das geeignete Werkzeug zur Hand haben, sonst könnte der Baustein kaputt gehen. Elektrisch kann die Schaltung bleiben, damit auch weiterhin das Flashen und die Funktion als serielle IR-Schnittstelle wie gewohnt möglich sind. Den mechanischen Umbau kann man recht gut in dem Bild erkennen. Befestigt ist der Aufsatz mit einem Gewindebolzen in dem bereits vorhandenen Loch in der Asuroplatine. Wichtig für eine gute Funktion sind der Mittelsteg und das so weit nach vorne gezogene untere Blech. Der Mittelsteg verhindert eine direkte optische Kopplung zwischen Sendediode und Empfänger und das vorgezogene Blech vermeidet Reflektionen von Bauteilen des Asuro bzw. vom Untergrund direkt vor dem Asuro. Die elektrischen Verbindungen werden einfach mit isolierten Litzen von der Asuroplatine zu dem Aufsatz gezogen (siehe auch Bild).
Bild hier
Um nun ein Hindernis detektieren zu können, muss man nur die IR-Diode mit 36kHz versorgen. Das ist die Frequenz, die der IR-Empfänger SHF5110-36 braucht. Der Ausgang des IR-Empfängers wird dann auf LOW gezogen, wenn ein reflektiertes Signal erkannt wird. Das 36kHz-Signal ist im Asuro schon vorbereitet und steht am Ausgang PB3 an. Die IR-Diode ist über einen Vorwiderstand an PB3 und an PD1 angeschlossen. Man braucht also nur den Ausgang PD1 am Atmega auf LOW setzen und schon sendet die IR-Diode. Folgende 2 Zeilen im C-Programm sorgen dafür:
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
Die Auswertung des IR-Empfängers erfolgt über den Eingang PD0 des Atmega mit z.B. folgendem Code:
if (!(PIND & (1 << PD0))) // prüft Eingang PD0 auf LOW
Das ist die einfache Version der Hinderniserkennung mit der unveränderten Library "asuro.c". Ich habe zusätzlich noch eine Erweiterung durchgeführt, damit die Intensität der IR-Diode gesteuert werden kann. Das ermöglicht auch eine Erkennung bei geringeren Entfernungen, denn in der einfachen Version ist die Empfindlichkeit maximal und die Hindernisse werden meist bei 1 Meter oder mehr erkannt. Dazu musste ich allerdings die Library "asuro.c" verändern. Wer die Erweiterung haben will, muss auch meine Lib verwenden. Die Lib ist auf der Weja-Lib aufgebaut, wer die bereits benutzt, braucht also auf nichts zu verzichten. Mit meiner Lib "asuro.c" kann man die Intensität der IR-Diode mit der Pulsbreite des 36kHz-Signals steuern. Die Pulsbreite wird mittels Output Compare Register (OCR2) programmiert. Im Prinzip ist es eine PWM für die IR-Diode. Die kleinste einstellbare Pulsbreite ist 125ns, was dem µC-Takt entspricht und die grösste sinnvolle Pulsbreite ist 13,75µs, was 50% Tastverhältnis entspricht. Hier einige Beispiele zur Programmierung:
OCR2 = 0xFE; //Pulsbreite 1 entspricht 125ns
OCR2 = 0xFD; //Pulsbreite 2 entspricht 250ns
:
OCR2 = 0x90; //Pulsbreite 110 entspricht 13,75µs
Die Pulsbreite entspricht also der Differenz aus 255 und dem OCR2-Register.
Mit der Programmierung der Pulsbreite ist es nun möglich die Empfindlichkeit so weit runter zu drehen, dass der Detektor auch erst bei Objekten in 3cm Abstand anspricht. Damit kann man sich relativ gut an Objekte annähern. Allerdings ist zu sagen, dass das Prinzip keine exakte Abstandsmessung zulässt, da die Stärke der Echos abhängig ist vom Reflexionsfaktor des Objektes. Je nach Farbe und Winkel wird ein stärkeres oder schwächeres Signal reflektiert. Das ist aber generell so bei IR-Detektoren, Ausnahme sind die Sharp-Detektoren, die nach einem anderen Prinzip arbeiten.
Meine Lib "asuro.c" und auch "asuro.h" sind in dem zip-File im Anhang zu finden.
Hier noch 2 kleine Testprogramme. Für beide ist meine Lib notwendig.
Mit dem 1. Testprogramm lässt sich anhand der Taster am Asuro die Pulsbreite und damit die Empfindlichkeit einstellen. Die Status-LED zeigt mit dem Wechsel von grün auf rot ein erkanntes Objekt an. Das Testprogramm verdeutlicht sehr schön die Wirkung der Pulsbreite.
Code:
#include "asuro.h"
#include <stdlib.h>
int main(void)
{
unsigned char sw;
Init();
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
while(1)
{
if (PIND & (1 << PD0))
StatusLED(GREEN);
else
StatusLED(RED);
sw = PollSwitch();
if (sw & 0x01)
OCR2 = 0xFE; //Pulsbreite 1
if (sw & 0x02)
OCR2 = 0xFD; //Pulsbreite 2
if (sw & 0x04)
OCR2 = 0xFB; //Pulsbreite 4
if (sw & 0x08)
OCR2 = 0xF7; //Pulsbreite 8
if (sw & 0x10)
OCR2 = 0xEF; //Pulsbreite 16
if (sw & 0x20)
OCR2 = 0x90; //Pulsbreite 110
}
return 0;
}
Im 2. Testprogramm wird die Pulsbreite laufend von 1 bis 110 durchgesweept. Je nach Entfernung verändert sich die Farbe der Status-LED von rot über orange nach grün.
Code:
#include "asuro.h"
#include <stdlib.h>
int main(void)
{
float puls;
Init();
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
puls = 1;
while(1)
{
if (PIND & (1 << PD0))
StatusLED(GREEN); // kein Hindernis
else
StatusLED(RED); // Hindernis erkannt
puls = 1.02 * puls; // Pulsbreite wird um 2% erhöht
if (puls > 110) puls = 1;
OCR2 = 255 - (int)(puls);
}
return 0;
}
Mit den beiden Testprogrammen kann man nun spielen und herausfinden wie der IR-Detektor auf verschiedene Objekte reagiert.
Ich hoffe es gefällt und freue mich auf Feedback und vielleicht sogar Verbesserungen.
Gruss Waste
Lesezeichen