PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Portüberlastung?



sloti
25.10.2008, 12:38
Moin moin,

ich bastel im Moment an einem Roboter mit ATmega 16, der Controller ist bis auf 2 Pins voll belegt. An sich ja kein Problem oder? An dem ADC Port befinden sich 3 Sharp sensoren und 2 Linien sensoren bzw. SFH300 Fototransistoren belegt, d.h. PA0 bis PA4. Den Motortreiber l293d hab ich and PD2-PD7 angeschlossen. Der rest ist mit LEDs und ISP schnittstelle belegt. Nun zu meiner Frage. Als ich die IR-LEDs ( http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&products_id=116 )für die Linienverfolgung an die noch freien Ports von Port D angeschlossen habe, also PD0 und PD1, konnte ich die Motoren nicht mehr vernünftig ansteuern wenn die LEDs brannten, wenn sie aus waren hatte ich da keine Probleme mehr. Die Motoren haben da blos gezuckt. Dann habe ich die IR-LEDs an zwei freie Pins an Port B angeschlossen dort nun das selbe problem, dass wenn ich die IR-LED angeschaltet hab ich die anderen LEDs an dem Port nicht mehr vernünftig ansteuern kann. Aber die Motoren gingen nun wieder und ich komme auch ohne die LEDs aus, ich kann sie ja auch wieder benutzen wenn ich mit der linie fertig bin und die IR-LEDs aus sind. Nun das finde ich schon reichlich komisch, kann es sein das der Port einfach überlastet ist und den Geist aufgibt? Nun aber zu meinem eigentlichen Problem. Seit dem ich nun die (bösen) IR-LEDs angeschlossen habe kann ich auch nicht mehr Rückwärts fahren. Der Bot soll nämlich rückwärts in eine Parklücke fahren. Dazu sind die sharp sensoren. Er fährt jetzt also auf der Straße mithilfe der Liniensensoren und bleibt auch da stehen wo er soll schaltet die IR-LEDs aus und die Leds die vorher nicht gingen ohne Probleme ein. Doch jetzt wo er rückwärts fahren soll fängt die Led an zu Flackern und er macht gar nichts mehr. Das eigenartige ist blos bevor ich Liniensensoren angeschlossen hatte funktionierte das einparken schon und ich habe nichts geändert außer die Linienverfolgung dazu zu schreiben. Hat jemand vielleicht schonmal ähnliches erlebt oder hat jemand eine Idee woran das liegen könnte. Hier ist mal der Code :



#define F_CPU 1000000
#include <avr\io.h>
#include <avr\interrupt.h>
#include <inttypes.h>
#include <util/delay.h>



#define green 1
#define yellow 2
#define red 3
#define all 4
#define off 5
#define fwd 6
#define bwd 7
#define on 8


inline void Richtung_rechts(unsigned char c)
{
if (c==6) { PORTD |= (1<<PD2);PORTD &=~(1<<PD3);}
else { PORTD |= (1<<PD3);PORTD &=~(1<<PD2);}
}

inline void Richtung_links(unsigned char a)
{
if (a==6) { PORTD |= (1<<PD6);PORTD &=~(1<<PD7);}
else { PORTD |= (1<<PD7);PORTD &=~(1<<PD6);}
}

inline void Geschwindigkeit(unsigned char right_speed , unsigned char left_speed)
{
OCR1B = left_speed;
OCR1A = right_speed;
}

void DistanceData(unsigned int *data)
{
// Prozessorinterne Referenz verwenden
// Multiplexer auf linken Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1);
// Wandlung starten
ADCSRA |= (1 << ADSC);
// Warten, bis Wandlung beendet
while (!(ADCSRA & (1 << ADIF)));
// ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
// ADC-Wert auslesen
data[0] = ADCL + (ADCH << 8);// normale Sensoranordnung
// data[1] = ADCL + (ADCH << 8);// gekreuzte Sensoranordnung

// Prozessorinterne Referenz verwenden
// Multiplexer auf linken Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1)|(1<<MUX0);
// Wandlung starten
ADCSRA |= (1 << ADSC);
// Warten, bis Wandlung beendet
while (!(ADCSRA & (1 << ADIF)));
// ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
// ADC-Wert auslesen
data[1] = ADCL + (ADCH << 8);// normale Sensoranordnung
// data[1] = ADCL + (ADCH << 8);// gekreuzte Sensoranordnung

// Prozessorinterne Referenz verwenden
// Multiplexer auf linken Sensor schalten
ADMUX = (1 << REFS0) | (1 << REFS1)|(1<<MUX1);
// Wandlung starten
ADCSRA |= (1 << ADSC);
// Warten, bis Wandlung beendet
while (!(ADCSRA & (1 << ADIF)));
// ADCIF zurücksetzen
ADCSRA |= (1 << ADIF);
// ADC-Wert auslesen
data[2] = ADCL + (ADCH << 8);// normale Sensoranordnung
// data[1] = ADCL + (ADCH << 8);// gekreuzte Sensoranordnung
}

void status (int a)
{
if (a ==1)
{
PORTB |= (1<<PB0);
PORTB &=~(1<<PB1);
PORTB &=~(1<<PB2);
}

else if (a ==2)
{
PORTB |= (1<<PB1);
PORTB &=~(1<<PB0);
PORTB &=~(1<<PB2);
}

else if (a ==3)
{
PORTB |= (1<<PB2);
PORTB &=~(1<<PB1);
PORTB &=~(1<<PB0);
}



else if (a ==4)
{
PORTB = (1<<PB0)|(1<<PB1)|(1<<PB2);

}

else if (a ==5)
{
PORTB &=~(1<<PB2);
PORTB &=~(1<<PB1);
PORTB &=~(1<<PB0);
}
}

void IR_Status1 (int b)
{
if (b==1)
{
PORTC |=(1<<PC7);
PORTC &=~(1<<PC6);
}

else if (b==3)
{
PORTC |=(1<<PC6);
PORTC &=~(1<<PC7);
}

else if (b==4)
{
PORTC =(1<<PC6)|(1<<PC7);

}

else if (b ==5)
{

PORTC &=~(1<<PC6);
PORTC &=~(1<<PC7);
}
}

void IR_Status2 (int b)
{
if (b==1)
{
PORTA |=(1<<PA6);
PORTA &=~(1<<PA7);
}

else if (b==3)
{
PORTA |=(1<<PA7);
PORTA &=~(1<<PA6);
}

else if (b==4)
{
PORTA =(1<<PA6)|(1<<PA7);

}

else if (b ==5)
{

PORTA &=~(1<<PA6);
PORTA &=~(1<<PA7);
}
}

void IR_Status3 (int b)
{
if (b==1)
{
PORTC |=(1<<PC0);
PORTC &=~(1<<PC1);
}

else if (b==3)
{
PORTC |=(1<<PC1);
PORTC &=~(1<<PC0);
}

else if (b==4)
{
PORTC =(1<<PC1)|(1<<PC0);

}

else if (b ==5)
{

PORTC &=~(1<<PC1);
PORTC &=~(1<<PC0);
}
}

void showstart (void)
{
status(red);
_delay_ms(1000);
status(yellow);
_delay_ms(1000);
status(green);
_delay_ms(1000);
status(off);
_delay_ms(1000);

for(int i=0;i<5;i++)
{
status(red);
_delay_ms(100);
status(yellow);
_delay_ms(100);
status(green);
_delay_ms(100);
status(off);
_delay_ms(100);
}


}
void LineData(unsigned int *data)
{


ADMUX = (1 << REFS0) | (1<<MUX0)| (1<<MUX1); // AVCC reference with external capacitor

ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);


ADMUX = (1 << REFS0) | (1<<MUX2); // AVCC reference with external capacitor

ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);


}

void LinienLED(int a)
{
if (a==8)
{
PORTB= (1<<PB3)|(1<<PB4);
status(off);
}

else
{
PORTB &=~(1<<PB3)|(1<<PB4);
}

}


void init (void)
{
DDRB = (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4);
DDRC = (1<<PC0)|(1<<PC1)|(1<<PC6)|(1<<PC7);
DDRA = (1<<PA6)|(1<<PA7);
DDRD = (1<<PD2)|(1<<PD3)|(1<<PD5)|(1<<PD4)|(1<<PD6)|(1<<PD7);;
TCCR1A = (1<<COM1A1)|/*(1<<COM1A0)*/(1<<COM1B1)|/*(1<<COM1B0)|(1<<FOC1A)|(1<<FOC1B)|(1<<WGM11)|*/(1<<WGM10);
TCCR1B = /*(1<<ICNC1)|(1<<ICES1)|(nix)|(1<<WGM13)|(1<<WGM12)|(1<<CS12)|*/(1<<CS11)/*|(1<<CS10)*/;
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
status(green);
Richtung_rechts(fwd);
Richtung_links(fwd);
}

int main (void)
{
init();
unsigned int data[3],licht[2];
//showstart();
LinienLED(on);
// IR_Status1(red);
//IR_Status2(red);

while (1)
{
DistanceData(data);
LineData(licht);

if(licht[1]>400) // rechts weiß
{
if (licht[0]>400)
{
Geschwindigkeit(250,250);
}

else
{
Geschwindigkeit(250,0);
}
}

else
{
if (licht[0]>400)
{
Geschwindigkeit(0,250);
}
}

if (data[0]>500&&data[1]>500)
{
LinienLED(off);

Geschwindigkeit(0,0);
Richtung_links(bwd);
Richtung_rechts(bwd);


while(1)
{
status(green);


}
}


}
return 0;
}

Sorry, der Code ist noch ein wenig unordentlich und da ich nicht weiß ob das Problem software oder Hardware mäßig ist kann es auch sein das ich im falschen Thread bin.

mfg
Erik

Besserwessi
25.10.2008, 14:12
Die IR LEDs brauchen wie andere LEDs einen Vorwiderstand. Direkt am Controller sollte man höchstens 20 mA je Ausgang vorsehen. Wenn man die IR LEds mit voller Helligkeit (in der Regel 100 mA) betreiben will braucht man also einen Treiber. Je nach Anwendung können die 20 mA aber auch ausreichen.

avion23
25.10.2008, 14:15
Hallo Sloti,
welche Spannungsversorgung hast du? 7805? Wo ist der Motortreiber angeschlossen - ich hoffe nicht am 7805? Kann es sein, dass deine Versorgungsspannung soweit einbricht, dass der 7805 nicht die Spannung nicht halten kann?

Welchen Strom ziehen deine IR-Leds? Gemeßen, nicht angegeben. Welcher Vorwiderstand?

sloti
25.10.2008, 18:44
Hmm ok also die Überlastung des 7805 in kombination mit einem Kurzschluss den ich beim Montieren der Liniensensoren eingebaut habe war das Problem. Kurzschluss behoben Motoren direkt an den Akku angeschlossen und es funktioniert alles :) . Das ganze hat auch noch den schönen nebeneffekt das der kleine jetzt doppelt so schnell fährt wie vorher :) .

Danke für die Hilfe
mfg
Erik