Lesson 8: Writing Analog Voltages in Arduino

We have done some pretty cool stuff so far with the arduino. We have learned how to get input from the user, and how to send information to the user. We have learned how to control commands with both for loops and while loops. We are well on our way to building some really powerful projects. The thing is, so far all of our commands to the arduino pins have in effect been to either turn the pin On or turn it Off. That is, when we digitalWrite HIGH or LOW to the pins, we are either turning on the full 5 volts or turning it all the way off. The truth is that most times we want something in the middle. We would maybe want a voltage of 2.3 volts.

The arduino pins with the squiggly line by them are able to write these in between voltages. These are pins 3,5,6,9,10,11 on the arduino uno.

In the world of engineering and electronics, we say that we want an analog voltage. That is, we want to apply any voltage we want, not just 0 or 5. To output an arbitrary voltage between 0 and 5, would issue the arduino an analogWrite command. Unfortunately, the arguments for the analogWrite command are not as simple as telling it a number between 0 and 5. We must give it an integer between 0 and 255. If we issued the command analogWrite(mypin,0), it would apply 0 volts to mypin. If we issued the command analogWrite(mypin,255), it would appy 5 volts to the pin. As you can see, if we gave the command analogWrite(mypin, 127), we would get about 2.5 volts applied to mypin. You can see those are the easy ones, but in order to figure out exactly what value we should use for exactly the voltage we want, we will need to do some math. Remember all the times you had to calculate the equation of a line in math? Well you are going to do it for real now and for a reason. We need to get an equation that will allow us to calculate the Write Value we should use to get the Voltage

Write Values
You will need to choose the correct value between 0 and 255 to get your desired voltage

You can see that you need the equation for the line above. Good news! You have two points so can calculate the equation of the line. The first point is (0,0), that is to say, that if you want a voltage of 0 to be applied to the pin, you should analogWrite the value of 0, as we explained above. The second point is (5,255), that is to say, if you want to apply a voltage of 5 Volts, you should analogWrite the value 255, as explained above. Now we calculate the equation of the line. the slope would be:

m = (y2-y1)/(x2-x1) = (255-0)/(5-0) = 51

OK, now to get the equation of the line we will use the point slope form of a line, and we get:

(y-y1)=m(x-x1)

We can plug in the point (0,0) and get

(y-0) = m(x – 0)

And when we plug in 51 for m we get:

y = 51X

Remember X is the voltage we want, and Y is the value we write, so this equation can be rewritten:

Write Value = 51 X (Desired Voltage)

So, this equation lets us calculate precisely what value we should analogWrite in order to get the voltage we want on the pin. I hope this makes sense. If you are confused watch the video and it will make more sense.

The bottom line is that we can use this equation to calculate the number we should write to get the voltage that we want at a pin.

As an example, if we wanted to get exactly 2 volts, we should write the value 2X51= 102. If we wanted two volts on the pin myPin, we would issue the command analogWrite(mypin, 102).

Now lets start playing around with a circuit. Lets use the circuit we have been using the last few lessons. Hopefully you still have it hooked up, but if you need help we take you through it step-by-step in Lesson 3.

LED Schematic
This circuit will allow you to independently control two Light Emitting Diodes from the arduino microcontroller

Lets start with our code from Lesson 7:

If you have been following these lessons, this code should make sense as we have built up step by step.

What we need to do now is to replace the four digitalWrite commands with analogWrite commands. Lets say that instead of applying 5 volts to the LED we want to apply 1 volt. This should make the LED’s blink noticeably dimmer. Remember that we would not analogWrite a value of 1, but need to calculate the write value from our formula. We want a voltage of 1 volt, so our write value should be 1 X 51, or the value 51. So now instead of digitalWrite, we should have a command like analogWrite(redLEDPin, 51) or analogWrite(yellowLEDPin, 51). Notice that on the commands that turn the LEDs off . . . digitalWrite(redLEDPin, LOW) would still work to turn the pins off, but I think it is good practice to change all the writes to analogWrites in a problem like this. To turn the pin off with an analog write would could use the command analogWrite(redLEDPin, 0).

With this new knowledge, you should modify your code and replace the 4 digitalWrite commands with analogWrite commands. Play around with writing different values to see the effect on the LED Brightness.

31 thoughts on “Lesson 8: Writing Analog Voltages in Arduino”

  1. I adore your Arduino lessons. While video is great for when one is particularly stuck, I find it much more useful to read general how-to lessons, than to sit through entire videos.

    Best of all, your writing is super-clear, and your examples are always cogent.

    If the mood hits, I’d love to see you cover Ethernet and Wi-Fi for Arduino. I’ve spent 3 hours, trying to get a W5100 shield from Addicore to talk to my router, and I’m stymied. I suspect I got a bum shield, but I’m sufficiently a n00b as to doubt myself.

    Anyway, I can’t wait to graduate to your Python for Arduino stuff!

  2. Love your lessons! I have commited to doing all of them.

    Just one thing on lesson 8. I noticed that when I was compiling my code, I could not get my LEDs to dim no matter what voltage I set. I found my Uno kit at a thrift store for $4 and figured I had found out why it was there.

    I did some research and found on the Arduino website that the that the two pins I was using (13 and 8) did not support the analogWrite function.

    Just a tidbit for anyone else who runs into this.

    Thanks!

  3. I’m sorry, but this is just WRONG. analogWrite (at least on the Uno) does not write an analog voltage to the output pin. Just read the analogWrite page at arduino.cc: http://www.arduino.cc/en/Reference/analogWrite

    It writes a PWM value between 0 and 255 to the pin. That toggles the voltage between 0 and 1 with a frequency between 0 and 255. While an LED responds slowly enough to smooth out a PWM signal to the average voltage, if you hook your circuit up to something that isn’t quite so slow – like a cheap digital multimeter – you’ll see that the actual voltage jumps all over the place.

    So while your code works, and is a standard way to control the brightness of an LED with an arduino, you are NOT writing out an analog voltage. You need a little external circuitry to smooth the signal, as described here.

    1. @Mike – exactly. This is what I have found as well. The value being set is the DutyCycle and it toggles between Off (Zero volts) and On (5 volts). The DutyCycle is the length of time the On and Off are set to.

    2. Honestly, can’t you see he knows that? He is just trying to keep things simple for beginners. What is the point of explaining low pass circuit at this point to a fourth or fifth grader. Let’s respect him for what he is giving “Free of Charge”.

  4. You’re doing a good job, I appreciate that.
    I’ve a silly question…
    If we can control output voltage, can we remove resistor of the picture?
    Regards

    1. You always need a current limiting resistor in series with LED. LED is a very non-linear device, and stable operation is from current limiting resistor.

  5. hi im really amazed of your lessons, there is a question i have for you.. how do i know when do i need analog or digital writes?

    i mean basically i can use just 3 volts or 2 it doesnt really matter .

  6. I agree with Mike. This article will cause a frustration for people who doesn’t know how analogWrite works. This article can somehow be applied only for lighting a led but if you really want to control a device with linear voltage from 0 to 5 you will start to wonder why it doesn’t work. Answer is that analogWrite defines duty cycle of square signal, if you want to get an output described in this article you need at least an RC circuit. So basically article looks nice, has some mathematical calculation but in total is wrong…

  7. Hi

    Enjoying the lessons

    FYI: in the last paragraph of the text you typed ‘analowWrite’. I think you intended ‘analogWrite’.

    Looking forward to more detail about building in the balloon project with my kids.

    Thanks

  8. I LOVE your lessons but can you send me the code of the ending of lesson NO.8 you are a very good teacher I like your teaching very much.

    best Regards! 🙂

  9. Why using the analog ground instead of the digital one? would it work if we used the digital ground? what the difference between the two (what should we keep in mind)?

  10. please sir l need help l just come to know you lesson recently and l cherish it so well. am convince that you can help me out with a code to run 24×6 LED Display. using three register 954 ic for colum and decade counter 4017ic for row.
    now left with code and connection to complete me program. am asked to write ” WELCOME TO AKWA IBOM STATE UNIVERSITY A PROJECT BY …… 2016/2017 SESSION” then it can also be used with the serial pot communication

    1. It is not an error, it is a simplification, given I am targeting these lessons for 7th graders. PWM actually acts like analog voltages for many applications besides LED. Hence, I simplify for the purpose of clarity, and then later can describe the subtleties of PWM more fully.

  11. I tested my voltage and found that my code values failed to generate my expected voltage values. After reading the comments here, I suspect that it’s due to the PWM. But I’m on pin 9 as is the lesson. I would have thought that the PWM pins were 0 through 7, as is printed on the board. Any thoughts or suggestions?

  12. I enjoyed the lesson, thank you. What I wonder though, I would like to use Arduino for a 24-tone scale project. So after doing some math and looking into D/A converters, I was wondering if you can even create such precise voltages with Arduino with only 255 different duty cycles.
    If one uses a 12 tone scale in music, in a 1V/Oct system, 1 step/tone increases by 0.0833 Volts and a full octave by 1 Volt. So you can quickly see, my plan to go for quarter tones in music, means I need 0.04165 Volt per step. What would you say… or in what direction should I do some research? Thanks a lot…

  13. Thanks for Lesson no:8
    I was make little bit change with this program ..
    use input data will be show us at serial monitor

    i was learned lots of thing with these lessons . without no having any experience in programming ,, your video is a awesome..

    My code :
    int redPin=9;
    int greenPin=10;
    int redOn=250;
    int redOff=250;
    int greenOn=250;
    int greenOff=250;
    int redTime=5;
    int greenTime=5;
    int redValue;
    int greenValue;

    void setup() {
    Serial.begin(9600);
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    Serial.println(“Aries Computer Solutions”);
    Serial.println(“Welcome to my new Program”);

    Serial.println(” Set Value for RED LED between the 0-255 = “);
    while(Serial.available()==0); {}
    redValue=Serial.parseInt();
    Serial.print(“User input Value is a = “);
    Serial.println(redValue);

    Serial.println(” Set Value for Green LED between the 0-255 “);
    while(Serial.available()==0); {}
    greenValue=Serial.parseInt();
    Serial.print(“User input Value is a = “);
    Serial.println(greenValue);

    }

    void loop() {
    Serial.println(“Red LED Start”);
    int x=1;
    while (x<=redTime) {
    Serial.print(" Red LED Blinking = ");
    Serial.println(x);
    analogWrite(redPin, redValue);
    delay(redOn);
    analogWrite(redPin,0);
    delay(redOff);
    x=x+1;
    }
    Serial.println("Green LED Start");
    int y=1;
    while (y<=greenTime) {
    Serial.print(" Green LED Blinking = ");
    Serial.println(y);
    analogWrite(greenPin, greenValue);
    delay(greenOn);
    analogWrite(greenPin, 0);
    delay(greenOff);
    y=y+1;
    }

    }

Leave a Reply

Your email address will not be published. Required fields are marked *