▷ #TSCLab #TCLab #ESP32 #Arduino #Control #MACI
En el siguiente blog se presenta la trigésima primera práctica del laboratorio de control de temperatura y velocidad de un motor.
Objetivo general:
- Embeber un sistema de control PID para la temperatura del TSC-Lab
Materiales:
- TSC-Lab
Introducción:
Una de las alternativas para implementar un sistema de control dentro del ESP-32 es mediante un controlador PID. En la presente práctica se usará el propuesto por Ziegler Nichols.
Procedimiento:
Nota: se asume que todas las librerías han sido previamente instaladas. Además se cree que la función de transferencia del sistema ya se lo tiene por lo que se procederá a cambiar los valores tanto de la ganacia, tau y retardo del código.
- Copiar y cargar el siguiente código al TSC-Lab.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
****************************** TSC-Lab ******************************* | |
***************************** PRACTICE 31 **************************** | |
This practice is about SISO using temperature sensor | |
By: Kevin E. Chica O | |
Reviewed: Víctor Asanza | |
More information: https://tsc-lab.blogspot.com/ | |
More examples: https://github.com/vasanza/TSC-Lab | |
Dataset: http://ieee-dataport.org/4138 | |
*/ | |
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
// Definiciones componentes de la tarjeta | |
#define sensor1 4 //DS18B20 left | |
#define sensor2 0 //DS18B20 right | |
#define heater1 17 //TIP31C left | |
#define heater2 16 //TIP31C right | |
#define hot 18 //Led | |
// temperature sensor | |
//GPIO pin 0 as sesnsor 1 is set as OneWire bus | |
OneWire ourWire1(sensor1); | |
//GPIO pin 4 as sensor2 is set as OneWire bus | |
OneWire ourWire2(sensor2); | |
//A variable or object is declared for our sensor 1 | |
DallasTemperature sensors1(&ourWire1); | |
//A variable or object is declared for our sensor 2 | |
DallasTemperature sensors2(&ourWire2); | |
//Variables Globales | |
float temp1, aux; //Temperature of Heater 1 | |
float r1 = 0.0; //reference of Heater 1 | |
volatile float u = 0.0, u_1 = 0.0; //control action | |
byte Ts = 8; //Sampling period (seconds) | |
//PID parameters | |
float kp, ti, td; | |
float q0, q1, q2; | |
volatile float e = 0.0, e_1 = 0.0, e_2 = 0.0; | |
float k = 1.04, tau = 160, theta = 10 + Ts / 2; //System Model Parameters | |
String dato; | |
// setting PWM properties | |
const int freq = 5000; | |
const int ledChannel = 0; | |
const int resolution = 8; | |
//interrupt funtion | |
volatile int interruptCounter; | |
int totalInterruptCounter; | |
hw_timer_t * timer = NULL; | |
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; | |
void IRAM_ATTR onTimer() { | |
portENTER_CRITICAL_ISR(&timerMux); | |
interruptCounter++; | |
portEXIT_CRITICAL_ISR(&timerMux); | |
} | |
//PID function | |
void PID(void) | |
{ | |
e = (r1 - temp1); | |
// Controle PID | |
u = u_1 + q0 * e + q1 * e_1 + q2 * e_2; //Ley del controlador PID discreto | |
if (u >= 100.0) // control saturated action 'uT' at a maximum and minimum limit | |
u = 100.0; | |
if (u <= 0.0 || r1 == 0) | |
u = 0.0; | |
// Return to real values | |
e_2 = e_1; | |
e_1 = e; | |
u_1 = u; | |
// The calculated action is transformed into PWM | |
ledcWrite(ledChannel, map(u, 0, 100, 0, 255)); | |
} | |
void setup() { | |
//interruption | |
timer = timerBegin(0, 80, true); | |
timerAttachInterrupt(timer, &onTimer, true); | |
timerAlarmWrite(timer, 8000000, true);//change time in us | |
timerAlarmEnable(timer); | |
// configure LED PWM functionalitites | |
ledcSetup(ledChannel, freq, resolution); | |
// attach the channel to the GPIO to be controlled | |
ledcAttachPin(heater1, ledChannel); | |
pinMode(hot, OUTPUT); //Led "Caliente" como salida | |
digitalWrite(hot, LOW); | |
Serial.begin(115200); | |
//wait 10 seconds when start for first time | |
delay(10000); | |
r1 = 32.0;// reference point | |
//ZIEGLER and NICHOLS | |
kp = (1.2 * tau) / (k * theta); | |
ti = 2.0 * theta; | |
td = 0.5 * theta; | |
//Digital PID | |
// Calculo do controle PID digital | |
q0 = kp * (1 + Ts / (2.0 * ti) + td / Ts); | |
q1 = -kp * (1 - Ts / (2.0 * ti) + (2.0 * td) / Ts); | |
q2 = (kp * td) / Ts; | |
} | |
void loop() { | |
if (interruptCounter > 0) { | |
portENTER_CRITICAL(&timerMux); | |
interruptCounter--; | |
portEXIT_CRITICAL(&timerMux); | |
digitalWrite(hot, !digitalRead(hot)); //Led Toggle | |
PID(); | |
} | |
int i, ini = 0, fin = 0; | |
//Filtro de promedio movil en la lectura ADC | |
aux = 0; | |
for (i = 0; i < 10; i++) { | |
//The command is sent to read the temperature | |
sensors1.requestTemperatures(); | |
aux = aux + (float(sensors1.getTempCByIndex(0))); | |
//delay(5); | |
} | |
temp1 = aux / 10.0; | |
//temp1= float(sensors1.getTempCByIndex(0); | |
Serial.println("Temperatura_1,Setpoint_1"); | |
Serial.print(temp1); | |
Serial.print(","); | |
Serial.println(r1); | |
delay(1000); | |
} |
Repositories: https://github.com/vasanza/TSC-Lab/tree/main/Practice31
Comments
Post a Comment