-
ATMEGA32 mit 2 IR-LEDs
Hallo zusammen,
ich habe nun meinen ASURO mit einem ATMEGA32-Prozessor ausgestattet.
Um die "Sichtweite" zu erweitern, habe ich versucht die IR-Einheit auf 2 LEDs zu erweitern:
- Die Kathode der rechten IR-LED hängt mit Vorwiderstand an PIN15 (PD1)
- Die Kathode der linken IR-LED hängt mit Vorwiderstand an PIN2 (PB1)
- Die Anoden beider IR-LEDs sind mit PIN21 (PD7) verbunden
Ich möchte nun ein Testprogramm machen, das zwischen der linken und rechten LED unterscheiden kann. Wenn die rechte LED ein Hindernis "sieht", soll die Status-LED grün leuchten, wenn die linke LED ein Hindernis "sieht", soll die Status-LED rot leuchten und wenn beide ein Hindernis erkennen soll die Status-LED orange leuchten.
Die Ausgänge auf LOW ziehen mache ich mit:
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
und
DDRD |= (1 << DDB1); // Port B1 als Ausgang
PORTD &= ~(1 << PB1); // PB1 auf LOW
So weit, so gut - nur wie kann ich zwischen links und rechts unterscheiden?
Die Platine habe ich hier erworben: http://www.e-robotix.de
Noch ein Foto von meinem Umbau:
-
Hallo pinsel,
wie willst du denn IR LEDs als Sensor verwenden? :-k
Eine IR LED kann Infrarot Licht senden, nicht empfangen.
Oder meinst du vielleicht Fototransistoren? Die müßtest du allerdings wie die Liniensensoren an Analog Eingänge hängen. Und die Ports müssen dementsprechend als Eingang initialisiert werden.
-
Hi m.a.r.v.i.n,
Sender sind 2 Infrarot-DIODEN vom Typ SFH415-U. Als Empfänger verwende ich einen IR-TRANSISTOR vom Typ SFH5110, der mit OUT am PIN14(PD0) verbunden ist.
-
Hei, pinsel120866,
hübsche Geschichte! Aber laufen jetzt die üblichen asuro-Programme ohne Änderung? Ausserdem: ich nehm mal an, dass Du nachgerechnet hast (oder nachgemessen), ob der µC ohne Probleme beide LED´s treiben kann. Weil ein Port ja eine Stromquelle/-senke mit etwas begrenzter Lieferfähigkeit ist.
Zum Unterscheiden: eben einen der Ports auf high setzen, dann ist nur der andere aktiv. Optisch "siehst" Du die LED leuchten, wenn Du sie mit einer digitalen Kamera betrachtest - also Optik auf die LED und auf dem Display gucken. Bei mir geht auch die Cam im Handy.
Na und dass Du mit den "Dioden" nicht sehen kannst, das hatten wir doch schon hier .
Viel Erfolg mit dem Gerät.
-
Hallo Pinsel,
der SFH5110 ist keine IR-LED , sondern ein Infrarot Empfänger IC für moduliertes IR Licht. Das wären dann ja 3 Empfänger und gar kein Sender.
Irgendwie verstehe ich nicht, was du eigentlich machen willst.
Ein Entfernungsdetektor wie der Liniensensor mit 2 Fototransistoren als Empfänger und einer LED als Sender. Dazu brauchst du 2 Analog Eingänge und einen Digital Ausgang. Ein Fototransistor empfängt das Licht von der linken Seite, der andere von der rechten.
Oder ein Entfernungsdetektektor wie die Modifikation der IR Schnittstelle von waste, mit einem IR Empfänger IC und 2 IR-LEDs als Sender. Dazu benötigst du einen digital Eingang und 3 Ausgänge für die IR LEDs (einer davon PWM fähig wg. moduliertem IR Licht). Ob das mit einem Empfänger funktioniert, kann ich so nicht sagen. Theoretisch ja, indem man die IR LEDs abwechselnd einzeln anschaltet und dann mit dem Empfänger lauscht, ob ein Signal aus dieser Richtung kommt.
In deiner Initialisierung für PB1 war noch ein Fehler. So geht es.
Code:
DDRB |= (1 << DDB1); // Port B1 als Ausgang
PORTB &= ~(1 << PB1); // PB1 auf LOW
Zudem müßte PD7 als Timer Ausgang die 36kHz liefern, sonst empfängt der SFH5110 kein Signal. Code für den Mega32 hab ich gerade nicht griffbereit.
-
Hallo,
ich habe folgenden Code angepasst und getestet:
Code:
/************************************************************************
Test Programm fuer den ASURO IR-Adapter
Der ASURO ermittelt ueber den nach vorne gerichteten
Infrarot Empfänger und Sender über die Reflektion des
Lichtes an einem Objekt ungefaehr dessen Abstand.
Es wird je nach Abstand die Status-LED in verschiedenen Farben
eingeschaltet. Bei der größten Reflexion werden zusätzlich
die Rueckfahr-LEDs eingeschalten.
Zur Compilierung dieses Programmes wird asuro.c und asuro.h aus
der ASURO Lib 2.6.1 benötigt. Die ASURO Lib ist auf sourceforge
zu finden.
************************************************************************
Hardware: ASURO Roboter
prozessor: ATMEGA32
clock: 16MHz Crystal
****************************************************************************
date authors version comment
====== ====================== ======= ==============================
Jan.08 (ch) robo.fr V1.0 First implemetation
Mai 08 (aut) pinsel120866 V1.1 Erweitert auf 2 IR-Dioden
Versions:
V1.0
- first version
***************************************************************************/
/***************************************************************************
*
* (c) 2007 robo.fr , christoph(at)roboterclub-freiburg.de
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
***************************************************************************/
#include "asuro.h"
#include <stdlib.h>
/*************************************************************************
uint8_t objekt_sichtbar(uint8_t abstand)
Ist ein Objekt in der Entfernung kleiner oder gleich
dem Eingangsparameter "abstand" erkennbar?
objekt_sichtbar(7) liefert TRUE zurück, falls überhaupt
ein Object detektierbar.
abstand:
0: 5cm
1: 7cm
2: 13cm
3: 15cm
4: 16cm
5: 17cm
6: 18cm
7: 22cm
( Testobjekt: Joghurtecher, Umgebungsbeleuchtung: Zimmer )
return: TRUE falls Objekt gefunden
FALSE wenn nicht
Zeitbedarf: 5ms
*************************************************************************/
uint8_t objekt_sichtbar_rechts(uint8_t distance)
{
uint16_t j,z;
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
uint8_t objekt_sichtbar_links(uint8_t distance)
{
uint16_t j,z;
DDRB|= (1 << DDB1); // Port B1 als Ausgang
PORTB &= ~(1 << PB1); // PB1 auf LOW
OCR2 = 254-distance; // wenn OCR2=0xFE dann Objekt sehr nahe
z=0;
for(j=0;j<30;j++) // loop time: 5ms
{
if (PIND & (1 << PD0))z++;
Sleep(6); // 6*Sleep(6)=1ms
}
if (z>=29) return FALSE; // Objekt nicht gefunden
else return TRUE;
}
/*************************************************************************
uint8_t abstand()
Abstandsermittelung über IR-Sendiode / IR-Empfänger.
0:kleinster Abstand
7:größter Abstand
255: kein Objekt
Zeitbedarf: 5ms*9=45ms
*************************************************************************/
uint8_t abstand_rechts()
{
uint8_t k,n;
k=255;
for(n=0;n<8;n++)
{
if (!objekt_sichtbar_rechts(n)) k=n; // solange kein Objekt, Distanz erhoehen
}
return k;
}
uint8_t abstand_links()
{
uint8_t l,m;
l=255;
for(m=0;m<8;m++)
{
if (!objekt_sichtbar_links(m)) l=m; // solange kein Objekt, Distanz erhoehen
}
return l;
}
/*************************************************************************
Hauptprogramm
*************************************************************************/
int main(void)
{
uint8_t n,m;
Init();
FrontLED(ON);
while(1)
{
n=abstand_rechts();
m=abstand_links();
StatusLED(OFF);
BackLED(OFF,OFF);
if ((n!=255) || (m!=255))
{
if (n<2) StatusLED(GREEN);
if (m<2) StatusLED(RED);
Msleep(10);
}
else StatusLED(YELLOW);
}
}
Wenn ich mit der Digitalkamera daraufblicke, leuchten beide LEDs. Irgendwie habe ich das Gefühl, als ob beide Dioden Synchron leuchten und nicht getrennt voneinander die Abstandsmessung durchführen.
-
Nochmal hallo,
es ist ein Entfernungsdetektektor wie die Modifikation der IR Schnittstelle von waste, mit einem IR Empfänger IC und 2 IR-LEDs als Sender.
-
Hallo pinsel,
sieht soweit gut aus, du mußt nur noch die nicht benötigte LED auschalten:
Code:
uint8_t objekt_sichtbar_links(uint8_t distance)
{
uint16_t j,z;
PORTD |= (1 << PD1); // PD1 auf HIGH (LED ausschalten)
DDRB |= (1 << DDB1); // Port B1 als Ausgang
PORTB &= ~(1 << PB1); // PB1 auf LOW
...
uint8_t objekt_sichtbar_rechts(uint8_t distance)
{
uint16_t j,z;
PORTB |= (1 << PB1); // PB1 auf HIGH (LED ausschalten)
DDRD |= (1 << DDD1); // Port D1 als Ausgang
PORTD &= ~(1 << PD1); // PD1 auf LOW
...
und beachte den Unterschied zwischen PORTD und PORTB, bzw. DDRD und DDRB.
-
Danke m.a.r.v.i.n,
hat geklappt, jetzt hat mein Asuro 2 "Augen" und kann sogar zwischen links und rechts unterscheiden. Als nächstes versuche ich mich an einem Programm zur Hinderniserkennung und -umfahrung in die Richtung, wo mehr Platz ist.
-
Super, dann mal weiter so.