can virtual library be used with PID controller

Hi adelphysi,

i have already tried the pins you mentioned ( it is known that they are PMW out put on uno)

however it is not necessary to use them , i have tried that( as Joop Brooking says ^_^)

Using the 50Hz servo library is not the way to go regarding quadcopter motor output. When I started out, I made this mistake myself.

Also, Joop Brokking is using a timer, but he's manually switching the ESC ouputs in software. In Joop's video he says that this gives an accuracy of 20us. However, is not the optimal solution, as it still requires processor intervention.

Hardware PWM using analogWrite() on the other hand works independently of the CPU, so once it's been set the hardware whirs round like clockwork knocking out the PWM signal for you. This will give you PWM with 8-bit resolution.

Also, if you're using the Arduino Leonardo you can take advantage of the fact that it has two 16-bit timers: timer 1 and timer 3 with 4 output channels between them. It's possible to use register manipulation to produce 490Hz PWM signals with almost 11-bit resolution, accurate to 1uS.

Using the Leonardo, first enable digtial pins 5, 9, 10 and 11 as outpus:

// Configure the motor pins as outputs
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

Next set up the 16-bit timer in phase and frequency correct mode to operate at 490Hz:

// Initialise timers 1 and 3 for phase and frequency correct PWM
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);         // Enable the PWM outputs OC1A, OC1B and OC1B on digital pins 9, 10 and 11
  TCCR1B = _BV(WGM13) | _BV(CS11);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 1
  TCCR3A = _BV(COM3A1);                                     // Enable the PWM output OC3A on digital pin 5
  TCCR3B = _BV(WGM33) | _BV(CS31);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 3
  ICR1 = 2040;                                              // Set TOP value for phase and frequency correct PWM on timer 1
  ICR3 = 2040;                                              // Set TOP value for phase and frequency correct PWM on timer 3
  OCR1A = 0;                                                // Set OCR1A to output 0 on digital pin 9
  OCR1B = 0;                                                // Set OCR1B to output 0 on digital pin 10
  OCR1C = 0;                                                // Set OCR1C to output 0 on digital pin 11
  OCR3A = 0;                                                // Set OCR3A to output 0 on digital pin 5

Then in your loop() just load the OCRxx registers with a number between 1000 (low throttle) and (2000) high throttle.

OCR1A = 1000;
OCR1B = 1000;
OCR1C = 1000;
OCR3A = 1000;

If you require 50Hz output, for example for a tricopter analog servo then just change the ICR3 register to 20000. In this case the OCR3A register should be loaded with 1500 to centre the servo, just like the servo library's writeMicroseconds() function.

Warning: Please remove your propellers if testing this code with motors.