PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Software PWM für 4 Motoren (Quadrocopter) auf ATMega8



zitrone18
15.12.2011, 22:11
N'abend zusammen,

im Moment baue ich einen Quadrocopter.

Auf der Hauptplatine befindet sich ein ATMega8 ein SPI 433Mhz Funkmodul und ein 3-Kanal G-Sensor.
Alles bis auf die Ansteuerung der 4 Motoren funktioniert.

Der bisher geschriebene Code sieht so aus:

Taktfrequenz: 16Mhz



#define running 1
//Motoren
#define VORNE 1<<PD5
#define LINKS 1<<PB0
#define RECHTS 1<<PC5
#define HINTEN 1<<PC0

#define VORNE_EIN PORTD|=VORNE;
#define VORNE_AUS PORTD&=~VORNE;
#define LINKS_EIN PORTB|=LINKS;
#define LINKS_AUS PORTB&=~LINKS;
#define RECHTS_EIN PORTC|=RECHTS;
#define RECHTS_AUS PORTC&=~RECHTS;
#define HINTEN_EIN PORTC|=HINTEN;
#define HINTEN_AUS PORTC&=~HINTEN;

//PWM TIMER
volatile int iValVorne = 0;
volatile int iValLinks = 0;
volatile int iValRechts = 0;
volatile int iValHinten = 0;
int pwmCount = 0;
int pwmStep = 0;

#define TIMERVALUE_0 235 //235 mit Vorteiler 8 (20 Steps = 10us)
#define VORTEILER_0 0b00000010 //Vorteiler: 8

int main( void )
{
//Timer initialisierung
// Timer 0 konfigurieren
TCCR0 = VORTEILER_0; // Prescaler 8
// Overflow Interrupt erlauben
TIMSK |= (1<<TOIE0);
TCNT0 = TIMERVALUE_0;

//Ports definieren
DDRB |= 0b11000011;
DDRC = 0b11100011; // Port C als Eingang
DDRD = 0b11111111;

//PWM-Werte einstellen
iValVorne,iValLinks,iValRechts,iValHinten = 0;

VORNE_AUS LINKS_AUS RECHTS_AUS HINTEN_AUS

sei(); //Interrupts starten

//Startsequenz der Motoren
_delay_ms(1000);

iValRechts = 100;
iValLinks = 100;
iValVorne = 100;
iValHinten = 100;
_delay_ms(200);

iValRechts = 0;
iValLinks = 0;
iValVorne = 0;
iValHinten = 0;
_delay_ms(1000);
//Startsequenz ENDE

// Hauptschleife des Programms
while ( running )
{

}
}

/* ################################################## ############################## */
/* ############################# Timer ######################################## */
/* ################################################## ############################## */
ISR(TIMER0_OVF_vect)
{ TCNT0 = TIMERVALUE_0;
// 20us
if(pwmStep == 0) { //1. ms
HINTEN_EIN
VORNE_EIN
LINKS_EIN
RECHTS_EIN
}
if(pwmStep == 1){ //2. ms

if(pwmCount==iValVorne) VORNE_AUS //else VORNE_EIN
if(pwmCount==iValLinks) LINKS_AUS //else LINKS_EIN
if(pwmCount==iValRechts) RECHTS_AUS //else RECHTS_EIN
if(pwmCount==iValHinten) HINTEN_AUS //else HINTEN_EIN
}
if(pwmStep > 1){ //3. bis 20. ms
HINTEN_AUS
VORNE_AUS
LINKS_AUS
RECHTS_AUS
}
if(pwmCount++ == 99){
if(pwmStep++==19){
pwmStep = 0;
}
pwmCount = 0;
}
}


Die Startsequenz funktioniert.
Wenn ich einen Wert in iValHinten stecke, fängt der Brushlessregler an zu Piepsen (Break->Fehlerhaftes Signal)
Bei allen anderen Ansteuerungen funktioniert.
Wenn ich alle anderen Motoren rausnehme und nur den hinteren Motor ansteuere, dann funktioniert das ganze.
Ich würde sagen, dass es dadurch nicht an der Hardware liegt (Kalte Lötstellen etc.)

Sieht vllt. einer von euch einen Fehler in der Ansteuerung???

Über Hilfe würde ich mich sehr freuen :D
Danke und Gruß,
Zitrone

zitrone18
30.12.2011, 12:38
Hi ich nochmal,

der Fehler liegt in diesem Block:



//Motoren
#define VORNE 1<<PD5
#define LINKS 1<<PB0
#define RECHTS 1<<PC5
#define HINTEN 1<<PC0


die jeweiligen Ausdrücke müssen geklammert werden.

So muss es aussehen.




//Motoren
#define VORNE (1<<PD5)
#define LINKS (1<<PB0)
#define RECHTS (1<<PC5)
#define HINTEN (1<<PC0)



Gruß
Zitrone

radbruch
30.12.2011, 13:08
Der "Fehler" liegt wohl eher hier:

#define VORNE_AUS PORTD&=~VORNE;

Nach der Ersetzung durch den Preprozessor würde das dann so aussehen:

#define VORNE_AUS PORTD&=~1<<PD5;

Die Bindung der Tilde ~ an die 1 ist größer als bei Shift:

http://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit% C3%A4t

Das vermute ich mal als Ursache. Im Zweifel immer klammern!

Gruß

mic