Frequency Question

Hi,

I have an ArduPilot Legacy board.
It has been made a PCB for it, and it's using the the third timer for generating frequencies (pins 3 and 11). The idea is that when I made the PCB, I tought that the non-exactly frequency the Arduino is giving won't make my motors work abnormally.

What I need is an exact frequency of 10kHz (for my motor controllers).

The question is how do I set them to this fixed frequency? Plus, I need to send the pulse at a certain duty cycle. For example 30%, or 21%. Do I have to use another function than analogWrite(), just because is a particular frequency? How?

Unfortunately, I'm a beginner in terms of timers, so sorry me for this question which might be trivial.

Thank you,
RobertEagle

You could use timer 1 (which outputs to pins 9 and 10). With PWM mode and counting up to 1600 and a prescaler of 1 you would get a frequency of 10 KHz exactly.

Or Timer 2 (which outputs to pins 3 and 11) with a prescaler of 8 and counting up to 200 you would also get a frequency of 10 KHz.

The problem is that for a frequency of exactly 10 KHz you need both sides of the timer (the A and B side) where the A side counts up to the required figure (eg. 1600 or 200) and the B side gives you the duty cycle. So you might need to use pins 3 and 10 (the B side outputs).

The resolution of the duty cycle has to fit into the count. In other words, with timer 2 the duty cycle will be in the range 0 to 199 which would give you a 0.5% duty cycle resolution.

I have some example code on this page:

Near the bottom where it says "Modulating 38 KHz signal" is an example of generating 38 KHz frequency with a variable duty cycle. You just have to change one constant to change from 38 KHz to 10 KHz.

I did understand how the frequency is being calculated.
I have changed some things from that particular sketch (which was including a 38kHz signal, along with duty cycle).

Is this how it should like? I want to specify that I need timer2 which is using pins 3 and 11 on the Arduino.

// 16 MHz clock divided by 10 KHz frequency desired
const long timer2_OCR2A_Setting = 16000000L / 10000L;

void setup() 
 {
  pinMode (11, OUTPUT);
  pinMode(3,OUTPUT);

  // set up Timer 2 - gives us 10 KHz 
  TCCR2A = _BV (WGM10) | _BV (WGM11) | _BV (COM1B1); // fast PWM, clear OC1B on compare
  TCCR2B = _BV (WGM12) | _BV (WGM13) | _BV (CS21);   // fast PWM, 8 prescaler
  OCR2A =  timer2_OCR2A_Setting - 1;                 // zero relative  
  OCR2B = (((long)(0) * timer2_OCR2A_Setting) / 1024L) - 1;//initialize with 0
  OCR2A = (((long)(0) * timer2_OCR2A_Setting) / 1024L) - 1;//initialize with 0
  }

void loop()
  {
  OCR2B = (((long)(analogRead..etc) * timer2_OCR2A_Setting) / 1024L) - 1;
  OCR2A = (((long)(analogRead..etc) * timer2_OCR2A_Setting) / 1024L) - 1; 
  }

PS: What's the purpose with those float types typed in the OCR2A and B? What does it do?
Plus I can't change the pins. They must be 3 and 11.

Does anybody know how? I just need a ,,quick and dirty" fix. It's quite urgent for me. And how I said, there are some fixed pins. Pins 3 and 11 working with timer2.

Thank you in advance,
RobertEagle

PS: What's the purpose with those float types typed in the OCR2A and B? What does it do?

There are no float types in OCR2A and B, what makes you think there are?

Plus I can't change the pins. They must be 3 and 11.

Yes that is right the hardware timers are attached to fixed pins, there is no way to change them.

Hi,

I have this setup on timer2:

  1. TCCR2A - COM2A1 and COM2B1 are set on non-inverting mode, WGM20 and WGM21 are set on Fast PWM(mode 3, TOP at 0xFF,Update at BOTTOM, and TOV flag set on MAX)

  2. TCCR2B - CS21 with prescaler set at 8

  3. TCNT2 set at 200

  4. OCR2n registers for the duty cycle.

This configuration should give a frequency of 10Khz=16000000/8(prescaler)/200(counter value).

This is my code:

void setup()
{
 pinMode(3,OUTPUT);
 pinMode(11,OUTPUT);
 TCCR2A = _BV(COM2A1) | _BV(COM2B1)|_BV(WGM20)|_BV(WGM21);
 TCCR2B = _BV(CS21);
 TCNT2=200;
}
void loop()
{
  OCR2A=75;//random value
  OCR2B=190;//random value
}

I have uploaded the code onto the Arduino, and checked with the multimeter the ,,voltage". At 200, instead of giving me 5V it gave me 3.92V, situation which was telling me that the value stored in TCNT2 wasn't considered.

What could be the solution here? What is wrong with me setting?

And referring my last reply, it was deleted because it had too many errors in what it was saying.

Thank you, again,
RobertEagle

Move all the code into setup, do not keep reloading those values rapidly with loop. A multimeter will not work with a PWM signal.

1.Well, the duty cycle must be variable, as I said, I have to drive 2 motors using 2 ESC's(controllers).

2.How am I going to control the motors then if I move all the code into setup?

3.On a multimeter's screen will appear a sort of ,,voltage", which is the average of the duty cycle on that period.

RobertEagle:
1.Well, the duty cycle is variable, as I said, I have to drive 2 motors using 2 ESC's(controllers).

Most ESCs interface with an arduino as a servo device and as such one uses the servo library to control them. Why are you using low level timer commands to try and control the ESC. Perhaps if you posted a link to your ESC controller we would know more about your requirments and best solutions?

2.How am I going to control the motors then?
Again the servo library may be what you should be using?

3.On a multimeter's screen will appear a sort of ,,voltage", which is the average of the duty cycle on that period.

Only if your DMM is of a 'true RMS' type (more expensive models have this feature) you won't get accurate values using simple DC voltage reading on a PWM signal.

1.My ESCs are Roxxy Robbe BL Control 710 and work with Roxxy Robbe 2216/25 Motors.

2.This is the official page of the ESC:
http://www.robbe.de/roxxy-blcontrol-710.html

And this is the only datasheet of the ESC:
http://www.4shared.com/office/IWZkRgDo/Anleitungen_INT_A_8637_8638_BL.html

3.Isn't the servo library too slow?

RobertEagle:
1.My ESCs are Roxxy Robbe BL Control 710 and does work with Roxxy Robbe 2216/25 Motors.

2.This is the official page of the ESC:
http://www.robbe.de/roxxy-blcontrol-710.html

Looks like a standard R/C type motor speed controller designed to interface as a servo device to me.

And this is the only datasheet of the ESC:
http://www.4shared.com/office/IWZkRgDo/Anleitungen_INT_A_8637_8638_BL.html

3.Isn't the servo library too slow?

No, your confusing the 10KHz switching rate the ESC uses to drive the three motor windings attached to it. The command inputs the ESC needs to control the motor are standard 1-2 millisec pulses at a 20-25millisec frame rate, just like all standard R/C servos and ESC controllers. Use the standard Arduino servo library. You will have to find out what the proper 'arming sequence' for the ESC before it will enable output commands to the motor, a standard 'safety feature', and this can vary amoung ESC manufactures.
Lefty

  1. So how can I find the real ESC input frequency?
  2. Does the duty cycle of the ESC need to be incremented sequentially or is it just possible to directly switch from 0 to max 255?
  3. I tried last week at 490Hz and they worked very badly. The motors were responding very hard, and since than I tried to find another solution. And sadly, the motors worked only by incrementing the duty cycle with one.
  4. It means that these ESC's aren't designed for acrobatic maneuvers?
  1. You don't have to find the input frequency, servo library will take care of that (btw, its ca 50HZ)
  2. You control the ESC, just like a servo, take a look at the servo knob/sweep example sketch
  3. se 2
  4. I dont know why it should not work with acrobatic maneuvers, but as it is designed for about 100W motor (3 lipo's at 10A), it should be a leightweight plane if you want to do any serius 3D flying.

The arming sequence that Lefty mentioned can be found here

http://www.produktinfo.conrad.com/datenblaetter/200000-224999/206291-an-01-ml-ROXXY_BLUSHLESS_CONTROL_710_de_en_fr.pdf

RobertEagle:

  1. So how can I find the real ESC input frequency?

Why do you need to know this? The arduino standard servo library handles those low level details and continously sends the last servo.write command you sent at the rate the servo is designed to handle. Using the myservo.writeMicroseconds(xxxx); you get at least 1,000 counts of resolution (1000-2000usec) of speed control representing 0-100% rpm from the motor.
Servo - Arduino Reference

  1. Does the duty cycle of the ESC need to be incremented sequentially or is it just possible to directly switch from 0 to max 255?
    Direct commands to any value within range and the servo library allows much more then 256 counts of resolution as already stated above.
  2. I tried last week at 490Hz and they worked very badly. The motors were responding very hard, and since than I tried to find another solution. And sadly, the motors worked only by incrementing the duty cycle with one.

**That's because were not using the standard servo library commands to control your ESC and you probably not correctly simulating what a proper servo command pulse looks like? Again use the servo library to control your ESC, to resist is futile. :wink: **
4. It means that these ESC's aren't designed for acrobatic maneuvers?

Airframe, motor power, and pilot skill is the limiting factor in acrobatic maneuvers, not the servo command rate to the ESC.
Lefty

My idea was to make another library, which had to be more efficient in terms of cpu usage.

What I have designed is a testing board (which I'll post after I finish the 1st stage, the motors and the equilibrium library). To start, I've used just 2 of the 4 motors I have for testing. Later, I'll make a quadcopter having a maximum of 550-600 grams. And my target is to make the quadcopter super responsive to stimuli. And you know how frustrating is to know that the motors don't work after 350 hours of total work?

That's why I wasn't thinking at the Servo library. I thought it was too slow.

I'll post later the results of using the Servo library.

Thanks,
RobertEagle

RobertEagle:
My idea was to make another library, which had to be more efficient in terms of cpu usage.

What I have designed is a testing board (which I'll post after I finish the 1st stage, the motors and the equilibrium library). To start, I've used just 2 of the 4 motors I have for testing. Later, I'll make a quadcopter having a maximum of 550-600 grams. And my target is to make the quadcopter super responsive to stimuli.
That's why I wasn't thinking at the Servo library. I thought it was too slow.

Well the ESC cannot accept new valid speed commands faster then it's 50Hz frame rate allows so the servo library will not be the limiting factor of how responsive motor commands will be, your sketch loop rate will probably be the limiting factor.

I'll post later the results of using the Servo library.

Good luck on your project.
Lefty

Thanks,
RobertEagle

1.My ESCs are Roxxy Robbe BL Control 710 and work with Roxxy Robbe 2216/25 Motors.

Unless your ESCs are some strange beasts, they are not going to run at 10Khz. They usually take 20ms signal (20hz).

If that is the case, you can easily replicate such a thing via software. A few possibilities:

  1. the simplest would be polling: set up a free running 20ms timer. in the loop, read the timer and set / clear output pins based on the value of the timer and your desired duty cycle. This is the simplest to code but sucks all processor power and may have some jitter.
  2. or you can use software timers. st up a timer to run the duty cycle; on up the isr, reload the timer with 20ms - duty cycle, and then set / clear pins.
  3. use three hardware timers. You can use either the OCnA/B/C pins, or user-specified pins.

The last approach is the best but requires 3 timers.

dhenry:

1.My ESCs are Roxxy Robbe BL Control 710 and work with Roxxy Robbe 2216/25 Motors.

Unless your ESCs are some strange beasts, they are not going to run at 10Khz. They usually take 20ms signal (20hz).

If that is the case, you can easily replicate such a thing via software. A few possibilities:

  1. the simplest would be polling: set up a free running 20ms timer. in the loop, read the timer and set / clear output pins based on the value of the timer and your desired duty cycle. This is the simplest to code but sucks all processor power and may have some jitter.
  2. or you can use software timers. st up a timer to run the duty cycle; on up the isr, reload the timer with 20ms - duty cycle, and then set / clear pins.
  3. use three hardware timers. You can use either the OCnA/B/C pins, or user-specified pins.

The last approach is the best but requires 3 timers.

And why would not just using the standard Arduino servo library not be the best solution? Curious minds would like to know. :wink:

Lefty

And why would not just using the standard Arduino servo library not be the best solution? Curious minds would like to know

I can see one reason, which by the way do not aplly to this ESC, and that is the fact that some servo's and ESC's are designed for faster refresh rates than the 50Hz used by most standard servos.

For example servos to control the tailrotor on helicopters, and ESC's to multicopters use a higher resfreshrate (200-400 HZ), because they have to respond more quickly

Can you give me an example of these? Like a project of somebody's..or something like that?
And if you're proving that you're right, how far can it go with the frequencies?