The problem is at extreme duty cycles, the outputs are not correct.
When the duty cycle is 100% (255), both outputs are 1, instead of pin 9=1 and pin10=0.
Conversely, when the duty cycle is 0%, both outputs are 0, instead of pin 9=0 and pin10=1.
The intermediate values of 1-254 work fine.
May I know if this is normal and my code is correct?
To fix it, I can probably force it to the right values, e.g. if duty cycle=0, then force pin 10 to 255 & vice-versa
My code is
void setup() {
// put your setup code here, to run once:
// set the digital pin as output:
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TCCR2A = TCCR2A | B11000000; //invert OC2A pin 10 0xC0 0X30
}
void loop() {
float duty = 0; //constant for testing
analogWrite(9, duty);
analogWrite(10, duty);
}
You will not be able to use analogWrite to change the values. You will have to directly access the registers. A quick perusal of the source code will reveal why.
So if I want to increase duty cycle by using a pot, after using the forced code above, essentially pin 9 runs from 0-255, while pin 10 runs from 255, 1-254, 0 during the same period. Is this normal?
Arduino project is open source - so go and open the source and have a look...
analogWrite() configures the PWM outputs all the same, not in inverting/non-inverting
pairs, so you can't use it. Instead you just write the OCR register for that timer, perhaps here
OCR2A and OCR2B (double check, I haven't memorized the Mega timer pin assignments yet).
I took a look at the source code in the previous post but I'm not sure what to look out for.
In my first post above, I do have a line which writes directly to the register to do the inverting.
TCCR2A = TCCR2A | B11000000;
This makes pin 10 opposite of pin 9.
As I increase the analogWrite output from 0 to 255 using a pot, pin 9 works fine. The duty cycle increases.
But for pin 10, as the analogWrite output increases from 0 to 255, the extremes don't work properly, i.e. 0 & 255. The centre portion 1-254 works fine, with the duty cycle decreasing because it is inverted.
So to fix pin 10, I wrote "if" statements in post #2 to swap 0 & 255 on pin 10. So analogWrite for pin 10 runs in this order to get the decreasing duty cycle: 255, 1-254, 0.
So my question is, is the 0 & 255 extremes getting swapped normal?
If this is not the right way to do it, then what should be the right way? Sorry, I am a newbie, could you provide a bit more detailed answers? Thanks.
Other posters have tried to point you at the source code for analogWrite(). If you had looked at it, you would have seen that analogWrite(pin,0) actually calls digitalWrite(pin,LOW); and analogWrite(pin,255) calls digitalWrite(pin,HIGH). At the extremes, the timer settings are not used. This was done sometime in the past to fix a bug where analogWrite(pin,0) put out a short pulse of a single clock cycle.
Check the datasheet of the micro. I know the datasheet for the 328 has some information about special cases at the extremes (0 and 255); the behaviour is normal depending the timer and mode that you use.
Can't help further, unfortunately.
//Edit
I see that cattledog posted while I was typing so the above might not be applicable; interesting read none-the-less