Professional Documents
Culture Documents
Arduino Uno Keeps Header O Ffset Improving The Beginner's PID - Sample Time
Arduino Uno Keeps Header O Ffset Improving The Beginner's PID - Sample Time
People directly interested in whats going on inside the Arduino PID library will
get a detailed explanation.
Anyone writing their own PID algorithm can take a look at how I did things and
borrow whatever they like.
Its going to be a tough slog, but I think I found a not-too-painful way to explain my
code. Im going to start with what I call The Beginners PID. Ill then improve it
step-by-step until were left with an efficient, robust pid algorithm.
This leads pretty much everyone to write the following PID controller:
1 /*working variables*/
long lastTime;
2 unsigned
double Input, Output, Setpoint;
3 double errSum, lastErr;
4 double kp, ki, kd;
5 void Compute()
6 {
/*How long since we last calculated*/
7
unsigned long now = millis();
8
double timeChange = (double)(now - lastTime);
9
10
/*Compute all the working error variables*/
double error = Setpoint - Input;
11
errSum += (error * timeChange);
12
double dErr = (error - lastErr) / timeChange;
13
14
15
16
/*Compute PID Output*/
17
Output = kp * error + ki * errSum + kd * dErr;
18
19
/*Remember some variables for next time*/
20
lastErr = error;
21
lastTime = now;
22}
23
24void SetTunings(double Kp, double Ki, double Kd)
25{
kp = Kp;
26
ki = Ki;
27
kd = Kd;
28}
29
30
Compute() is called either regularly or irregularly, and it works pretty well. This series
isnt about works pretty well though. If were going to turn this code into something
on par with industrial PID controllers, well have to address a few things:
1. Sample Time - The PID algorithm functions best if it is evaluated at a regular
interval. If the algorithm is aware of this interval, we can also simplify some of
the internal math.
2. Derivative Kick - Not the biggest deal, but easy to get rid of, so were going to
do just that.
3. On-The-Fly Tuning Changes - A good PID algorithm is one where tuning
parameters can be changed without jolting the internal workings.
4. Reset Windup Mitigation -Well go into what Reset Windup is, and implement
a solution with side benefits
5. On/Off (Auto/Manual) - In most applications, there is a desire to sometimes
turn off the PID controller and adjust the output by hand, without the controller
interfering
6. Initialization - When the controller first turns on, we want a bumpless
transfer. That is, we dont want the output to suddenly jerk to some new value
7. Controller Direction - This last one isnt a change in the name of robustness per
se. its designed to ensure that the user enters tuning parameters with the correct
sign.
Once weve addressed all these issues, well have a solid PID algorithm. Well also, not
coincidentally, have the code thats being used in the lastest version of the Arduino PID
Library. So whether youre trying to write your own algorithm, or trying to understand
whats going on inside the PID library, I hope this helps you out. Lets get started.
Next >>
UPDATE: In all the code examples Im using doubles. On the Arduino, a double is the
same as a float (single precision.) True double precision is WAY overkill for PID. If the
language youre using does true double precision, Id recommend changing all doubles
to floats.
.
http://www.arduino.cc/playground/Code/PIDLibrary
PID Library
/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/
#include <PID_v1.h>
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
//initialize the variables we're linked to
Input = analogRead(0);
Setpoint = 100;
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
}
PID Library
/********************************************************
* PID Adaptive Tuning Example
* One of the benefits of the PID library is that you can
* change the tuning parameters at any time. this can be
* helpful if we want the controller to be agressive at some
* times, and conservative at others.
in the example below
* we set the controller to use Conservative Tuning Parameters
* when we're near setpoint and more agressive Tuning
* Parameters when we're farther away.
********************************************************/
#include <PID_v1.h>
//Define Variables we'll be connecting to
myPID.Compute();
analogWrite(3,Output);
Como ya sabrn la mayora de los que leen este blog a diario, el algoritmo PID
(o Proporcional Integral Derivativo), es un elemento bastante usado en
sistemas autmatas (de una manera u otra), en los cuales este algoritmo cobra
bastante importancia en las funciones de re-alimentacin, adems de provocar
que la curva de respuesta sea mucho mas suave que si usamos un sistema
alternativo.
La idea es haceros un poco de resumen sobre el panorama de libreras ya
diseadas que nos permitan crear un control PID sencillo (relativamente), sin
tener que programarlo desde 0.
Arduino no se queda atrs!
El PID tiene una frmula, ecuacin, expresin, que nos permite calcular los
parmetros de salida, a partir de unos dados, bsicamente es esta:
Funciones
PID()
Compute()
SetMode()
SetOutputLimits()
SetTunings()
SetSampleTime()
SetControllerDirection()
Ejemplo bsico:
view plaincopy to clipboardprint?
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/
#include
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
//initialize the variables we're linked to
Input = analogRead(0);
Setpoint = 100;
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
}
Enlaces
Descarga la ltima versin
Pgina de ejemplos
Pgina oficial en background de Arduino (Con 2 ejemplos mas!)
Explicacon de la librera y el PID por el autor de dicha libreria
-----------------
Si ests desarrollando un quadcopter pero te encuentras ya con el "problema" de la calibracin del control
PID ests de suerte. He encontrado un interesante enlace al cdigo fuente de un pequeo programa
hecho en Visual Basic 6 que muestra en todo su esplendor cmo funciona un control PID.
Un PID (Proporcional Integral Derivativo) es un mecanismo de control por realimentacin que calcula la
desviacin o error entre un valor medido y el valor que se quiere obtener. Es bsicamente lo que se utiliza
para la estabilizacin de quadcopters, hexacopters etc. Para entender cmo funciona y sobre todo cmo
reacciona cambiando sus parmetros de control, la aplicacin simula un tanque con una entrada de
lquido, una salida y un nivel de lquido que queremos mantener. En funcin del calculo y modificacin de
las tres variables del PID (Proporcional, Integral y Derivada), podremos ver las distintas respuestas del
algoritmo y entenderemos qu hace cada parmetro. Es interesante ver la respuesta del ciclo de
llenado/vaciado segn vamos modificando las variables y nos puede dar una idea de la respuesta que
queremos para nuestro objeto volador.
No os perdais el enlace y ya me contareis qu tal! ;)
PID (Proportional,
Integral, Derivative) Loop
Simulation
Author:
Max Seim
Category: Miscellaneous
Type:
Applications
Difficulty: Intermediate
Version
Compatibility:
http://www.freevbcode.com/ShowCode.asp?ID=3808
sensible al ruido, y la ausencia del proceso integral puede evitar que se alcance al valor
deseado debido a la accin de control.
Contenido
[ocultar]
1 Funcionamiento
o 1.1 Proporcional
o
1.2 Integral
1.3 Derivativo
3 Usos
5 Limitaciones de un control
PID
6 Ejemplos prcticos
7 Aplicaciones / Ejemplo
8 Referencias
9 Enlaces externos
Funcionamiento
Para el correcto funcionamiento de un controlador PID que regule un proceso o sistema
se necesita, al menos:
Proporcional
Artculo principal: Control proporcional
Proporcional.
Integral
Artculo principal: proporcional integral
Integral.
El modo de control Integral tiene como propsito disminuir y eliminar el error en estado
estacionario, provocado por el modo proporcional. El control integral acta cuando hay
una desviacin entre la variable y el punto de consigna, integrando esta desviacin en el
tiempo y sumndola a la accin proporcional. El error es integrado, lo cual tiene la
funcin de promediarlo o sumarlo por un perodo determinado; Luego es multiplicado
por una constante I. Posteriormente, la respuesta integral es adicionada al modo
Proporcional para formar el control P + I con el propsito de obtener una respuesta
estable del sistema sin error estacionario.
El modo integral presenta un desfasamiento en la respuesta de 90 que sumados a los
180 de la retroalimentacin ( negativa ) acercan al proceso a tener un retraso de 270,
luego entonces solo ser necesario que el tiempo muerto contribuya con 90 de retardo
para provocar la oscilacin del proceso. <<< la ganancia total del lazo de control debe
ser menor a 1, y as inducir una atenuacin en la salida del controlador para conducir el
proceso a estabilidad del mismo. >>> Se caracteriza por el tiempo de accin integral en
minutos por repeticin. Es el tiempo en que delante una seal en escaln, el elemento
final de control repite el mismo movimiento correspondiente a la accin proporcional.
El control integral se utiliza para obviar el inconveniente del offset (desviacin
permanente de la variable con respecto al punto de consigna) de la banda proporcional.
Derivativo
Artculo principal: proporcional derivativo
Derivativo.
La accin derivativa se manifiesta cuando hay un cambio en el valor absoluto del error;
(si el error es constante, solamente actan los modos proporcional e integral).
El error es la desviacin existente entre el punto de medida y el valor consigna, o "Set
Point".
La funcin de la accin derivativa es mantener el error al mnimo corrigindolo
proporcionalmente con la misma velocidad que se produce; de esta manera evita que el
error se incremente.
Se deriva con respecto al tiempo y se multiplica por una constante D y luego se suma a
las seales anteriores (P+I). Es importante adaptar la respuesta de control a los cambios
en el sistema ya que una mayor derivativa corresponde a un cambio ms rpido y el
controlador puede responder acordemente.
Usos
Por tener una exactitud mayor a los controladores proporcional, proporcional derivativo
y proporcional integral se utiliza en aplicaciones ms cruciales tales como control de
presin, flujo,fuerza, velocidad, en muchas aplicaciones qumica, y otras variables.
Adems es utilizado en reguladores de velocidad de automviles (control de crucero o
cruise control), control de ozono residual en tanques de contacto.
Ajuste manual
Si el sistema debe mantenerse online, un mtodo de ajuste consiste en establecer
primero los valores de I y D a cero. A continuacin, incremente P hasta que la salida del
lazo oscile. Luego establezca P a aproximadamente la mitad del valor configurado
previamente. Despus incremente I hasta que el proceso se ajuste en el tiempo requerido
(aunque subir mucho I puede causar inestabilidad). Finalmente, incremente D, si se
necesita, hasta que el lazo sea lo suficientemente rpido para alcanzar su referencia tras
una variacin brusca de la carga.
Un lazo de PID muy rpido alcanza su setpoint de manera veloz. Algunos sistemas no
son capaces de aceptar este disparo brusco; en estos casos se requiere de otro lazo con
un P menor a la mitad del P del sistema de control anterior.
Ejemplos prcticos
Se desea controlar el caudal de un flujo de entrada en un reactor qumico. En primer
lugar se tiene que poner una vlvula de control del caudal de dicho flujo, y un
caudalmetro, con la finalidad de tener una medicin constante del valor del caudal que
circule. El controlador ir vigilando que el caudal que circule sea el establecido por
nosotros; en el momento que detecte un error, mandar una seal a la vlvula de control
de modo que esta se abrir o cerrar corrigiendo el error medido. Y tendremos de ese
modo el flujo deseado y necesario. El PID es un clculo matemtico, lo que enva la
informacin es el PLC.
Se desea mantener la temperatura interna de un reactor qumico en su valor de
referencia. Se debe tener un dispositivo de control de la temperatura (puede ser un
calentador, una resistncia elctrica,...), y un sensor (termmetro). El P, PI o PID ir
controlando la variable (en este caso la temperatura). En el instante que esta no sea la
correcta avisar al dispositivo de control de manera que este acte, corrigiendo el error.
De todos modos, lo ms correcto es poner un PID; si hay mucho ruido, un PI, pero un P
no nos sirve mucho puesto que no llegara a corregir hasta el valor exacto.
Aplicaciones / Ejemplo
Un ejemplo muy sencillo que ilustra la funcionalidad bsica de un PID es cuando una
persona entra a una ducha. Inicialmente abre la llave de agua caliente para aumentar la
temperatura hasta un valor aceptable (tambin llamado "Setpoint"). El problema es que
puede llegar el momento en que la temperatura del agua sobrepase este valor as que la
persona tiene que abrir un poco la llave de agua fra para contrarrestar el calor y
mantener el balance. El agua fra es ajustada hasta llegar a la temperatura deseada. En
este caso, el humano es el que est ejerciendo el control sobre el lazo de control, y es el
que toma las decisiones de abrir o cerrar alguna de las llaves; pero no sera ideal si en
lugar de nosotros, fuera una maquina la que tomara las decisiones y mantuviera la
temperatura que deseamos?
Esta es la razn por la cual los lazos PID fueron inventados. Para simplificar las labores
de los operadores y ejercer un mejor control sobre las operaciones. Algunas de las
aplicaciones ms comunes son:
The picture above illustrates the 4 base cases that we can get out of the simple
version of an H-Bridge. The two cases that interest us are when A & D are both 1 and
when B & C are both 1.
When A & D are 1 current from the battery will flow from point A through the
motor to D's ground. However for the case when B & C are both 1, current will flow in
the opposite direction from B through the motor to C's ground.
LMD18245 Pinout
Gadgets powered by
Google
.
.
Con el motivo de la primera VirtualCamp (Julio 2011), el proyecto ha sido
crear una maqueta de control didctica con un presupuesto de menos de 10
euros (Arduino no incluido). La idea fue hacer un proyecto en 48h durante el
fin de semana del 16-17 de Julio.
El proceso elegido es el control de temperatura. Para ello dos resistencias de
potencia generan el calor y un ventilador actua como control para la
refrigeracin. Un sensor resistivo de tipo NTC se encarga de registrar la
temperatura del habitculo.
Se ha instalado el sensor de temperatura en medio de las resistencias de
potencia para que el proceso disponga de la menor inercia posible, y as se
comporte ms rpido ante cambios de la entrada.
Componentes necesarios:
Transistor Mosfet.
Diodo 1N4148.
Un recipiente (habitculo).
Vemos una foto de como ha quedado la maqueta (se ha usado una dremel
para modificar el recipiente de plstico):
INTRODUCCIN
3.- Control derivativo (D): produce una seal de control que es proporcional
a la rapidez con la que cambia el error. Ante un cambio rpido de la seal de
error, el controlador produce una seal de correccin de gran valor; cuando
el cambio es progresivo, slo se produce una seal pequea de correccin.
El control derivativo se puede considerar un control anticipativo porque al
medir la rapidez con que cambia el error se anticipa a la llegada de un error
ms grande y se aplica la correccin antes que llegue. El control derivativo
no se usa solo, siempre va en combinacin con el control proporcional y/o
con el control integral.
4.- Control integral (I): produce una accin de control que es proporcional a
la integral del error en el tiempo. En consecuencia, una seal de error
constante producir una seal correctora creciente y aumentar si el error
continua. El control integral se puede considerar que recuerda la situacin
anterior, suma todos los errores y responde a los cambios que ocurren.
CONTROL PID
El control Proporcional Integral Derivativo (PID) es mecanismo de control
mediante realimentacin negativa, el cual aplica una accin correctora al
sistema para obtener el valor de consigna (Setpoint).
Existe multitud de recursos en internet acerca del mismo, por lo que aqu se
ver desde el punto de vista prctico. Por ejemplo, wikipedia dispone de una
buena introduccin.
El nuestro sistema:
La parte integral consigue que nuestro sistema alcance los valores objetivo
(Set Points de 60 y 58 grados), ya que corrige el error permanente del
sistema.
out there about using a feedback loop to position a motor, and of course there was. It
turns out that the classic way of doing this is through a PID servo controller
(Proportional, Integral, Derivative). At its simplest this method can be thought of as a
way to use the difference between where the motor should be and where it is
(error), plus the speed at which the error is changing, plus the sum of past errors to
manage the speed and direction that the motor is turning.
Ok, so I have to say at this point, that I am not an engineer. I did take an engineering
calc. class or two, but that was more then 25 years ago, and I never much
understood it even then. So all I really have to go on is my intuition about how this is
working, a few good explanations, and some example code. As always , Google is
your friend. If you do have a good understanding I would welcome your comments!
The first resource I found was this exchange on the Arduino forums and then followed
through to an article that really explained what was going on here at
embedded.com.
After reading the embedded.com article a few times I put together some simple
code, and was amazed to find that the thing worked almost perfectly the first time.
The key elements of the code look like this
int val = analogRead(potPin); // read the potentiometer value (0 1023)
int target = map(val, 0, 1023, 0, 3600);// set the seek to target by
mapping the potentiometer range to the encoder max count
int error = encoder0Pos - target; // find the error term = current
position - target
// generalized PID formula
//correction = Kp * error + Kd * (error - prevError) + kI * (sum of
errors)
around. This is a way to figure out how fast the error is changing, and is the
Derivative term of the equation, and you can think of it a bit like looking into the
future. If the error rate is changing fast then we are getting close to where we want
to be FAST and we should think about slowing down. This helps dampen the
oscillation from the position term by trying to slow us down faster if we are
approaching the target too quickly. Again, we multiply the value by a constant to
amplify it enough to matter.
6. lastly add in the sum of all past errors multiplied by a constant gain. This is the
Integral term, and is like looking at our past performance and learning from our
mistakes. The further off we were before, the bigger this value will be. If we were
going too fast then it will try to slow us, if to slowly, then it speeds us up.
7. set the lastError to the current error, and add the current error to our sum.
The resulting motorSpeed value will be a signed integer. Since the Adafruit controller
takes an unsigned int as its speed value I do a little more manipulation to figure out
the direction and get a abs() value for the speed, but that part is all pretty easy.
As I said, it seems really simple for such a complicated process. It turns out that the
geared motor from the ink jets is much easier to control that some other mechanical
systems. The physics of its gears, and the performance curve of the simple DC motor
mean that you can be pretty far off on your tuning and it will still end up in the right
place (eventually). If we were trying to do extremely precise positioning, or make it
all work really fast, or handle huge inertial loads, then it would need to be a lot
more robust. I am still working on "tuning " the configuration (i.e. slowly changing
the 3 constant parameters one-by-one until it works best) and I will write more about
that later.
In the mean time here is the code. Bear in mind that it is designed for use with the
Adafruit controller and library. You will also most likely find that it does not work
well with the constants I have chosen*. In that case you will need to do some tuning
yourself. Stay tuned (hah) and I will show you how I did it.
*discerning readers of code will notice that the Kd constant is 0 meaning that this is
actually a PI controller. I found that while the Derivative made the motor settle into
position faster, it also injected an enormous amount of noise and jitter. This is due in
part to the cheap, noisy, and non-linear potentiometer I am using. I need to do some
more experimenting before I can really call it a complete PID.
Oh yeah, if you are taking apart an ink jet you may find these Optical Encoder
datasheets to be valuable. These are specific to Agilent parts, but I have found they
all share pretty much the same pin-outs.
The resulting motorSpeed value will be a signed integer. Since the Adafruit controller
takes an unsigned int as its speed value I do a little more manipulation to figure out
the direction and get a abs() value for the speed, but that part is all pretty easy.
As I said, it seems really simple for such a complicated process. It turns out that the
geared motor from the ink jets is much easier to control that some other mechanical
systems. The physics of its gears, and the performance curve of the simple DC motor
mean that you can be pretty far off on your tuning and it will still end up in the right
place (eventually). If we were trying to do extremely precise positioning, or make it
all work really fast, or handle huge inertial loads, then it would need to be a lot
more robust. I am still working on "tuning " the configuration (i.e. slowly changing
the 3 constant parameters one-by-one until it works best) and I will write more about
that later.
In the mean time here is the code. Bear in mind that it is designed for use with the
Adafruit controller and library. You will also most likely find that it does not work
well with the constants I have chosen*. In that case you will need to do some tuning
yourself. Stay tuned (hah) and I will show you how I did it.
*discerning readers of code will notice that the Kd constant is 0 meaning that this is
actually a PI controller. I found that while the Derivative made the motor settle into
position faster, it also injected an enormous amount of noise and jitter. This is due in
part to the cheap, noisy, and non-linear potentiometer I am using. I need to do some
more experimenting before I can really call it a complete PID.
Oh yeah, if you are taking apart an ink jet you may find these Optical Encoder
datasheets to be valuable. These are specific to Agilent parts, but I have found they
all share pretty much the same pin-outs.
http://pdf1.alldatasheet.com/datasheet-pdf/view/164530/HP/HEDS-9710.html
http://pdf1.alldatasheet.com/datasheet-pdf/view/163090/HP/HEDS-974X.html
L A B E L S : A R D U I N O , E L E C T R O N I C S , M O TOR C O N T R O L , P I D , S C R O U N G I N G
PID Library
/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/
#include <PID_v1.h>
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
//initialize the variables we're linked to
Input = analogRead(0);
Setpoint = 100;
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
}