The code now works... two things had to be done...
- The array was incorrectly dimensioned in the beginning of the code (embarrassing)... I also changed the way the array is used in the OCR1B ISR.
- In the OCR1A interrupt routine you needs to clear the interrupt. And to clear you need to write a 1 to the corresponding bit (so I write 255 to TIFR1) before you enable the interrupts again.
The now well working code
//Convenience macros
#define TC1_ConnectToPrescaler_8 TCCR1B &= ~((1<<CS12) | (1<<CS10)) ; TCCR1B |= (1<<CS11)
#define TC1_ClearOnCompareMatchWithOCR1A TCCR1A &= ~((1<<WGM11)|(1<<WGM10)); TCCR1B &= ~(1<<WGM13); TCCR1B |= (1<<WGM12)
#define TC1_EnableInterruptOnCompareMatchWithOCR1A TIMSK1 |= (1<<OCIE1A)
#define TC1_EnableInterruptOnCompareMatchWithOCR1B TIMSK1 |= (1<<OCIE1B)
#define TC1_DisableInterruptOnCompareMatchWith0CR1B TIMSK1 &= ~(1<<OCIE1B)
const byte PPM_Pin = 12;
volatile byte PPM_Progress = 0;
volatile word CHX_Pulse[8];
void setup () {
pinMode(13,OUTPUT);
pinMode(PPM_Pin, OUTPUT);
TC1_ConnectToPrescaler_8; //1 count = 0,5 µs
TC1_ClearOnCompareMatchWithOCR1A;
TC1_EnableInterruptOnCompareMatchWithOCR1A;
OCR1A = 40000;
for (byte i = 0 ; i < 8 ; i++){
CHX_Pulse[i] = 800 + i*200;
}
}
void loop () {
}
ISR(TIMER1_COMPA_vect){
digitalWrite(PPM_Pin, LOW);
PPM_Progress = 1;
OCR1B = 800;
TIFR1 = 255;
TC1_EnableInterruptOnCompareMatchWithOCR1B;
digitalWrite(13,HIGH);
digitalWrite(13,LOW);
return;
}
ISR(TIMER1_COMPB_vect){
switch (PPM_Progress) {
case 1: case 3: case 5: case 7: case 9: case 11: case 13: case 15: case 17:
digitalWrite(PPM_Pin, HIGH);
OCR1B = OCR1B + CHX_Pulse[((PPM_Progress + 1)/2) - 1]*2;
break;
case 2: case 4: case 6: case 8: case 10: case 12: case 14: case 16:
digitalWrite(PPM_Pin,LOW);
OCR1B = OCR1B + 800;
}
PPM_Progress++;
if (PPM_Progress == 18) {
TC1_DisableInterruptOnCompareMatchWith0CR1B;
}
return;
}