A proportional–integral–derivative controller (PID controller or
three-term controller) is a control loop mechanism employing feedback
that is widely used in industrial control systems and a variety of
other applications requiring continuously modulated control. A PID
controller continuously calculates an error value e(t) as the
difference between a desired setpoint (SP) and a measured process
variable (PV) and applies a correction based on proportional, integral,
and derivative terms (denoted P, I, and D respectively), hence the name.
2.
The
simplest PID control setup - the photocell and the LED.
Connect the Arduino board, the photocell, the LED, and the resistors as
shown in the following schematic:
The photocell
shows very
large resistance in dark. The stronger the light it receives, the
lower the internal resistance it has. By sensing the voltage at the
bottom pin of the photocell in the schematic above, the voltage at A0
increases as the light gets more intense and vice versa.
Test the ambient
light
intensity. Keep in mind that the circuit setup doesn't have an 'Ambient
Light Dimmer'. You cannot make your ambient light intensity weaker
than what you have (it is from the sun!). At a different time point (it
receives different amount of light during different time of the day)
you
are testing your circuit, you
must test the ambient light first before
you move forward.
If the ambient ligh intensity is very strong and easily saturates your
photocell, you may use a box to cover your photocell to block some of
the light.
In the following example, I did this experiment at noon, it was very
bright in the room, the ambient light intensity received by the
photocell is 677 (0-1023).
In my PID
controller, the
setpoint must be larger than this value because I can not make it
dimmer, the only thing the external LED can do is add more light.
Now, I will turn on the LED to the brightest level and see what is the
maximum value being receied by the photocell:
Is this correct?
Remember the
Arduino board is
running at 16M Hz, from 'digitalWrite(3,255)' to 'int
ambientLight=analogRead(A0)' may only take several microseconds. Before
the LED is being turned on to the full brightness, the 'ananlogRead'
function has been executed and the light intensity being read to the
CPU is smaller than the real value.
So, we need a
time delay
after the 'digitalWrite()' function:
After the delay
function is
added, the intensity is a lot higher than the previous one, and it
reflects the real light being received by the photocell.
Now I know my
current ambient
light intensity is 677 and the brightest light my LED can provide plus
the ambient light is 924. I'll set the SP (set point) to the middle of
these two values: 800.
Now let's look
at the the
following code to implement the PID controller.
(Note that I did
not use the
Ki*I so I've to integrate the PID_value to make it work, which is
PID_value=PID_value+Kp*p+Ki*I+Kd*D. If you have a non-zero Ki value,
you can directlly use PID_value=Kp*P+Ki*I+Kd*D)
The set point is
400 but the
ambient light is already way above the setpoint. The system will never
be able to reach the set point!
Task 1: Fix
the code above to make the sensed light oscillate around the setpoint
(use an appropriate setpoint).
Complete the blocked line for the 'PID_value'.
Example:
3.
Add an
extra LED to change the
ambient light
We can add an
extra LED light
beside the photocell to see the respose
of the PID controller:
Connect the
following
circuit. Use a pushbutton to turn on/off the LED.
Now, change Kp
to 0.001. Run
the program, turn on/off the LED and
observe what the real-time plot looks like:
At 0:03, I
turned on the
extra LED (hold the push buton) so the signal
being received the photocell is more than the SP. The PID controller
generates a negative error to reduce the light from the original LED to
bring the intensity back to the set point. At 0:20, I release the push
button to turn off the extra LED. The PID controller must send more
power to the original LED to bring the light intensity back to the set
point.
Aparently the
'P' gain is too
low. I changed it to 'Kp=0.1', it looks
like this: At 0:03, I
pressed the
pushbutton to turn on the LED and held it. At 0:06, I released the
pushbutton to turn off the LED.
Task 2: Repeat the work in this
section.
Save the data in a local drive and plot your data use Python and
present your data in your report. Show clear X/Y axis, labels, and
titles. Record and plot
data using
Python can be found in this link: http://yilectronics.com/Courses/CE232/Spring2019/lectures.html Refer to the
lectures on
Aprial 12th for how to save your data to your local drive. Refer to the
lectures on March 1st and March 11th for plotting/presenting your data
using Python.
4.
Setpoint tracking
The set point
can be a
variable and your system must be adjusted to follow the set point in
real-time.
Add an extra
pushbutton to
your system, every time you push the button to trigger activate a new
setpoint, the board will detect a
signal and the PID system will adjust the setpoint to a new value.
A function
'setPointChange()'
was added to the script. I was trying to add 10 to the LED intensity
every time I push the button. However, this code won't make it.
Keep in mind
that the CPU
runs at 16M Hz, the mechanical pushbutton won't give you a clear step
function but a lot of bounces. Also, how can you make your code only
detect one 'push' when you push it? You finger definitely cannot push
it at the similar rate (16M Hz), which means when you push it even
though you think you did it fast, the loop() function has been executed
for thousands of times.
Task
3: Fix the setPointChange()
function to enable the desired PID function as follows. Plot both the
SP and the sensor data in a same figure using Python. Present your
result in your report.