I'm using the Registers of the Arduino micro to get a signal for Electronic Speed Controllers (ESC) for brushless motors. The idea is comming from the Multiwii project/various other online sources.
I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correct, please help me out here.
So I set the Registers DDR (to set the pin as output), TCCR1A and TCCR1B and ICR1 (TOPvalue = 2048 = 0x800).
Now using OCR1A = 1000 should give me a pulse width of 1000ms at a sample rate of 488.28Hz. This is the expected or target behaviour.
The minimal not working code is:
// using a 16-bit timer to generate PWM signals for ESCs
// Phase Correct Mode counts from Bottom to Top and back to Bottom
// setting the range to (BOTTOM) 0 - 2048 (TOPvalue)
// we need a prescaler of 8 to get 488.28 Hz
// which is max, since 2000 is nearly full dutycycle
// Motor signal (OCRnx) uses values of 1000-2000
// which directly corresponds to microseconds HIGH-time
// n = number of timer (1,3)
// x = A,B,C
uint16_t dutytime = 1000;
void setup(void) {
// TIMER 1
// TIMSK1 = 0; // disable Interrupts for timer1
DDRB |= (1<<DDB5); // D9 Output
DDRC |= (1<<DDC6); // D5 Output
// bits 7,5,3 PWM Output on pins A,B,C respectively
// bits 1,0 WGM_1,0: phase correction mode
TCCR1A |= 0x82; //0xAA for all 3 = 0b 1010 1010
// bit 4,3 WGM_3,2: phase correction mode
// bits 2,1,0 Prescalar: 8
TCCR1B |= 0x12; // 0b 0001 0010
ICR1 = 0x800; // TOPvalue = 2048
// TIMER 3
// TIMSK3 = 0; // disable Interrupts for timer3
// bit 7 PWM Output on pin A
// bits 1,0 WGM_1,0: phase correction mode
TCCR3A |= 0x82; // 0b 1000 0010
// bit 4,3 WGM_3,2: phase correction mode
// bits 2,1,0 Prescalar: 8
TCCR3B |= 0x12; // 0b 0001 0010
ICR3 = 0x800; // TOPvalue = 2048
OCR1A = dutytime;
OCR3A = dutytime;
// delay(1000);
}//setup
void loop(void) {
while (dutytime < 2000) {
dutytime += 10;
OCR1A = dutytime;
OCR3A = dutytime;
delay(1000);
}
while (dutytime > 1000) {
dutytime -= 10;
OCR1A = dutytime;
OCR3A = dutytime;
delay(1000);
}
}//loop
I repeated the settings for timer3 to get something to compare to. Both do give the same: if i delete the loop and just write loop{} nothing happens. The pins are high and seem to stay so. With the while loops activated, my multimeter gives me 1Hz (which are the changes of course) and between 99.9% duty cycle and 96%.
An led, which i connected to it blinks every second a very short time.
What am I doing wrong?