# Lesson 11: Arduino Circuit to Dim LED with Potentiometer

In Lesson 8 you learned to write analog voltages on the Arduiono, and in Lesson 10 you learned to read analog voltages from the arduino. In this lesson we will combine what you did in lessons 8, 9, and 10 to create an LED with adjustable brightness. The brightness will be set based on the position of the potentiometer. In order to do this, we need to set the potentiometer up as a voltage divider, and we need to drive the LED from one of the analog pins. For this example, I am using pin 9. The circuit schematic I am using is shown below.

In placing the LED into the circuit, remember that you must always put the longer leg towards the positive voltage. In the case above, the longer leg should be connected to the resistor, and the shorter leg connected to ground. Also remember that we are using a 330 ohm resistor in the circuit to limit the current through the LED.

The goal now is to use what you learned in the last three lessons. You will want to read a value from the potentiometer, and then write a voltage to the LED based on the reading from the potentiometer. Remember that when you read an analog voltage between 0 and 5 volts, the arduino will report a number between 0 and 1023, with 0 representing 0 volts, and 1023 representing 5 volts.

Similarly, when you are writing an analog voltage between 0 and 5 volts, you must write a number between 0 and 255. If you write a “0” value, that corresponds to 0 volts. If you write a value of 255, that will output 5 volts. So, you must scale your write values between 0 and 255 to get voltages between 0 and 5 volts.

The tricky thing now is that we want to dim the LED based on what value we read from the potentiometer. If we read a 0 value from the potentiometer, we want to write a value of 0, which corresponds to a voltage of 0. If we read a value of 1023 from the potentiometer, then we will want to write our maximum voltage of 5 volts, which means we need to write a value of 255. Basically, we need to scale our read values, which will be between 0 and 1023 to suitable write values, which should be between 0 and 255.

Like in the earlier lessons, this is a simple linear relationship and allows us to use the skills we have learned in math class. This sheet explains the math:

So, from the math above, we can see that the Write Value that we should write to the LED should be the value that we are reading from the potentiometer X (255/1023).

With the math out of the way we can write the program. This code is designed for the schematic above where the potentiometer center leg is read with pin A0 and the LED is written from pin 9.

With this code, you should be able to set the brightness from the potentiometer. You read the voltage from the potentiometer and then scale the value you write to the LED based on the reading from the potentiometer.

RESOURCES: On all these lessons I will include resources on where you can purchase the items mentioned in the lecture.

Arduino Microcontroller : You can get a good deal on the arduino on Amazon. Arduinos are open source and many are cheap Chinese knockoffs, so you want to make sure you get an “official” version, which you can at the link above.

Sparkfun Inventor’s Kit : While the bare arduino will get you started, I really suggest getting the Sparkfun Inventor Kit. The projects I will feature in this tutorial set will use the components in this kit, and it is probably cheaper to go ahead and get the kit than to buy the individual components as you go along. The kit is under \$100 on Amazon. The sparkfun kits has everything you need including the arduino.

## 56 thoughts on “Lesson 11: Arduino Circuit to Dim LED with Potentiometer”

1. william says:

how to get it to read out the seconds
can’t get the equation right

1. brocostutsamanki says:

@william try delaying by 500 miliseconds.

2. Terry says:

I have been enjoying the lessons.
in this one i am wondering why the variables are INT yet they are written as a FLOAT ? 255. 1023.

1. admin says:

If you leave 255 and 1023 as ints, the division would result in 0. WriteValue will be written to a pin, so it is best for it to be an int.

2. Rob says:

Hi,

Thanks for putting your enormous effort in this great study!
Really learning something!

Regards,Rob (Netherlands)

3. Techno says:

It is known as type casting wher ethe compiler automatically changes from one type to another to meet programme requirements. As an int can take only numerical values without decimal places, “255/1023” as an int operation will give out 0 instead of 0.25 and will cause trouble cuz it will write voltage 0 even when not required hence we have transformed them by doing the operation “(255./1023.)*readvalue”.

3. Paul says:

Paul you are by far the best teacher the internet has to offer…I had a bit of a head scratch at the end of lesson 11 when you ask us to go and make the LED blink slower or faster depending on potentiometer…thought, “you should have explained more”, but no, I figured it in the end with your maths lesson on point slope form of line. Still a bit over my head but I got it…next up was, “why is the LED so dim”?…hmmm, changed them back to digitalWrite HIGH LOW and Robert was my fathers uncle! Though I do think my math is out…I dont have a 1 second delay at slowest blink rate…could you check my code please?

“int LEDPin = 9; // Declare LEDPin to be Arduino pin 9
int potPin = A0; //Declare potPin to be analog pin A0
int delayTime; //Declare an int called delayTime

void setup() {
Serial.begin(9600); //Start serial port
pinMode(potPin, INPUT); //Set potPin to be an Input
pinMode(LEDPin, OUTPUT); //Set LEDPin as Output
}

void loop() {

delayTime = (255./900.) * readValue; //Calculate delayTime
digitalWrite(LEDPin, HIGH); //Write to LED
delay(delayTime); // set delay time from potentiometer
digitalWrite(LEDPin, LOW);
delay(delayTime);

}”

Ive got something backwards in the math I’m sure. Thank you again, all the way from Mid Wales, UK.

1. admin says:

you declare dalayTime as an int, so 255/900 will always round to 0. Try making delayTime a float

1. Paul says:

Thank you…but I think you will have to put me out of my misery…with the line ” delayTime = (1000./1023.) * readValue;” I get the longest delay between blinks as a perfect 1000.00ms but still at the other end of the pot I’ve got issues. Serial monitor says the delay is 0.00ms but the LED goes off not on. Can you help me, going on just that info and my code above? Would be truly appreciative. In a nutshell, can not get the minimum delay to be 10th of a second that you asked for.

Thanks and sorry to keep asking you stuff.

2. Nader Zineh says:

Hi my name is Nader, i think the equation should be as the following

regards,

3. ankit mishra says:

i think u should take delay = (923.0/1000.)*readValue+100

1. ankit mishra says:

4. Brian says:

This will solve the problem,
when doing the math remember y1 is 100!
; y-y1 = m(x-x1)
;delaytime = (900.0 / 1023.0)*readvalue + 100.0

Hope this helps!

4. Paul says:

Nevermind 🙂 I found my mistake. Had mapped the wrong slope if you know what I mean…..oh, not so fast…when I turn the pot all the way down, instead of staying on and blinking fast(theoretically delay 100 ms) the LED goes off….any Ideas? it’s a 100k linear pot. Thanks again.

1. Kevin Mc Natt says:

Did you ever get an answer? Here’s my code that worked for me:

int LEDPin = 9; //Declare variable LEDPin, assign to pin 9
int PotPin = A0; //Declare variable PotPin, assign to pin A0

float delayTime; //Declare variable delayTime to hold LED on/off time

String Blank = ” “; //Declare variable Blank to hold blank string for easier reading

void setup() {
Serial.begin(9600); //Srart serial communication at 9600 Baud

pinMode(LEDPin, OUTPUT); //Set up LEDPin as Output pin
pinMode(PotPin, INPUT); //Set up PotPin as Input pin
}

void loop() {
Serial.print(“Reading: “); //Print string to serial monitor
Serial.println(Blank); //Print blank line to serial monitor for easier reading

Serial.print(“Delay Time: “); //Print string to serial monitor
Serial.println(delayTime); //Print delayTime to serial monitor
Serial.print(Blank); //Print blank line to serial monitor for easier reading

digitalWrite(LEDPin, HIGH); //Turn on LED
delay(delayTime); //Leave LED on for time specified by potentiometer as stored in delayTime
digitalWrite(LEDPin, LOW); //Turn off LED
delay(delayTime); //Leave LED off for time specified by potentiometer as stored in delayTime
}

5. danie says:

Paul is the best teacher ever
This works for me to get a blink from 0.1sec to 1 sec:

int potpin = A0; //input value from pot to pin A0
int LEDPin = 9; //output to led on pin 9
int writeValue; //write flashing value from 1second (1000ms) to 0.1 (100ms) second
/* write value can be int because the final calculated value will always be an int
-0.879765 x [0 to 1023] + 1000 = between 100 and 1000 */

void setup() {
Serial.begin(9600); //start serial port
pinMode(potpin,INPUT); //potpin is input
pinMode(LEDPin,OUTPUT); //LEDPin is output
}
void loop() {
Serial.println(readValue); // gives 0 to 1023 reading from pot on serial monitor
Serial.println(writeValue); // gives 0.1sec (100ms) to 1sec (1000ms) reading from pot on serial monitor

writeValue = (-0.879765*readValue) + 1000; // calculation
digitalWrite(LEDPin,HIGH); // LED on
delay(writeValue); //delay as calculated (-0.879765*readValue) + 1000
digitalWrite(LEDPin,LOW); // LED off
delay(writeValue); //delay as calculated (-0.879765*readValue) + 1000
}

6. danie says:

l

y
l (100ms or 0.1sec)
l
l
l
l
l (1000ms or 1 sec for y)
0 for x—————————————————–1023 –x

7. omji singh says:

is it necessary to write integers value(write value) in analogWrite command.?

8. Jan says:

Is it also possible to set readValue and writeValue as a float instead of an int?

9. Sunil says:

I am not able to see dimming of led when potentiometer value changed from 0 to max, with this arduino code. It is showing on at value of 129 and till 255 it is with same intensity.

Pls help me out.

int potpin=A0;
int ledPin=12;
int writevalue;

void setup() {
// put your setup code here, to run once:

pinMode(potpin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
analogWrite(ledPin, writevalue);
Serial.print(“You are writing a value of “);
Serial.println(writevalue);

}

1. admin says:

Pin 12 is not an analog out pin. You must use a pin with a squiggle line y it ~

1. Sunil says:

Thank you…done….

10. Enache Lucian says:

Why don’t we use the map() function?

1. admin says:

Because I am trying to teach high school students how to use the math they learn in math class for a practical application.

11. rammmmmmmmm says:

can we use LDR in the place of potentiometer

12. David Mills says:

with the calculation you provide
the voltage hits 255.

where am i going wrong?
even if i copy your code, it still hits 255.
any ideas?

13. Usman says:

Please Explain me how to code for two outputs. I am trying to operate two small motors simultaneously.

14. Martin says:

Thanks Paul, great lesson as always.
And as always 24 mins of video leads to 24 hours of exploration, and as a bit of a math geek, (tbh a general geek) I decided to use your line equations to give users a little more flexibility when using a potentiometer as input.
I am not a professional teacher so apologies if the following is either too complex or too patronising.

Paul gives a general slope equation of…
(1) m = (y2 – y1)/(x2 – x1)
and a point slope form equation…
(2) (Y-y1) = m(X-x1)

It is always true that x2 = 1023 = readValueMax
It is always true that x1 = 0.
Substituting into (1) gives…

Allowing the user to decide the blink rate output dependent on potentiometer readings we get…
y2 = user input = outValueMax
y1 = user input = outValueMin
Giving…
(3) m = (outValueMax – outValueMin) / readValueMax

From (2) we have…
Rearranging…

Paul, in his examples above, mentioned typecasting, and it being a source of problems for many students. I must admit it caused me a few problems when I tried to implement the above into an arduino script. While it is straightforward to tell arduino to treat a constant, for example 99, as a floating point by typing 99. it is not so obvious how to do the same with a variable. fortunately arduino provides cast functions such as int() and float(). The following is essential to prevent “m” evaluating to zero.

(3a) m = float(outValueMax – outValueMin) / float(readValueMax)

Oddly only one of these float() functions is necessary. If anyone could explain this I would be grateful.

After all this I ended with the following script. Any lines with //debug code can safely be edited out without effecting functionality.

//Declare variables
const int potPin = A0;//declare pin A0 to read potentiometer
const int outPin = 9; //to control LED
const int readValueMax = 1023; //as per arduino specification.
int outValue; //Wil be used as a delay value
int outValueMax; //longest delay wanted
int outValueMin; //shortest delay wanted
float m;

void setup() {
pinMode(potPin,INPUT);
pinMode(outPin,OUTPUT);
Serial.begin(9600); //starts the serial monitor for input values and debuggering

Serial.print(“Enter longest delay(milliseconds)…”);
while(Serial.available()==0){} //wait for user input
outValueMax = Serial.parseInt(); //reads user input into outValueMax

Serial.print(“Enter shortest delay(milliseconds)…”);
while(Serial.available()==0){} //wait for user input
outValueMin = Serial.parseInt(); //reads user input into outValueMin

}

void loop() {
m = (float(outValueMax – outValueMin)/float(readValueMax)); //calculate slope
outValue = m*readValue + outValueMin; //substitute slope(m) into line equation y = mx + c
Serial.print(“m = “);//debug code
Serial.println(m);//debug code
Serial.print(“outValue = “); // debug code
Serial.println(outValue); // debug code
digitalWrite(outPin,HIGH);
delay(outValue);
digitalWrite(outPin,LOW);
delay(outValue);
}

1. Martin says:

In all that I forgot to say…
The purpose of the script is to give an LED pulse rate dependent on a range given by a user and the settings of a potentiometer.

15. Emmanuel says:

how was the value 1023 chosen for pot(potentiometer)

16. Malaka says:

it’s kind of tricky. but it does what we need.

int ledGrn=10;
int potPen=A0; // Assigning potPen to A0
float Voltage; // Declare our voltage variable
int delayTime;

void setup() {
Serial.begin(9600);
pinMode(potPen,INPUT);
pinMode(ledGrn,OUTPUT);
}
void loop() {
digitalWrite(ledGrn, HIGH);
analogWrite(ledGrn, 0);
}
}

17. Malaka says:

int ledGrn=10;
int potPen=A0; // Assigning potPen to A0
float Voltage; // Declare our voltage variable
int delayTime;

void setup() {
Serial.begin(9600);
pinMode(potPen,INPUT);
pinMode(ledGrn,OUTPUT);
}
void loop() {
digitalWrite(ledGrn, HIGH);
analogWrite(ledGrn, 0);
}
}

18. Chad says:

Thank you Paul for taking your valuable time to share your knowledge with us. Your lessons are a great introduction to the world of Arduino and are very easy to understand and follow.

Homework assignment:
Pot at 0 = blink every 1sec (1000ms)
Pot at 1023 = blink every .1sec (100ms)

For anyone interested, this is the code that worked for me. Thanks to danie’s post for helping me figure out the math.

int LEDPin=9; //Declare LEDPin is pin9
int potPin=A0; //Declare potPin is analog pin A0
int writeValue; //Write blinking value 100ms to 1000ms
float voltage; //Read pot voltage value 0v to 5v

void setup() {
Serial.begin(9600); //Turn on serial port
//Print title message
Serial.println(” “); //Print space
pinMode(potPin,INPUT); //Set potPin to input
pinMode(LEDPin,OUTPUT); //Set LEDPin to output
}

void loop() {
Serial.print(“Potentiometer voltage (0-5) is : “);
//Print message
Serial.println(voltage); //Prints 0 to 5 voltage
Serial.print(“Potentiometer value (0-1023) is : “);
//Print message
Serial.print(“Speed of blink in msec is : “); //Print message
Serial.println(writeValue);
//Prints 100ms to 1000ms writeValue
Serial.println(” “); //Print space

voltage = (5./1023.)*readValue; //Calculate pot voltage value
//Analog read value from potPin (0-1023)
//Calculate writeValue
digitalWrite(LEDPin, HIGH); /Turn on LEDPin
delay(writeValue); //Delay as calculated in writeValue
digitalWrite(LEDPin, LOW); //Turn off LEDPin
delay(writeValue); //Delay as calculated in writeValue
delay(250); //Delay 250 msec
}

1. Tony Woicekowski says:

this is a nice addition to danie’s solution – but I had 2 problems. The compiler did not like the quotation marks as copied to my clipboard, so I replaced them with quotation marks from my text editor. Also, there is a back slash missing from the comment on the 5th from the final line – /Turn on LEDPin. Thanks to all for the very helpful input.

19. Muhammad Nabi says:

Successfully done it in the first attempt. 😀

int LEDpin = 9;//LEd is connected to pin 9
int Potpin = A0;// Potpin is conected to A0
int Readvalue;//declaring a variable to get value at A0
int delaytime;//Declarijg variable for calculting delaytime of led
int Writevalue;

void setup() {

Serial.begin(9600);// intializing the serial moniter
pinMode(Potpin, INPUT);// set potpin to be an input
pinMode(LEDpin, OUTPUT);// Set LED pin to be an output

}

void loop() {

delaytime = (1000./1023.)*Readvalue;// Caclulating delaytime for led
Writevalue = (255./1023.)*Readvalue;// Calculting the write value
analogWrite(LEDpin,Writevalue);// write the value to led
delay(delaytime);// delay between on and off
analogWrite(LEDpin,LOW);// turning off the LED
delay(delaytime);//delay beyween on and off
Serial.print(“You are writing the vlaue: “);//
Serial.println(Writevalue);

}

20. Muhammad Nabi says:

You are an Amazing teacher. I love watching all of your lessons. I am sure no one on the internet can teach better than you. Thanks for everything you are doing.

1. admin says:

Wow, that was sure a nice thing to say. Thank you for the kind words. I will work hard to keep teaching. I am glad people think it is working.

21. Ricky says:

This works perfect.
________________________________________________________________

int potPin=A0; //Declare int “potPin”,assign value A0;
int LED=3; //Declare int “potPin”,assign value 9;

void setup() {

pinMode(potPin,INPUT); //Declare int “potPin” as INPUT;
pinMode(LED,OUTPUT); //Declare int “LED” as OUTPUT;

Serial.begin(9600); //Turn Serial Port on, set baud to 9600;
}

void loop() {

analogWrite(LED,88); //Send power to the LED equal to the power read by the potentiometer;

Serial.println(math);
delay(math);

analogWrite(LED,0);
delay(math);
}

22. Michael says:

I was just wondering if you get a minute if you might look at my work and tell me if this is what you were looking for in your “Arduino lesson 11” homework assignment. it took some time to figure out the code change but the big question is the math you wanted us to do. I’m trying to keep it simple to as I am not in school and have no teacher but am thinking of going back for a new career. I’m no math major so if you could give me your input it would be great.

MATH:

y2 = 1000 // one second
y1 = 1 // one millisecond
x2 = 255 // 1023 10K ohms
x1 = 0 // 0 0 Ohms

y2 – y1 1000 – 1 999milliseconds
M = ——— M= ———- = —— = .9675
x2 – x1 1023 – 0 1023ohms

but that looks like a dim light on the fast setting so I set my code to

It all works but is this what you wanted to see as far as the math goes?

MY CODE:

int potPin = A0; //declare potentiometer as pin A0
int BlueLed = 10; //declare Blue led as pin 10
float writeValue; //declare write value variable

void setup() {

pinMode(potPin,INPUT); //declare potentiometer as an input
pinMode(BlueLed,OUTPUT); //declare Blue Led as and output
Serial.begin(9600);

}

void loop() {

writeValue = (990./1023.) * readValue; //define writeVale as time / resistance * potentiometer input
digitalWrite(BlueLed,HIGH); //turn on Blue Led
delay(writeValue); //delay on time by writeValue variable
digitalWrite(BlueLed,LOW); //turn off Blue Led
delay(writeValue); //delay off time by writeValue variable
Serial.print (“you are writing a value of “); //serial monitor print message
Serial.println(writeValue); //serial print monitor variable with next line advance

}

Thank you,
Michael

23. peterb says:

Hi Paul! Thanks so much for this tutorial. Have you posted your Fritzing diagram anywhere?

24. Joseph says:

Great lesson Paul! Some really good solutions down here, but I think generally people are over thinking this.

int potPen=A0;
int LEDPin=9;
int delayValue;

void setup() {
Serial.begin(9600);
pinMode(potPen,INPUT);
pinMode(LEDPin,OUTPUT);
}

void loop() {
digitalWrite(LEDPin,HIGH);
delay(delayValue);
digitalWrite(LEDPin,LOW);
delay(delayValue);

Serial.println(delayValue);
}

25. Yule Mekkelholt says:

Hello Paul,

If I turn the piontometer to the right the lamp goes on but he prints says 0 and if I turn the piontometer to the left the lamp goes out and the print says 255? Can you help me?

Yule M 12 year

From the Netherlands

1. Yule Mekkelholt says:

potentiometer*

2. edy says:

possible have the pot wired uncorrectly

26. Thomas says:

I tried a program there I use an ultrasonic device to light up a LED diod when an object is 40 centimeters or less in front of the ultrasound device. It worked very nice so I tried to make the program dimming up the led-diod to full brightness. It also worked very well but when I tried to have it stay at full brightness it refused. It dims up and shortly turns off to dim up again. Is it any easy way to dim up and stay on full brightness meanwhile checking the distance to the U-sound unit? I checked the videos and to use potentiometer as input for brightness is nice but using the distance from ultrasound and make it dim up and stay there meanwhile continuing measuring I have not solved.

27. masoud says:

thanks for your teaching. it was really good.
what is the difference between 255 and 255. ?
(why we use dot?)

1. Daniel Pena says:

255 is an interger (whole number). 255. is a float (decimal). Arduino makes a distinction between the two and interger math is different from float math.
255/1023 = 0 because “0” is the closest interger.
255./1023. = 0.249266862170088 because this is a float (decimal ) answer.

28. Daniel Pena says:

I have the same problem that Sunil had – when I turn the potentiometer to zero the LED does turn off but the moment I get any voltage going through it the LED goes on to full brightness even though the serial monitor tells me that the voltage is less than 5 volts. Unlike Sunil I do have the red LED Pin set to pin 9. My LEDs are coming from the “Side KIck Basic Kick for Arduino” from Radio Shack. Please Help!
My Code –
int redLedPin=9;
int potPin=A0;
int writeValue;
float Voltage;

void setup() {
pinMode (potPin, INPUT);
pinMode(redLedPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
digitalWrite(redLedPin,writeValue);
Serial.print(” Write value = “);
Serial.print(writeValue);
Serial.print(” Volts = “);
Serial.println(Voltage);
Serial.println (” “);
}

29. Daniel Pena says:

Should have been analogWrite(redLedPin,writeValue);

Only took a day and a half to figure out 🙂

30. HN says:

Great Work, i have learned a lot from Paul (toptechboy). Thanks a lot appreciated.

31. Salaheddin says:

Hello Dears:
I write this code to control of led time on & off
enjoy
int potPin= A0; //Declare potPin to be analog pin A0
int LEDPin= 9; // Declare LEDPin to be arduino pin 9
int writeValue; // Use this variable for writing to LED
int delayon; //calculated value of delay on
int delayoff; //calculated value of delay off

void setup() {
pinMode(potPin, INPUT); //set potPin to be an input
pinMode(LEDPin, OUTPUT); //set LEDPin to be an OUTPUT
Serial.begin(9600); // turn on Serial Port
}

void loop() {

writeValue = (10000./1023.) * readValue; //Calculate Write Value for LED
delayon=writeValue ;
delayoff=writeValue ;
digitalWrite(LEDPin,HIGH);
delay(delayon);
digitalWrite(LEDPin,LOW);
delay(delayoff);
Serial.print(“You are writing a value of “); //for debugging print your values
Serial.print(delayon);
Serial.println(” MELLESEC”);

}

32. martin says:

dear Paul

many thanks for the great tutorial – i just have noticed it on the youtube portal.

one question:

for the Arduino with Python LESSON 11: https://www.youtube.com/watch?v=zH0MGNJbenc

here we have the correspoinding site;
http://www.toptechboy.com/arduino/lesson-11-arduino-circuit-to-dim-led-with-potentiometer/

question: is the whole code that you develope on the lesson 11 on the web-page toptechboy

love to hear from you

best regards martin

ps – keep up the great work – it rocks!!!

33. matt matthews says:

hi im trying to fire a npn transistor i need a code to adujst pulse with as well as frequece using 2 pots any help would be great sorry for my spelling no highschool but i am pretty good with circuts

34. Dixie says:

35. samrat says:

can anyone say me why fopen() is not working in Arduino IDE.

36. David P says:

Great training so far, really enjoying the class. You really do need to type your own code. I made a hundred mistakes in the code before I was able to work my way through it. This one took me a solid couple hours.

int LEDPin=10; // Declare LEDpin to be arduino pin 10
int potPin=A1; // Declare potPin to be analog pin A1
float delayValue; //Variable for delay

void setup() {
Serial.begin(9600); // Turn on serial port
pinMode(potPin, INPUT); // set potPin to be an input
pinMode(LEDPin, OUTPUT); // set LEDPin to be an output

}

void loop() {