PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMEGA32 mit 2 IR-LEDs



pinsel120866
14.05.2008, 07:46
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:

m.a.r.v.i.n
14.05.2008, 13:32
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.

pinsel120866
14.05.2008, 13:47
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.

oberallgeier
14.05.2008, 14:07
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 . (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=364963#364963)

Viel Erfolg mit dem Gerät.

m.a.r.v.i.n
14.05.2008, 14:16
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.


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.

pinsel120866
14.05.2008, 14:19
Hallo,

ich habe folgenden Code angepasst und getestet:


/************************************************** **********************

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.

pinsel120866
14.05.2008, 14:28
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.

m.a.r.v.i.n
14.05.2008, 14:35
Hallo pinsel,

sieht soweit gut aus, du mußt nur noch die nicht benötigte LED auschalten:


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.

pinsel120866
14.05.2008, 14:48
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.

m.a.r.v.i.n
14.05.2008, 14:55
Super, dann mal weiter so.

oberallgeier
14.05.2008, 14:59
Hi pinsel,

also ich seh in Deinem Code keine Timerinitialisierung für die LED. Vorbehaltlich der Tatsache, dass ich mit dem mega168 arbeite - OC1A steuert bei mir den PB1 - sende ich Dir als Anhalt für Deine Programmierung meine Codeschnippsel. ACHTUNG - bei Dir/beim mega32 geht OC1A auf Pin19/PD5 - und es ist natürlich/vermutlich die Initialisierung mit anderen Registerwerten durchzuführen.

Die Anschlüsse an MEINEM mega168:


--------------------==========-----------------------
Vorgesehene/belegte Anschlüsse am (ATMega168)-R2D03:
================== (für ´168 d = Drive/Director)
/RESET 1 28 PC5,(SCL)
RxD,(PD0) 2 27 PC4,(SDA)
TxD,(PD1)___3 26___PC3, ADC0 / Sharp GP2D120
(SigMot1) ExtINT0,(PD2) 4 25 PC2, SFH 5110, IN irDME 4 } vorgesehen
(SigMot2) ExtINT1,(PD3) 5 24 PC1, SFH 5110, IN irDME 3 } evtl. auch in
(E7) _|-- 3,4 Guz, PD4___6 23___PC0, SFH 5110, IN irDME 1-2 } ´168 n
VCC 7 22 GND
GND 8 21 AREF
XTAL1 PB6___9 20___VCC
XTAL2 PB7 10 19 PB5, Startblink (LED0), 3sec v Tmr0, Mehrzweck
(E6) PWM 1,2 uz+Guz,PD5 11 18 PB4 _|-- 3,4 uz (E4) (hier oder PB3)
(E5) PWM 3,4 uz+Guz,PD6___2 17___PB3, Reserve 2
(E8) _|-- 1,2 uz,PD7 13 16 PB2, Reserve 1
(E9) _|-- 1,2 Guz,PB0 14 15 PB1 SFH 415, OUT (irDME) */
/* ================================================== ============================ */

Die Timerinitialisierung zusammen mit der Subroutine, mit der OC1A gestellt wird, Basis ist ein Prozessortakt von 20 MHz:

/* ================================================== ============================ */
/* == PWM-Routinen zur IRLED-ansteuerung auf OC1A/PB1 ======================= */
void TC1SRV_init(void) //Init Timer/Counter 1, PWM-Signal
{ // normale PWM aktivieren (nicht invertiert)
TCCR1A |= (1<<COM1A1); //Clear/set OC1A on Compare Match, doc S132.
// Edit: hier war ein falscher Kommentar
// TCCR1A |= (1<<WGM11); //WGM10=0 => PWM, Phase Correct, doc S 133
TCCR1B |= (1<<CS10); // cs10 <=> clk/1 => no prescaling doc S 134
TCCR1B |= (1<<WGM13); // PWM, Phase+Frequency correct doc S 134
ICR1 = 270; // =>PWM-Frequenz 20MHz/(2*nn) => 37,0kHz/
/* Interrupts für Timer2 deaktivieren. Siehe Registerbelegung :
mega168 Bit7 6 5 4 3 2 1 0
TIMSK1 – – ICIE1 – – OCIE1B OCIE1A TOIE1
im m168 ? ? ? ? ? ? ? ? */
//
TIMSK1 &= ~(1<<OCIE1A)|(1<<OCIE1B); // Tmr/Cntr1 Oput CompA/B Mtch intrrpt disab
TIMSK1 &= ~(1<<TOIE1); // Tmr/Cntr1 Overflow interrupt disabled
}
/* ================================================== ============================ */
void setSRV1(uint16_t speed1) //Relative Pulslänge auf OC1A/PB1
{OCR1A = speed1;} // z.B. für SFH5110 oder Servo
/* ================================================== ============================ */Übrigens fahre ich aus bestimmten Gründen mit 37 kHz, das müsstest Du entsprechend anpassen. Die setSRV1 wird mit dem gewünschten Parameter aufgerufen.

Aufruf Timerinitialisierung aus main:


TC1SRV_init(); //Init Timer/Counter1 37,xkHz am 21feb08, 17:28

Der Rest sollte Dir ja geläufig sein. Nochmal - wenn Du Teile dieses Codes verwendest, musst Du die Register an Deinen mega32 anpassen!!!

pinsel120866
14.05.2008, 15:05
Danke Nachbar,

ich werd's mir mal Schritt für Schritt zu Gemüte führen - ist ja nicht gerade sooo einfach...

pinsel120866
15.05.2008, 09:42
Ich habe mich jetzt an folgendem Ablauf versucht:

Der Asuro soll einen Fixen Abstand zu einem Gegenstand einhalten, egal ob wie der Gegenstand sich bewegt. Wenn der GST sich wegbewegt, soll der Asuro folgen, wenn der GST näherkommt, soll der Asuro zurückweichen. Wie ein Hund, der einen Einbrecher gestellt hat :-)

Nur läuft es nicht so, wie ich's gerne hätte:

/************************************************** ***********************

Hauptprogramm

************************************************** ***********************/

int main(void)
{
uint8_t n,m,diff;

Init();

FrontLED(ON);
while(1)
{
n=abstand_rechts();
m=abstand_links();

if ((n > 2) && (m > 2))
{
diff = m - n;

if(abs(diff) > 0)
{
MotorDir(FWD, FWD);
MotorSpeed(255,155);
}
if (abs(diff) < 0)
{
MotorDir(FWD, FWD);
MotorSpeed(155,255);
}
}
else if ((n < 2) && (m < 2))
{
diff = m - n;

if(abs(diff) > 0)
{
MotorDir(RWD, RWD);
MotorSpeed(155,255);
}
if (abs(diff) < 0)
{
MotorDir(RWD, RWD);
MotorSpeed(255,155);
}
}
else
MotorSpeed(BREAK, BREAK);
}
}

Wo ist mein Denkfehler?

pinsel120866
17.05.2008, 15:58
Auch auf die Gefahr hin, in diesem Threat Selbstgespräche zu führen habe ich das o. a. Programm etwas überarbeitet:


/************************************************** ***********************

Hauptprogramm

************************************************** ***********************/

int main(void)
{
uint8_t n,m,diff;

Init();

FrontLED(ON);
while(1)
{
n=abstand_rechts();
m=abstand_links();

if ((n > 2) || (m > 2))
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(100,100);
}

else if ((n < 2) || (m < 2))
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(100,100);
}

else
MotorSpeed(BREAK, BREAK);
}
}
Damit hält der Asuro einen bestimmten Abstand zu einem Hindernis ein, dass sich entfernt bzw. auf ihn zubewegt - allerdings ohne sich seitlich zu bewegen.

Ich möchte nun einbauen dass sich der Asuro immer mit beiden "Augen" auf das Hindernis ausrichtet und den Abstand beibehält.

Hätte ev. einer von euch einen Tipp, wie ich dies machen könnte?

Danke in voraus für eure Unterstützung.

oberallgeier
17.05.2008, 16:24
Hallo pinsel120866,

irre ich mich, oder ist das nicht die gleiche Aufgabe wie in dem Thread von raid_ox (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=250910#250910) ? Der hatte dort auch einen Codeabschnitt veröffentlicht. Hattest Du dort nicht auch schon mal gepostet?

pinsel120866
17.05.2008, 17:02
Hallo Oberallgeier,

du irrst dich nicht, allerdings kann ich den Code von Raid nicht auf meine Anforderung übertragen, ich hab's versucht aber leider ohne Erfolg.

Da ich ja im Programmieren nicht gerade der Beste bin, hab ich trotzdem mal versucht selber einen passenden Code zu erstellen.

pinsel120866
12.07.2008, 14:00
Hallo Miteinander,

der Vollständigkeit halber habe ich ein Video meiner Erweiterung hier abgelegt:

http://de.youtube.com/watch?v=zOv8ilG39kc

oberallgeier
12.07.2008, 14:34
Aber hallo, nicht mal zwei Monate - und dann DER Fortschritt. Klasse! (Im Hintergrund hört man jetzt rauschenden Beifall). Im Ernst, ich finde das s..gut! Und die Bande hält ja auch vielfach höhere Geschwindigkeiten aus - da ist also schon wieder ein Fortschritt absehbar.

PS: So was kann mein asuro nicht.

pinsel120866
12.07.2008, 15:04
Lieber Nachbar,

auch wenn mich das leise Gefühl beschleicht dass bei deiner Antwort eine kräftige Portion Ironie drinsteckt, danke ich dir sehr herzlich für das Lob!

Ich versuche nur mit meinen sehr begrenzten Mitteln die Technik der kleinen Schritte anzuwenden, was auch nur kleine Erfolge zulässt.

Wer weiß, vielleicht werde ich mal DerAltevom(Rhein)Tal. :-)

oberallgeier
12.07.2008, 15:17
Nein - wirklich nicht - keinerlei Ironie. Fällt mir garnicht ein. Wie gesagt - so etwas kann mein asuro nicht - warum wohl - weil ICH so ein Programm nicht hinkrieg.


... Wer weiß, vielleicht werde ich mal DerAltevom(Rhein)Tal.
Immerhin wäre das ein Titel der keinen so entsetzlich schlechten Ruf hat. Obwohl ich mich mit dem früheren Träger des gleichen Namens in keinerle Weise ähnlich fühle oder gar ähnlich sein wollte.

Alt wird man von selbst - weil die Zeit nix anderes zu tun hat als zu verstreichen. Aber ob man was lernt und kann . . .

M1.R
13.07.2008, 15:17
Hallo Pinsel,

super! Das Ausweichen klappt ja echt gut.

Ich nehme an, der Empfänger ist in der Mitte und die LEDs leuchten abwechselnd, damit er links und rechts unterscheiden kann?
Oder gibt es 2 Empfänger?

Klappt die Verfolgung denn auch schon?

Gruss
M.

pinsel120866
13.07.2008, 18:40
Hi M.,

ja, du hast Recht - Empfänger in der Mitte und abwechselndes Leuchten der IR-Dioden.

Die Verfolgung läuft so leidlich. Ich plage mich damit einen Asuro mit Sharp-Sensoren langsam vorausfahren zu lassen, gefolgt von einem mit robo's SUMO-Aufsatz und dahinter soll dann der ASURO mit dem ATMEGA32 Prozessor folgen - also ein Gänsemarsch. Allerdings verlieren sich sie sich schnell aus den "Augen". Dein DORO bietet ja eine grosse Angriffsfläche, ich habe mir schon überlegt DIN-A4-Blätter als "Sichtfläche" zu verwenden - sieht aber unprofessionell aus.

M1.R
13.07.2008, 19:26
Hallo Pinsel,

wird sicher lustig dein "Gänsemarsch".
Was hälst du denn von der Idee, bei den vorausfahrenden ASUROs die IR-LEDs nach hinten auszurichten, so dass der Folgende seinen Vordermann sozusagen direkt sieht und nicht über die Reflektion der eigenen LED?

Gruss
M.

pinsel120866
13.07.2008, 20:44
Hört sich gut an, ist sicher die bessere Methode, dazu müsste ich allerdings den Asuro umbauen.

pinsel120866
08.08.2008, 16:02
Hallo Zusammen,

aus dem Urlaub zurück (war das heiiiiiß!) zeige ich euch gerne eine kleine Demo meines "Verfolgungsprogramms":

http://de.youtube.com/watch?v=Z3VCaXQcTHA

Ich finde das kommt dem Video von raid_ox (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=27368&highlight=) schon etwas näher - meint ihr nicht auch?

oberallgeier
08.08.2008, 16:37
Hallo Urlauber,

Verfolgungsprogramm? Ich dachte das hiesse "handzahm". Jedenfalls Gratulation - da hast Du Deine Vorgaben ja prächtig erfüllt ! ! !