hi , can someone please explain to me how I could do an analogWrite directly. below is the part of my code im trying to change bt im not sure how to do the analoguwrite ones.
#define A 2 #define B 4 #define PWM1 9 #define C 7 #define D 8 #define PWM2 10
The analogue write is not a direct mapped register function like a digital write.
There is no simple equivalent.
With digital write all you have to do is to set a bit in a register. With analogue write (poor name because it produces PWM ) you have to set up many registers in the counter timer blocks, there is no great speed up in doing this directly because that is what the C function does.
hi mike , thanks for replying .. i wanted to do that because at the moment im using digitalWrite and its taking very long for motors to respond at given inputs.. any alternative method i can use ?
There is a nice compromise - call analogWrite once in setup for each PWM pin
you want to use, thereafter directly write the relevant output-compare-register.
For the Uno and other 328-based Arduinos that means:
OCR0A = val ; // analogWrite (5, val)
OCR0B = val ; // analogWrite (6, val)
OCR1A = val ; // analogWrite (9, val)
OCR1B = val ; // analogWrite (10, val)
OCR2A = val ; // analogWrite (11, val)
OCR2B = val ; // analogWrite (3, val)
If you call digitalWrite() on one of the pins you'll have to call analogWrite() again
to set it up for PWM again.
Sorta dumb question but is the above a TIMER implementation of PWM on a digital pin ?
not sure what you mean but that is all PWM is anyway. It is one of the timer modes that allows a pin to be toggled automatically. You can use two pins per timer and the number of the pin to use is wired into the hardware. When you call analogWrite it sets up all the other things concerned with the timer like the prescale ratio, the clock source, the value in the counter register, the value in the compare register (that is the actual value duty cycle value ) and switches the pin to toggle on each compare and disables the interrupt when the compare is triggered and sets the timer mode.
By calling analogWrite in the setup you set all these things up. Then when you want to change the value of the duty cycle you simple use one of those lines. This will speed things up. If you ever call digitalWrite, that messes up these values and the have to be set up again. So you must call an analogWrite again so that those single line pokes work.
young14:
i wanted to do that because at the moment im using digitalWrite and its taking very long for motors to respond at given inputs.. any alternative method i can use ?
Basically as LarryD said you will not notice the difference in response of your motor between using this and any other technique. The delay you see is either due to your code or the inertia of your motors.
Motors react slow compared to the speed of the Arduino.
I agree that the difference between "analogWrite()" and "direct port IO" is very unlikely to be the cause of motors being "slow to react" on a human-visible timescale.
Motors react slow compared to the speed of the Arduino.
I agree that the difference between "analogWrite()" and "direct port IO" is very unlikely to be the cause of motors being "slow to react" on a human-visible timescale.
Well that depends on the code - if its like
for (int i = 0 ; i < $4000 ; i++)
analogWrite (pin, i >> 6) ;
Then the fact the call is in an inner-loop could make it significant at larger
timescales. Any code that's CPU-bound (doesn't wait or delay) is like this.