mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit PPM Signal


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich bin gerade dabei einen Mortorregler für ein Modellflugzeug zu bauen.
Die Schaltung ließt dazu ein PPM Signal ein und gibt ein PWM Signal für 
einen
DC Motor aus.

Wenn ich den Gasknüppel von der "Aus" Position langsam nach vorne 
schiebe, dann funktioniert alles erstmal prima. Ab einem gewissen Wert 
"springt" das eingelesene Signal (also thrust) schlagartig um etwa 15 
nach oben. Wenn ich weiter Gas gebe, springt er wieder zurück und 
funktioniert wieder ein bisschen, bis er erneut springt und so weiter. 
Interesannterweise sind die Sprünge immer an den selben Stellen (also 
bei der selben Schalterstellung).

Ich vermute mal, dass es mit dem überlauf des 8Bit-Timers zusammenhängt 
(Den 16er brauche ich für die PWM), aber ich komme nicht drauf, was 
genau es ist.
Vllt. fällt euch was ein?
(Und bei the way: wird TCNT0 automatisch auf 0 gesetzt, wenn der Timer 
wieder startet?)


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

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


volatile int up = 0;
volatile int overtime = 0;
volatile double thrust = 0;

ISR(INT0_vect){

  if(up == 0){
    TCCR0 |= (1 << CS00);
    up = 1;
    MCUCR &= ~(1 << ISC00);
  }else{
    TCCR0 = 0;
    thrust = ((overtime*256 + TCNT0) -9300)/23.6;
    TCNT0 = 0;
    overtime = 0;
    MCUCR |= (1 << ISC00);
    up = 0;  
  }  
  
}

ISR (TIMER0_OVF_vect)
{
  overtime++;
}
 
int main()
{
  //PWM Init
  DDRB |= (1 << PB1);
  TCCR1A |= (1 << WGM10);
  TCCR1A |= (1 << COM1A1);
  TCCR1B =  (1<<CS10) | (1<<CS11);
  
  //Interrupt Init
  GICR |= (1 << INT0);
  MCUCR |= (1 << ISC01);
  MCUCR |= (1 << ISC00);
  
  TIMSK |= (1<<TOIE0);
  
  sei();

  
  while(1<2){
  
    int mthrust = (int)thrust;
    if(mthrust < 0){
      mthrust = 0;
    }
    if(mthrust > 255){
      mthrust = 255;
    }
    
    OCR1A = mthrust;
    
  }

}


Vielen Dank im Vorraus
Andi

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon mal den simulator probiert ?

Autor: Peter Bünger (pbuenger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hai Andi,

Dein Programm hat einen entscheidenden Fehler: Wenn innerhalb der 
Interrupt-Routine INT0_vect der Timer überläuft, dann liest Du Müll 
zurück. Das Low-Byte aus TCNT0 ist schon übergelaufen, der Hilfszähler 
overtime für das High-Byte aber noch nicht, weil die TIMER0_OVF_vect 
erst ausgeführt wird, nachdem(!) die andere ISR fertig ist.

Und dann stellt sich die Frage, ob Floating-Point Rechnereien in der ISR 
denn wirklich nötig sind.

Peter

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daran hats gelegen, super Danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.