Go Down

Topic: Problema en control de tensión con librería fastPID (Read 248 times) previous topic - next topic

Agus123

Hola gente, estaba queriendo implementar un sistema de control para luego usarlo en una fuente de alimentación regulable en tensión y corriente, en un principio hice mi propio código con unos if pero era muy inestable, entonces pensé en emplear un control PID y para ello utilice una librería llamada FastPID (LINK) como salida utilice un DAC MCP4725 y como ADC utilice un ADS1115, y el circuito es simplemente la salida de DAC conectado a una de las entradas del ADC, bueno ahora el problema, funciona bastante bien pero por algún motivo cuando el setpoint supera un valor de 300 deja de funcionar y es el valor máximo que obtengo a la salida, quisiera saber porque ese es el limite y como puedo subirlo.

Codigo:
 
Code: [Select]

#include <FastPID.h>
#include <Wire.h>     // libreria para bus I2C
#include <Adafruit_GFX.h>   // libreria para pantallas graficas
#include <Adafruit_SSD1306.h>   // libreria para controlador SSD1306
#include <Adafruit_ADS1015.h>  // libreria Ads1115
#include <Adafruit_MCP4725.h> // libreria Dac Mcp4725


#define PIN_INPUT     A0
#define PIN_SETPOINT  A1

 
#define ANCHO 128     // reemplaza ocurrencia de ANCHO por 128
#define ALTO 64       // reemplaza ocurrencia de ALTO por 64

#define OLED_RESET 4      // necesario por la libreria pero no usado
Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET);  // crea objeto

Adafruit_ADS1115 ads; // Seleccionamos el Ads1115
Adafruit_MCP4725 dac;

float setp=310.0;
int hola=0;

float Kp=0.05, Ki=0.5, Kd=0, Hz=5;
int output_bits = 12;
bool output_signed = false;

FastPID myPID(Kp, Ki, Kd, Hz, output_bits, output_signed);

void setup() {
  Wire.begin();         // inicializa bus I2C
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // inicializa pantalla con direccion 0x3C
  //ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 0.0625mV
  ads.begin();              //Inicializamo el ADC
  dac.begin(0x60);          //Inicializamos el DAC
    oled.setTextColor(WHITE);   // establece color al unico disponible
bool  setOutputRange ( int16_t min, int16_t max);
}
 
void loop() {



      int16_t V_shunt;
      float multiplier = 0.1875F;             //Multiplicador, depende segun la ganancia del ADC

      V_shunt = ads.readADC_Differential_2_3();     //Medimos la tension en modo diferencial entre el canal 2 y 3 del ads115
      float Tension = (V_shunt * multiplier);  //Multiplicamos V_shunt por la R shunt para obtener la corriente

  int setpoint = setp;
  int feedback = Tension;
  uint32_t before, after;
  before = micros();
  uint8_t output = myPID.step(setpoint, feedback);
  after = micros();


 
dac.setVoltage(output, false);            //Seteamos la tension de salida del DAC   

Mostrar(Tension);

}


void Mostrar(float Tension){

  oled.clearDisplay();      // limpia pantalla     
  oled.drawRect(0, 0, 128, 64, WHITE); //x-y-ancho-alto  dibuja rectangulo
  oled.setCursor(2, 2);   // ubica cursor en coordenadas que queremos escribir
  oled.setTextSize(1); 
  oled.println("ADS1115 y MCP4725");
  oled.println("_____________________");

   
  oled.setTextSize(2);
  oled.print("S:");
  oled.print(setp);
  oled.setCursor(2, 49);   
  oled.setTextSize(2);     

  oled.print(Tension);     
  oled.print(" mV");
  oled.display();     // muestra en pantalla todo lo establecido anteriormente

}


Gracias por su atención.

surbyte

Que es lo inestable?
Empieza explicando tu problema porque asi como lo planteas no tiene mucho sentido.

Diagrama en bloques, esquema a mano alzada, foto, lo subes, lees como se postea una imagen la vemos y respondemos.

tauro0221

Hi,

Yo no se mucho de programacion pero creo que aqui hay un problema. En el programa tu tienes las siguentes instruciones.

Code: [Select]
uint8_t output = myPID.step(setpoint, feedback);
after = micros();
dac.setVoltage(output, false);            //Seteamos la tension de salida del DAC


Si te fijas tienes la variable output como de un byte y esta variable la usas para la salida del dac. Por lo tanto te va a dar una salida maxima de 256. Me parece que debes de cambiarla a uint16_t. Yo no se si es correcto pues yo no uso esa forma de definir las variables. Yo uso unsigned int. La salida del dac es de 4096.

Agus123

#3
Oct 21, 2019, 09:01 pm Last Edit: Oct 21, 2019, 09:34 pm by surbyte Reason: Visualización de imágenes
@tauro0221

El problema era que la salida no daba un valor superior a 300mV pero como dijo tauro0221 el problema estaba en la variable output que estaba mal declarada.

Igualmente cuando pongo valores superiores a 1000mv de setpoint nunca estabiliza la salida y queda oscilando continuamente, no se porque puede ser que pase esto.

Adjunto el esquema de conexiones:




surbyte

Observa por favor las correcciones que te hice.
1. No repitas lo que se lee arriba, citas a la persona con un simple @Nick
2. Las imagenes deben visualizarse.
Leiste parcialmente las normas del foro, dale un repaso por favor.

Go Up