PID regulation – Led brightness regulation with Arduino

Led brightness regulation using PWM based on a light sensor and a proportional–integral–derivative controller implemented on a Arduino UNO.

1. Led wiring and control

1.1 Led wiring

– Our led is a Yellow led with a 2.4v forward voltage at 20mA.
– Our current source (Arduino) delivers 3.3v.

Resistor calculation :
R = (3.3v – 2.4 V) / 25 mA = 0.9v / 0.02A = 45Ω

We’ll wire the cathode to one of the digital I/O of the Arduino. Note, we chose the digital I/O #3 as we’ll need to use PWM (described below).

As I just had a 47Ω resistor, this will work :

1.2 Led brightness control

In order to control the brightness of the LED, we’ll use the Pulse-width modulation (PWM), or pulse-duration modulation (PDM) :

To do this, we’ll use the following function : analogWrite(pin, value)
pin: the pin to write to.
value: the duty cycle: between 0 (always off) and 255 (always on).

Code sample :

void setup()
pinMode(3, OUTPUT); 

void loop()
//Analog write
analogWrite(3, 64); 

Results (0, 25%, 75%, 100%) :

2. Led brightness regulation

2.1 Light sensor

We’ll add a light sensor as wired below :

Just place the sensor in front of the LED:

2.2 Light regulation

In order to regulate, we’ll use a proportional–integral–derivative controller. A PID controller is a control loop feedback mechanism (controller) commonly used in industrial control systems. A PID controller continuously calculates an error value as the difference between a desired setpoint and a measured process variable. The controller attempts to minimize the error over time by adjustment of a control variable.

Here is the code :

double Setpoint, Input, Output;
//PID parameters
double Kp=0, Ki=10, Kd=0;

//Start PID instance
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
  //Start a serial connection to send data by serial connection
  //Set point : Here is the brightness target
  Setpoint = 100;
  //Turn the PID on
  //Adjust PID values
  myPID.SetTunings(Kp, Ki, Kd);

void loop()
  //Read the value from the light sensor. Analog input : 0 to 1024. We map is to a value from 0 to 255 as it's used for our PWM function.
  Input = map(analogRead(0), 0, 1024, 0, 255); 
  //PID calculation
  //Write the output as calculated by the PID function
  //Send data by serial for plotting 
  Serial.print(" ");

PID Parameters :
Kp accounts for present values of the error (e.g. if the error is large and positive, the control variable will be large and negative).
Ki accounts for past values of the error (e.g. if the output is not sufficient to reduce the size of the error, the control variable will accumulate over time, causing the controller to apply a stronger action).
Kd accounts for possible future values of the error, based on its current rate of change.

The Arduino 1.6.6 comes with a tool called “Serial plotter”, that might be useful to graph our data:
The measured value is note stable, probably due to the PWM. A solution would be to smooth the results by doing an average on the lasts results, in order to filter the high frequency changes.

Note : You can graph several values at the same time, you just need to send them on the same line, with a space as a delimiter.

When I disrupt the system with an external light, we clearly see that the system tries to keep the brightness at the setpoint (100) by managing the led control value :

To conclude, here is how the system is handling a change from 0 to setpoint, or from setpoint to 0 :

5 thoughts on “PID regulation – Led brightness regulation with Arduino”

  1. how to analyzing kp ki kd ? . I build LED Regulation same with yours, but the graphic difference with yours graphics

      1. Hi,

        Tool – Serial Plotter. If you don’t have it, check that you have the last version.

  2. I have noticed you don’t monetize your website, don’t waste your traffic, you can earn extra bucks every month because
    you’ve got hi quality content. If you want to know how to make extra
    $$$, search for: Boorfe’s tips best adsense alternative

  3. Thank you for this helpful example. A am new to Arduino and was looking for a PID example that could be made easily with the components in a basic learner kit. The only thing i had to change was to use a photoresistor instead of the light sensor for input. But it was used with a 1k resistor, so range mapping is almost the same.
    Great job making a simple easy to understand demo of the PID concept. …now to think about tuning those k values

Leave a Reply

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