PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem bei Ganganzeige für Motorrad



Mr Bean
31.03.2008, 16:49
Hallo

Ich möchte derzeit eine Ganganzeige mit einer Sieben Segment Anzeige für ein Motorrad bauen. Ich hab das ganze im Grunde auch schon zum laufen bekommen ich habe aber wohl noch Probleme mit der Eingangsspannung und der Spannung am AD Wandler.
In dem Motorrad ist ein Gangsensor dessen Widerstand sich nun ändert je nach dem wlecher Gang eingelegt ist. Die Spannung die über diesem Widerstand anliegt werte ich mit dem AD Wandler aus.

Jetzt hab ich das Problem dass sich der Controller des öfteren selber resetet. Das liegt denke ich an der "verseuchten" Eingangsspannung. Ich habe schon versucht das ganze mit einem großen (2000µ) und einen kleinen (100n) Kondensator zu verbessern leider fast ohne erfolg.

Das zweite Problem das ich habe ist eine wohl nicht ganz saubere Spannung am AD Wandler. Auch das habe ich versucht mit einem 100n Kondensator gegen Masse zu lösen, leider auch ohne Erfolg. Die Kombination aus Spule und Kondensator an der Versorgungsspannung des AD-Wandlers ist eingebaut (wie im Datenblatt).

Habt ihr da irgendwelche Ideen wie ich die beiden Probleme lösen kann?
Hier mal mein Code:

#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU = 2000000UL

void ADC_init(void);
uint16_t ADC_einlesen(void);
void Anzeige_init(void);
void long_delay(uint16_t ms);
void gangAnzeigen(void);

void print_1(void);
void print_2(void);
void print_3(void);
void print_4(void);
void print_5(void);
void print_6(void);
void print_L(void);

int main(void)
{

DDRC &= ~(1<<DDC5); //Pin C5 als eingang deklarieren (Leerlauf)
PORTC |= (1<<PC5); //Pull Up aktivieren

DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD5)|(1<<DDD4); //Pins für 7 Segmentanzeige als Ausgang
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten

DDRC = (1<<DDC2)|(1<<DDC3)|(1<<DDC4); //Pins für 7 Segmentanzeige als Ausgang
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4);

sei(); //Interrupts freigeben
TIMSK |= (1<<TOIE0); //TimerOverflow Interrupt freigeben
TCCR0 |= (1<<CS01); //Timer initialisieren und einschalten

ADC_init();
//Anzeige_init();


while(1)
{
}

}

void gangAnzeigen(void)
{
uint16_t gang;
gang = ADC_einlesen();
if ((gang<371) & (gang>367))
{
print_1();
}


else

if ((gang<469) & (gang>465))
{
print_2();
}

else

if ((gang<617) & (gang>613))
{
print_3();
}


else

if ((gang<760) & (gang>756))
{
print_4();
}

else

if ((gang<901) & (gang>897))
{
print_5();
}

else

if ((gang<969) & (gang>965))
{
print_6();
}

else

if (gang>971)
{
print_L();
}

}

ISR(TIMER0_OVF_vect)
{
gangAnzeigen();
}

void ADC_init(void)
{
ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS2);
ADMUX = (!(1<<MUX0)) | (!(1<<MUX1)) | (!(1<<MUX2));
ADMUX &= ~((1<<REFS1));
ADMUX &= ~((1<<REFS0));
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
}


uint16_t ADC_einlesen(void)
{
uint16_t result=0; //Variable für Ergebiss anlegen
uint8_t i; //Variable für Schleife anlegen

ADCSRA = (1<<ADEN);
for (i=0; i<4; i++)
{
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
result += ADC;
}

ADCSRA &= ~(1<<ADEN);
result /= 4;
return result;
}

void Anzeige_init(void)
{
int i;
for(i=0; i<2; i++)
{
PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7)); //alle LED`s einschalten
PORTC &= ~((1<<PC2)|(1<<PC3)|(1<<PC4)); //alle LED`s einschalten
long_delay(1000);
long_delay(1000);
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

print_1();
long_delay(1000);
long_delay(1000);
print_2();
long_delay(1000);
long_delay(1000);
print_3();
long_delay(1000);
long_delay(1000);
print_4();
long_delay(1000);
long_delay(1000);
print_5();
long_delay(1000);
long_delay(1000);
print_6();
long_delay(1000);
long_delay(1000);
print_L();
long_delay(1000);
long_delay(1000);
}

}

void long_delay(uint16_t ms)
{
for(; ms>0; ms--) _delay_ms(1);
}

void print_1(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD5)|(1<<PD6)); //LED`s für c und b einschalten
}

void print_2(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD4)|(1<<PD6)|(1<<PD7)); //LED`s für a,b,c einschalten
PORTC &= ~((1<<PC2)|(1<<PC4)); //LED`s für e,g einschalten
}

void print_3(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7)); //LED`s für a,b,c,d einschalten
PORTC &= ~((1<<PC4)); //LED`s für g einschalten
}

void print_4(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD5)|(1<<PD6)); //LED`s für b,c einschalten
PORTC &= ~((1<<PC3)|(1<<PC4)); //LED`s für f,g einschalten
}

void print_5(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD7)); //LED`s für a,c,d einschalten
PORTC &= ~((1<<PC3)|(1<<PC4)); //LED`s für f,g einschalten
}

void print_6(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD7)); //LED`s für a,b,c einschalten
PORTC &= ~((1<<PC2)|(1<<PC3)|(1<<PC4)); //LED`s für e,f,g einschalten
}

void print_L(void)
{
PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten
PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten

PORTD &= ~((1<<PD4)); //LED`s für d einschalten
PORTC &= ~((1<<PC2)|(1<<PC3)); //LED`s für e,f einschalten
}
Wie ihr seht hab ich schon einiges versucht um den AD Wandler "langsamer" zu machen um mir nicht allzu viele Störungen einzuhandeln.
Die nächsten ideen wären die Schleifendurchläufe in der AD-Wandlerroutine zu erhöhen, den AD Eingang zu entstören und den Controller generell etwas langsamer zu machen. Im Moment läuft er mit 8MHz (intern).
Welche Maßnahmen denkt ihr wären am hilfreichsten? Habt ihr mir weitere Ideen wie ich den AD-Eingang Hardwaremäßig entstören kann?
Vielen Dank im Voraus!

Mr Bean

Hubert.G
31.03.2008, 17:47
Wie sieht den deine Hardware aus, kannst du einmal die Schaltung zeigen.

Mr Bean
31.03.2008, 20:22
Nein kann ich leider nicht. Da diese 100km entfernt ist... :-) Ist im Grunde ein Controller experimentierboard. Also alles fest und sauber auf einer Leiterplatte aufgebaut.

Grüße!

Bean

jeffrey
01.04.2008, 14:04
hi,
ein schalplan reicht doch schon.
mfg jeffrey

Mr Bean
01.04.2008, 14:43
Hallo

Ja Schaltplan geht. Das ist der Schalplan des Experimentierboards. Über die Stiftleiste ist dann noch die 7 Segment Anzeige angeschlossen. Und im Moment noch ein Poti das das Motorrad simuliert... :-) So auf dem Schreibtisch klappt das auch wunderbar. Die Probleme treten erst dann auf wenn die Schaltung an die Motorradbatterie angeschlossen wird und das Poti durch den Gengsensor ersetzt wird.

Grüße!

Bean

Hubert.G
01.04.2008, 16:06
An Reset ein 10n nach GND.
An den Pin der beiden Tasten ein PullUp mit 1k.
In Serie zum ADC-Eingang ein 1k und vor und nachher 100n.
In die Versorgungsspannung nach der Diode eine Spule mit 100n auf jeder Seite.
Das Problem wird ja auch nur auftreten wenn der Motor läuft, diese Zündfunkenstörungen sind schwer in den Griff zu bekommen.