direct port manipulation --analogeWrite

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

analogWrite(PWM1, PWM_val);
analogWrite(PWM2, PWM_val);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);

thanks in advance

Doyou have a specific duty cycle youre trying to achieve or just want a pwm signal sent to an led?

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 ?

Motors react slow compared to the speed of the Arduino.
Show us your code, it may be the way it is written that is the problem.

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.

If you call digitalWrite() on one of the pins you'll have to call analogWrite() again to set it up for PWM again.

hi , can you plz clarify here ,

thanks

digitalWrite would take that pin out of PWM mode so you do a analogWrite to put it back

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)

Sorta dumb question but is the above a TIMER implementation of PWM on a digital pin ?

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.

COOL ! Thanks for the explanation.

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.

westfw:

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.

Hopefully motor driving code isn't CPU-bound!