Hi Marco,
I think that is because servo.h use timer1...
Yes, you're right. I overlooked the fact that the servo library uses timer1. This is also the reason why analogWrite() on pins 9 and 11 (which also uses timer1) didn't work.
To overcome this it's necessary to use the 8-bit timer2 for your motors and the 16-bit timer1 for your servos. This is because only timer1 is capable of phase and frequency correct PWM that allows you to set the frequency at 50Hz for your servos.
Timer2 on the other hand can only operate in phase correct PWM, which can be set at 490Hz that's suitable for your motor ESCs.
To convert timer1 for servo operation at 50Hz just change the ICR1 register from 2500 to 20000. Load the OCR1A and OCR1B registers with 1500 to centre the servos. Here's the code, it's identical to the previous code except that I've changed the ICR1 register to 20000:
void setup() {
// Initialise timer 1 for phase and frequency correct PWM at 50Hz on digital pins D9 and D10
pinMode(9, OUTPUT); // Set digital pin 9 (D9) to an output
pinMode(10, OUTPUT); // Set digital pin 10 (D10) to an output
TCCR1A = _BV(COM1A1) | _BV(COM1B1); // Enable the PWM outputs OC1A, and OC1B on digital pins 9, 10
TCCR1B = _BV(WGM13) | _BV(CS11); // Set phase and frequency correct PWM and prescaler of 8 on timer 1
ICR1 = 20000; // Set the PWM frequency to 50Hz
OCR1A = 1500; // Centre the servo on D9 and D10
OCR1B = 1500;
}
void loop() {
OCR1A = 1300; // Move the servo on D9 and D10
OCR1B = 1300;
delay(1000); // Wait for 1 second
OCR1A = 1700; // Move the servo on D9 and d10
OCR1B = 1700;
delay(1000); // Wait for 1 second
}
For the your motors, either use analogWrite() function on digital pins D3 and D11, or use the following code that sets up timer2 for phase correct PWM at 490Hz on D3 and D11:
// Set up timer 2 to output 490Hz, 8-bit resolution PWM on pins D11 and D3
void setup() {
pinMode(11, OUTPUT); // Set digital pin 11 (D11) to an output (OC2A)
pinMode(3, OUTPUT); // Set digital pin 3 (D3) to an output (OC2B)
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20); // Enable phase correct PWM outputs OC2A and OC2B on digital pins D11 and D3
TCCR2B = _BV(CS22); // Set the prescaler to 64 on timer 2
}
void loop() {
OCR2A = 125; // Set motor ESCs to standby at 1000us pulsewidth
OCR2B = 125;
delay(2000); // Wait for 2 seconds
OCR2A = 150; // Set motor ESCs to idle up at 1200us pulsewidth
OCR2B = 150;
delay(2000); // Wait for 2 seconds
}
Note that for the motors you'll have to map your 0us to 2000us ESC pulses to 0 to 255, as timer2's only 8-bit.
The reason for all this, is the fact that the Arduino Nano's Atmel 328P microcontroller has only one 16-bit timer (timer1) with 2 output channels.
Alternatively, you could consider the Arduino Micro with its Atmel 32U4 microcontroller. This has two 16-bit timers (timers1 & 3) with 4 output channels and would give you higher a 11-bit resolution PWM for your motors, in addition to your servos. (The disadvantage of the Arduino Micro is that it only has a limited number of interrupt pins).
That being said, the Arduino Nano's been successfully used in a lot of multi-rotor projects.