# 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

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. This circuit will allow you to independently control two Light Emitting Diodes from the arduino microcontroller

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.

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

1. Holden McGroin says:

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!

1. admin says:

The python and arduino lessons will show how to use ethernet.
PJM

2. Robert Tijerina says:

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!

1. admin says:

Yes, only the pins with the squigly line will do analog writes.

2. farhad says:

3. Mike says:

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 says:

Oops. Not “with a frequency”, but “with a duty cycle”. My bad.

2. Daniel Giblett says:

@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.

3. Vivek Sharma says:

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. Jay says:

You are right . It should be clarified , even to beginners .

4. Chris says:

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. admin says:

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.

2. MEGHJIT MAJUMDER says:

I think that the resistors are for limiting the amount of current flow through the resistors.

5. dmitry says:

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. Rav says:

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. khiz says:

How did we come to know that digital high is 5 volts?

1. admin says:

That is the standard for Arduino. Or, you can measure it with a volt meter.
PJM

8. sxott says:

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

1. admin says:

Thanks, I fixed that now.

9. Khanfr says:

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! 🙂

10. Khanfr says:

I got it, sry I was confused 😛 opps

11. Takishi says:

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)?

12. ibekwe says:

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

13. Ilya V Osipov says:

The lesson contains key error. You can not specify the output voltage through the use of commands on “AnalogWrite”
This command is used to create a “Pulse Width Modulation” look
https://www.arduino.cc/en/Tutorial/PWM
and https://www.arduino.cc/en/Reference/AnalogWrite

Due to the fact that the “LED” understands PWM how to change the brightness modulation – examples might work. In other cases, it would be completely erroneous

1. admin says:

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.

14. Tony Woicekowski says:

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?

15. Andy Gee says:

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…

16. Harshad Patel says:

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;
}

}

17. suresh says:

Where is 255 value came from? Please tell me the meaning of 255?

1. Gary McPherson says:

2 to the 8th power. It is an 8-bit DAC

18. Sagar Yennam says:

Excellent math work example. Its easy way to find analog value.Thanks a lot .

19. Larry Fostano says:

Lesson 8:
So far I think the analog part of this is easy and makes sense to me.I am however having an issue with the Yellow LED not turning on. However if I put in a value like 51 or 255 instead of writeValueYellow it works on value.I would appriciate some help here , looked over code several times, rewrote it ,cut red led code and pasted for yellow led and changed all ther red statements to show yellow , still same issue.I even for the sake of it swapped out LEDs which was ridiculous but tried it anyhow.See actuall code below
Serial.println(redMessage);
int j=1;
Serial.print(" You are on Blink#: ");
Serial.println(j);
analogWrite(redLEDPin,writeValueRed); //Turn on Red
delay(redOnTime); // Wait time on
analogWrite(redLEDPin,0); //Turn off time
delay(redOffTime); //Leave off
j=j+1;

Serial.print(" ");
Serial.println(yellowMessage);
for (int j=1; j<=numYellowBlinks; j=j+1){ //Start loop
Serial.print(" You are on Blink#: ");
Serial.println(j);
analogWrite(yellowLEDPin,writeValueYellow); //Turn yellow LED on
delay(yellowOnTime); //Wait time on
analogWrite(yellowLEDPin,0); //Turn yellow LED off
delay (yellowOffTime); //Leave off

20. Steve B says:

You did not include the beginning part of your code where the variables are declared. I suspect that your problem is in that part of your code. Did you remember to declare the variable writeValueYellow?

21. Ronald Kirby says:

Hi there i am enjoying your lessons very much i am only used to analog technology growing up with valves and then transistors and ic’s now i need to learn programming and digital communications . the thing i was wondering is ? you say the voltage line is linear for the analog write , i would have thought it would be more like a sinewave or part of one. anyway thank you so much for your lessons

22. PRASANTH L says:

Hi Sir ,
What is the diffrence between Serial.parseInt and Serial.Read

23. Gagan says:

The above code is not the code for anaglog value it says digitalwrite sir

24. Dr John C Bullas says:

I have a n analogue output from a automotive lambda probe controller that has been configured to output 0-5v in a away that is in the reverse sense required for any commercial displays.

I have reduced the voltage output to 1v via a voltage divider but still have to invert the output so 0v-1v becomes 1v-0v .

The arduino is a great way to read in the input voltage BUT how do I output a given true voltage to feed into a commercially available automotive LED array in a gauge?