I'm trying to create a code using an Arduino Uno board to increment and decrement the output voltage of the Arduino Uno which is 5 volts and I need to step it up to 10 volts which I have done below.

The things that are missing on the schematic are two buttons. I want to be able to increment 0.5 volts with each press of Button-A until the Arduino is at 5 volts. With Button-B I want to be able to lower the voltage by 0.5 volts with each press of the button till value is 0.

I can do the calculations and the circuit design but I'm not much of a programmer. I just want to know if anyone can point me in a good direction of where I can get the right code. I have already looked at all the tutorials on the Arduino Website. I do know I have to work with the PWM functions as well as attachinterrupt() and Debounce() functions. Also, how do I set the increments so that I don't go over, say it takes 10 presses to get to 5 volts on the 11th press have it not do anything so I don't break anything. So can anyone please help me with any suggestions?

I have a low pass filter on the circuit for noise handling and like I said I need to add in the buttons to my schematic.


simulate this circuit – Schematic created using CircuitLab

Here is my code I have made. I'm using an LED to test the Vout aspect. So far I can only get my LED to flicker from 2 to 4 volts and my buttons A and B don't work. Can someone look over my code and see how bad I made this?

int PWMPin = 6; // output pin supporting PWM  
int buttonApin = 9; // buttonA to pin 9 PWM  
int buttonBpin = 10; // buttonB to pin 10 PWM  
float value = 0; // read the value at 0  
int fadeValue = value;  

void setup()    
  Serial.begin(9600); //initialize serial communication at 9600 baud  
  pinMode(buttonApin, INPUT_PULLUP);   
  pinMode(buttonBpin, INPUT_PULLUP);  
  pinMode(PWMPin, OUTPUT);  
void loop()    
    int port = analogRead(0);  
    port = map(port, 0, 10, 0, 255);  
    analogWrite(6, port);  

  if (digitalRead(buttonApin) == LOW, fadeValue)  
  // fade from min to max in increments of 25.5 points: basically (0.5 volts)  
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=25.5)   

    digitalWrite(PWMPin, fadeValue);  

    // sets the value (range from 0 to 255):  
   analogWrite(PWMPin, fadeValue);                                       

    if (digitalRead(buttonBpin) == LOW, fadeValue)  
  // fade from max to min in increments of 25.5 points:  
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=25.5)   

    digitalWrite(PWMPin, fadeValue);  

  // sets the value (range from 0 to 255): basically (0.5 volts)  
  analogWrite(PWMPin, fadeValue);                                     
  • I think you need to add a pull-down resistor to the + side of the opamp. Since the input of the opamp is high impedance, the voltage on the + is always 5v even at a low pwm duty cycle. – Gerben Jun 8 '15 at 18:47

I suggest you to use debounce to detect if a pin has been definitely pressed. You could also test using interrupts (hint: interrupts can happen multiple times even if you "only" pressed once). So either use Arduino's example of debounce or take a look at the Bounce2 library found on their website.

Now that you can check whether or not either button A or B has been pressed, how do you keep track of the voltage to be output? You should use a counter variable that will be incremented when button A is pressed and decremented when button B is pressed. Here is a pseudocode:

if(ButtonA == pressed) 
else if(ButtonB == pressed) 

This counter variable can be used to control the output voltage. Remember that the argument for analogWrite() function on the Arduino Uno is the duty cycle which takes in values from 0 to 255. So analogWrite(0) ≣ 0 Volt and analogWrite(255) ≣ 5 Volt. So at the moment, you couldn't just do analogWrite(counter) because you would need to press 255 times button A!

Instead, you would need a way to convert your counter to reflect the increment you need. You mentioned that it should require 10 presses to reach 5 Volt at the Arduino output, and the easiest way to accomplish this is to use Arduino's Map function. The pseudocode would look like this:

Output = map(counter, 0, 10, 0, 255); 

Now there is one last step! The map function will limit the output voltage from 0 to 5 Volt so everything will be safe; however, the counter is not limited to 0 to 10. This means that even if the counter is at 15 (because you pressed button A too many times) the voltage will be 5 Volt and you would need to press button B at least 6 times to see the voltage go down! So to limit the counter you could easily implement your own function:

if(counter >= 10) 
  counter = 10; 
else if (counter<= 0) 
  counter = 0; 

You could also use Arduino's constrain() function which more information can be found on their website.

Hopefully this points you in the right direction.

| improve this answer | |

If all you have to do is to read those 2 buttons, you could just forgo the interrupts and simply poll in the main loop. The Bounce2 library does basically the same.

Also, about the PWM, why not an R-2R?

10V/0.5V + 1 => 21 steps < 32 => 5 bits => 6 resistors.

But it could be more precise, as you would not depend on the oscillator, rather on the precision of the resistors.

| improve this answer | |
  • 1
    Agreed with Igor. Resistor ladders are much more accurate and noise resistant. I would go for an I2C potentiometer such as AD5248. – bot3663369 Sep 22 '15 at 8:25

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.