Für ungeduldige Leser sei vorweg gesagt: ES ZAPPELT IMMER NOCH !.
Es ist zum Haare raufen ......
Ich habe mir dieser Tage mal ein paar INO's vom MultWii reingespannt.
Die Leseroutine des PPM-Signals machen die genau wie ich (ich hab nicht abgeguckt !). Einfach ein attachinterrupt() und die micros() ausgewertet. Also nix besonderes.
Zum Betreiben der ESC/Servos gibt es einen Mix aus "direkt schreiben" oder ala Servo-Lib mit umgedängelten Pins.
Da das mit der Servo-Lib ja hier nicht läuft, weil eine zusätzliche ISR möglicherweise durch die PPM-ISR gestört wird, habe ich mir gedacht, nimmst du halt alle freien Timer des MEGA und machst dir 9 Servokanäle max. mit Fast-PPM auf Hardware-Basis.
In etwa so:
(diesmal richtig !)
void setup()
{
.....
// Setup pins & timer for servos
pinMode(3,OUTPUT); // timer 3 channel A
pinMode(2,OUTPUT); // timer 3 channel B
pinMode(5,OUTPUT); // timer 3 channel C
pinMode(6,OUTPUT); // timer 4 channel A
pinMode(7,OUTPUT); // timer 4 channel B
pinMode(8,OUTPUT); // timer 4 channel C
pinMode(46,OUTPUT); // timer 5 channel A
pinMode(45,OUTPUT); // timer 5 channel B
pinMode(44,OUTPUT); // timer 5 channel C
// ATMEL Doku MEGA: http://www.atmel.com/images/doc2549.pdf
// 17.9 Modes of Operation, Seite 148 ff
// ! ! ! http://www.mikrocontroller.net/topic/177721 ! ! !
// Modus 14: Fast PWM - Steuerung des Ausgangsport: Set at BOTTOM, Clear at match (Tabelle 17.2)
// -> WGMn1, WGMn2, WGMn3
// PreScaler: clk/8 -> CSn1 -> "Tick" = 0.5µs (alle ICR-/OCR-Werte x 2 !!!)
// Zu setzen in TCCRxA: COMnA1, COMnB1, COMnC1 für alle 3 Compare-Out-Pins
// WGMn1
// Zu setzen in TCCRxB: WGMn2, WGMn3, CSn1
// Zu setzen ICRn: 40000 für Wiederholfrequenz 50Hz 20ms (6666/150Hz, 3333/300Hz)
// Zu setzen OCRnA/B/C: PPM-Signal x 2 (angepasst mit map für min./max. Servoweg)
rep_rate = 40000; // div 2 = 20000 µs = 20 ms = 50 Hz
val_mid = 3000; // div 2 = 1500 µs = 1,5 ms = Servo-Mittelstellung
// init 16bit timer 3 - connect pin 5, 2, 3
TCCR3A = (1<<COM3A1) | (1<<COM3B1) | (1<<COM3C1) | (1<<WGM31);
TCCR3B = (1<<WGM33) | (1<<WGM32) | (1<<CS31);
ICR3 = rep_rate;
OCR3A = OCR3B = OCR3C = val_mid;
// init 16bit timer 4 - connect pin 6, 7, 8
TCCR4A = (1<<COM4A1) | (1<<COM4B1) | (1<<COM4C1) | (1<<WGM41);
TCCR4B = (1<<WGM43) | (1<<WGM42) | (1<<CS41);
ICR4 = rep_rate;
OCR4A = OCR4B = OCR4C = val_mid;
// init 16bit timer 5 - connect pin 46, 45, 44
TCCR5A = (1<<COM5A1) | (1<<COM5B1) | (1<<COM5C1) | (1<<WGM51);
TCCR5B = (1<<WGM53) | (1<<WGM52) | (1<<CS51);
ICR5 = rep_rate;
OCR5A = OCR5B = OCR5C = val_mid;
}
Die Pulsbreite wird dann in der Loop mit jeweils anderen Werten für OCRnA/B/C gesetzt.
Das funktioniert wie ne "1", wenn man z.B. mit nem Poti Werte vorgibt und die passend mit map() aufbereitet.
Aber ...........
Wie oben schon gesagt: Kommt das PPM-Signal hinzu, ist wieder Ende im Gelände !
... der/die Servos zappel wieder.
HEUL. :~
Hat das doch was mit der Hardware zu tun ?