How can I output a specific value on a pin using port manipulation?

Example: I want to use this code but without any arduino functions, just with port manipulation:

for (int i = 0; i < 255; i++){
analogWrite(11, i); //write the i value to pin 11

I want to replace the analogWrite function with register manipulation. Is that possible?

  • Of course, how do you think analogWrite does it?
    – Nick Gammon
    Jan 4 '17 at 2:20
  • @NickGammon Alright, I made some quick research and I am back from where I started. I must actually generate a PWM on that PIN and change the duty cycle acordingly ( basically what analogWrite does). Am I right?
    – Adrian
    Jan 4 '17 at 2:36
  • Have you read the ATmega328 datasheet? This is where you have to start. Taking a look at the implementation of analogWrite() might help too.
    – jfpoilpret
    Jan 5 '17 at 17:21

The analogWrite function is just an interface to setting up the hardware timers to do PWM (pulse-width modulation). I have a page about timers which you may find helpful.

Depending on which pin you want to output the PWM to, the registers will be slightly different. Here is one example from my page:

const byte OUTPUT_PIN = 3;  // Timer 2 "B" output: OC2B

const byte n = 224;  // for example, 1.111 kHz

void setup() 

  TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2A on compare
  TCCR2B = bit (WGM22) | bit (CS22);         // fast PWM, prescaler of 64
  OCR2A =  n;                                // from table  
  OCR2B = ((n + 1) / 2) - 1;                 // 50% duty cycle
  }  // end of setup

void loop() { }

How can I output a specific value on a pin ?

I should point out that the only values you can output are +5V or 0V. There is no provision for outputting (say) 3.7V. The only way you can sort-of do this is by using PWM and then running the result through an RC filter. There is an example on my page about op amps.

An example circuit could be:

Filter circuit

This uses a resistor and capacitor to filter out the "ripple" in the PWM, giving you a reasonably smooth output voltage, proportional to the PWM duty cycle.

For a larger range of output values a rail-to-rail op-amp would be preferable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.