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.
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.
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)
TCCR2B - CS21 with prescaler set at 8
TCNT2 set at 200
OCR2n registers for the duty cycle.
This configuration should give a frequency of 10Khz=16000000/8(prescaler)/200(counter 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.
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.
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
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?
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.
It means that these ESC's aren't designed for acrobatic maneuvers?
You don't have to find the input frequency, servo library will take care of that (btw, its ca 50HZ)
You control the ESC, just like a servo, take a look at the servo knob/sweep example sketch
se 2
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
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
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.
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. **
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.
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.
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:
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.
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.
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.
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:
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.
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.
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.
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?