Problem with PWM code for controlling ESCs for motors

I am writing code to output PWM signals from my Arduino Mega. I need a PWM signal that refreshes on the order of 300Hz for my quadcopter. I can't use the Servo.h library because that only works at 50Hz, and besides, I don't want to modify it because I would like to be able to use the servo library as well. So far my Motor class works perfectly, except for some reason it doesn't work on pin 8. I am using timer3 and timer4 so I thought it should work for pins 2,3,5,6,7,8, and it works for everything except pin 8. I don't have an oscilloscope so I can't really check what it is doing for pin 8, though connecting an LED, it "appears" to be changing the pulse width. Please let me know how I can fix this.

This is my <Motor.h> file:

#ifndef _Motor_h
#define _Motor_h

class Motor{
public:
	Motor();
	void attach(int port);
	void write(int n);
private:
	int pin;
};

#endif

This is my <Motor.cpp> file:

#include <Arduino.h>
#include <Motor.h>

Motor::Motor(){
}

void Motor::attach(int p){
	TCCR3A =((1<<WGM31)|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1));
	TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS30); 
	TCCR4A =((1<<WGM41)|(1<<COM4A1)|(1<<COM4B1)|(1<<COM4C1)); 
	TCCR4B = (1<<WGM43)|(1<<WGM42)|(1<<CS40); //Set timer divider to 1;
	ICR3 = 53333; //300Hz Refresh rate
	ICR4 = 53333;
	if(p!=2 && p!=3 && p!=5 && p!=6 && p!=7 && p!=8){
		Serial.println("Error: Motors can only be attached to pins 2,3,5,6,7,8.");
	}
	else{
		pin = p;
		pinMode(pin, OUTPUT);
		write(0);
	}
}

void Motor::write(int n){
	n = min(1000, n);
	n = max(0, n);
	n = (n+1000)*16;
	if(pin == 2) OCR3B = n;
	else if(pin == 3) OCR3C = n;
	else if(pin == 5) OCR3A = n;
	else if(pin == 6) OCR4A = n;
	else if(pin == 7) OCR4B = n;
	else if(pin == 8) OCR4C = n;

}

And this is my Arduino sketch to test if it is working:

#include <Servo.h>
#include <Motor.h>

Motor motor;

void setup(){
    motor.attach(8);
    motor.write(200); //1200us pulse to get motor going
    delay(500);
    motor.write(0); //1000us pulse to stop motor  
}

void loop(){}

What ESC are you using? Why do you think it needs a 300 Hz update cycle?

	TCCR3A =((1<<WGM31)|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1));
	TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS30); 
	TCCR4A =((1<<WGM41)|(1<<COM4A1)|(1<<COM4B1)|(1<<COM4C1)); 
	TCCR4B = (1<<WGM43)|(1<<WGM42)|(1<<CS40); //Set timer divider to 1;

What about the other 4 or 5 bits for each byte?

I'm using a Turnigy Plush 30A. It probably only needs to update at around 100Hz, but I thought faster couldn't hurt. It seems like most ESC's support close to 400Hz.

I'm not quite sure what's happening there. I looked at the AVR datasheet, but I couldn't quite tell what it was doing. That could be the problem. I took that part from the PWM output from the Aeroquad source code.

PaulS:
What about the other 4 or 5 bits for each byte?

I hadn't spotted that. It's why I don't like that "WGM31" etc approach to setting bits. Its much clearer with an 8-bit binary value.

...R

yutowatanabe:
I'm using a Turnigy Plush 30A. It probably only needs to update at around 100Hz, but I thought faster couldn't hurt. It seems like most ESC's support close to 400Hz.

People out there say the Plush can accept the higher update rate, but there's some reports of problems with 400Hz and that person had to back it down to 350Hz... however, it seems that it is doing this by simply ignoring most of the data. I know that there is a large contingent in the multi-rotor community who are saying crazy things like it's impossible to fly with 50Hz updates, but I gotta say, those people are just plain wrong. They are ignoring facts of the physics about motors - your motor can not change speed in 1/400th of a second. It can barely make a significant speed change in 1/50th of a second, so updating it faster than that is just wasting data and time you could be doing something else.

I would not use a Plush on any of my multi-copters - it's really designed for planes. On my multi-copters I use DJI Opto and HK Afro. Those are designed for use with multi-copters and they have some features which work a little better - such as 'no low-voltage cutoff' which can crash your copter if the different ESCs cut out at different voltages.

I can't read spanish so I might be wrong about this, but this seems to illustrate that 50Hz response isn't that great? Not saying that it's impossible to fly, but the 400Hz looks much better.

yutowatanabe:
I can't read spanish so I might be wrong about this, but this seems to illustrate that 50Hz response isn't that great? Not saying that it's impossible to fly, but the 400Hz looks much better.
https://www.youtube.com/watch?v=6EM7Xx3QEE0

Theoretically, being able to respond infinitely fast is the best way to run things, but there is a practical limit to what will be effective on the motor end, and the law of diminishing return comes into play. I think it's probably advantageous to go to the highest rate you can, but I'm extremely skeptical at the value of going really fast with it, and I know for a fact that 50Hz is fine in many situations.

If we run some quick numbers, you can see we cross some lines...
Props never really run faster than 10,000 rpm - and in most cases they run a lot slower than that, but lets' use the high end just to be sure. 10K RPM is 166 rotations per second. Most of the time, the motor speed is the same as the prop speed (only micro quads use gear drives usually).

So... if you updated at 50Hz, you're a little slow - it takes 3 rotations before the motor can respond.
I you try to update at 400 Hz, you're trying to change the speed of the motor 2.4 times in one rotation. That is pointless.

I know what people are saying about ridiculous update rates these days and I think it's hogwash. That's just a personal opinion, but like I said, you get into the realm of things that don't matter any more, and I think a lot of the claims of being able to see performance differences with super high update rates are... well... they are confirmation bias. If I spent time flashing firmware and money buying the right ESCs and my copter still flew ok, I would probably think it was better even if it wasn't.

So, what I'm saying is, don't put a lot of energy toward trying to get really high update rates, put your efforts toward solid, fault-free code. Quads can fly fine on a 50Hz update rate. I'm pretty sure all of mine are using it, and they run heavy outrunners with big props so they can't accelerate and decelerate that quickly anyway. All my aircraft are stable - one KK hex-copter 550, one APM hex-copter 550, one KK quad 450, and 4 RTF quads of various sizes. I use DJI Opto ESCs, and Afro ESCs, and the Blade has Blade ESCs I guess - pretty sure they are all running at the 50Hz update rate.

Here's videos... tell me if you don't think these are stable enough. Keep in mind, my dumb ass is flying them :slight_smile:

This one flies better after I tuned it up, but it's fine with no tuning at all. The APM hex-copter is almost exactly the same but it has DJI ESCs instead of Afro.

This is video from a hard-mounted GoPro on my 450 Quad - it's pretty stable I think. I made it through the gate :slight_smile: