I've been trying to control an led's brightness with PID. I have a light sensor connected to an analog pin of an Arduino and an LED connected to another pin. I want to dim the led to a point where the value from the light sensor is equal to the setpoint. I'm using this project to gain a better understanding of pid controllers. This is the code
/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/
#include <PID_v1.h>
#define PIN_INPUT A6
#define PIN_OUTPUT 11
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=3;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd,P_ON_M, DIRECT);
void setup()
{
//initialize the variables we're linked to
Input = analogRead(PIN_INPUT);
Setpoint = 100;
//turn the PID on
myPID.SetMode(AUTOMATIC);
Serial.begin(9600);
}
void loop()
{
Input = analogRead(PIN_INPUT);
myPID.Compute();
Serial.print(Input);
Serial.print(" ");
Serial.println(Output);
analogWrite(PIN_OUTPUT, Output);
}
when I upload the code the system oscillates but does not dim the led, it turns it on or off.
an image of the output is attached. The red line is the Output of the PID and the blue line is the light sensor value.
analogRead() just flashes the LED on and off faster than you can see. However analogRead() can see the flickering. You have to be sure that the analog side of your circuit is filtering that out.
In addition to dealing with flickering overhead lights and the on/off nature of analogWrite(), what is your plan for selecting the PID constants?
As an aside, an LED and photosensor is a rather poor choice of system for experimenting with PID. There is no obvious analog to mechanical friction or inertia, leading to a response lag, so there should be no need for Ki and Kd.
A heater attached to a small block with a temperature sensor would be a much better choice.
Unless your light sensor has a very slow response (some LDRs are slow enough), there is no way
a PID can handle your system as the system being controlled is severly non-linear.
Agree about the none linearity of the sensor/led and PWM .
It is worth the OP reading around the subject of control and PID . The non linearity of this setup will , for example, mean a different Kp value is needed at different brightness levels as the loop “ gain” varies - an interesting exercise is to try “ gain scheduling”, but that’s much further on .
Also agree this is a bit of a fast loop and not ideal for learning as lags ( the enemy of PID) through the Arduino will make it hard.
Google’s your friend , there are some good examples out there.
I tried the system with p and d gains of 0 with a i gain of 5, it worked mostly fine. Now i'm using servos and a gyroscope/accelerometer for a plane stability project.