jueves, 21 de enero de 2016

Obtener valores de PID con componente AT PID y configurar temperatura.

Al final del tutorial se dejarán todos los archivos que se necesitan para poder hacer funcionar la configuración de la impresora 3d con Machinekit. 

En este tutorial se va ha explicar como funciona el componente AT PID para poder calibrar los extrusores de una impresora 3d, para la cama caliente se realiza de la misma manera pero considerando algunos cambios que también se explicarán.

Lo primero que se debe realizar es configurar el Device Tree Overlay para que inicie cuando se prenda la Beaglebone Black, con esto se evita que se calienten los extrusores y cama caliente, mientras no se inicie Machinekit (LinuxCNC).

//This source file is provided under MIT License terms.
//Copyright (c) 2013 Calypso Ventures, Inc.
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

/dts-v1/;
/plugin/;

/ {
 compatible = "ti,beaglebone", "ti,beaglebone-black";

 /* identification */
 part-number = "BBB-LCNC-MF5";
 version = "00A0";

 /* state the resources this cape uses */
 exclusive-use =
  /* the pin header uses */
/*  "J8.3",        gpio1_6  eMMC*/
/*  "J8.4",        gpio1_7  eMMC*/
/*  "J8.5",        gpio1_2  eMMC*/
/*  "J8.6",        gpio1_3  eMMC*/
  "J8.7",     /* gpio2_2 -> Libre*/
  "J8.8",     /* gpio2_3 -> Libre*/
  "J8.9",     /* gpio2_5 -> Libre*/
  "J8.10",    /* gpio2_4 -> Libre*/
  "J8.11",    /* gpio1_13-> lcd R1 -> Libre*/
  "J8.12",    /* gpio1_12-> lcd G1 -> Libre*/
  "J8.13",    /* gpio0_23-> lcd G0 -> Libre*/
  "J8.14",    /* gpio0_26-> lcd R0 -> Libre*/
  "J8.15",    /* gpio1_15-> lcd R2 -> Libre*/
  "J8.16",    /* gpio1_14-> lcd B2 -> Libre*/
  "J8.17",    /* gpio0_27-> lcd B1 -> Libre*/
  "J8.18",    /* gpio2_1 -> Libre*/
  "J8.19",    /* gpio0_22-> lcd B0 -> Libre*/
/*  "J8.20",       gpio1_31  eMMC*/
/*  "J8.21",       gpio1_30  eMMC*/
/*  "J8.22",       gpio1_5   eMMC*/
/*  "J8.23",       gpio1_4   eMMC*/
/*  "J8.24",       gpio1_1   eMMC*/
/*  "J8.25",       gpio1_0   eMMC*/
  "J8.26",    /* gpio1_29-> Libre*/
/*  "J8.27",       gpio2_22-> lcd VSYNC*/
/*  "J8.28",       gpio2_24-> lcd PCLK*/
/*  "J8.29",       gpio2_23-> lcd HSYNC*/
/*  "J8.30",       gpio2_25-> lcd DE*/
/*  "J8.31",       gpio0_10-> lcd B6*/
/*  "J8.32",       gpio0_11-> lcd B7*/
/*  "J8.33",       gpio0_9 -> lcd B5*/
/*  "J8.34",       gpio2_17-> lcd B3*/
/*  "J8.35",       gpio0_8 -> lcd B4*/
/*  "J8.36",       gpio2_16-> lcd G7*/
/*  "J8.37",       gpio2_14-> lcd G5*/
/*  "J8.38",       gpio2_15-> lcd G6*/
/*  "J8.39",       gpio2_12-> lcd G3*/
/*  "J8.40",       gpio2_13-> lcd G4*/
/*  "J8.41",       gpio2_10-> lcd R7*/
/*  "J8.42",       gpio2_11-> lcd G2*/
/*  "J8.43",       gpio2_8 -> lcd R5*/
/*  "J8.44",       gpio2_9 -> lcd R6*/
/*  "J8.45",       gpio2_6 -> lcd R3*/
/*  "J8.46",       gpio2_7 -> lcd R4*/
  
  "J9.11",    /* gpio0_30-> Libre*/
  "J9.12",    /* gpio1_28-> Libre*/
  "J9.13",    /* gpio0_31-> Libre*/
/*  "J9.14",       gpio1_18-> LCD ehrpwm1A*/
  "J9.15",    /* gpio1_16-> Libre*/ 
  "J9.16",    /* gpio1_19-> Libre*/
/*  "J9.17",       gpio0_5 -> spi0_cs0*/
/*  "J9.18",       gpio0_4 -> spi0_d1*/
/*  "J9.19",       gpio0_13-> EEPROM/I2C*/
/*  "J9.20",       gpio0_12-> EEPROM/I2C*/
/*  "J9.21",       gpio0_3 -> spi0_d0*/
/*  "J9.22",       gpio0_2 -> spi0_sclk*/
  "J9.23",    /* gpio1_17-> Libre*/
  "J9.24",    /* gpio0_15-> Libre*/
  "J9.25",    /* gpio3_21-> Libre*/
  "J9.26",    /* gpio0_14-> Libre*/
  "J9.27",    /* gpio3_19-> Libre*/
  "J9.28",    /* gpio3_17-> Libre*/
  "J9.29",    /* gpio3_15-> Libre*/
  "J9.30",    /* gpio3_16-> Libre*/
  "J9.31",    /* gpio3_14-> Libre*/
  "J9.41",    /* gpio3_20-> Libre*/
  "J9.42",    /* gpio3_18-> Libre*/
  
  /* the hardware IP uses */
/*  "gpio1_6", */
/*  "gpio1_7", */
/*  "gpio1_2", */
/*  "gpio1_3", */
  "gpio2_2", 
  "gpio2_3", 
  "gpio2_5",  
  "gpio2_4", 
  "gpio1_13", 
  "gpio1_12", 
  "gpio0_23", 
  "gpio0_26", 
  "gpio1_15", 
  "gpio1_14", 
  "gpio0_27", 
  "gpio2_1", 
  "gpio0_22", 
/*  "gpio1_31", */
/*  "gpio1_30", */
/*  "gpio1_5", */
/*  "gpio1_4", */
/*  "gpio1_1", */
/*  "gpio1_0", */
  "gpio1_29", 
/*  "gpio2_22", */
/*  "gpio2_24", */
/*  "gpio2_23", */
/*  "gpio2_25", */
/*  "gpio0_10", */
/*  "gpio0_11", */
/*  "gpio0_9", */
/*  "gpio2_17", */
/*  "gpio0_8", */
/*  "gpio2_16", */
/*  "gpio2_14", */
/*  "gpio2_15", */
/*  "gpio2_12", */
/*  "gpio2_13", */
/*  "gpio2_10", */
/*  "gpio2_11", */
/*  "gpio2_8", */
/*  "gpio2_9", */
/*  "gpio2_6", */
/*  "gpio2_7", */
  
  "gpio0_30",
  "gpio1_28",
  "gpio0_31",
/*  "gpio1_18", */
  "gpio1_16",
  "gpio1_19", 
/*  "gpio0_5",      */
/*  "gpio0_4",      */
/*  "gpio0_13", */
/*  "gpio0_12", */
/*  "gpio0_3", */
/*  "gpio0_2",      */
  "gpio1_17",
  "gpio0_15",
  "gpio3_21",
  "gpio0_14",
  "gpio3_19",
  "gpio3_17",
  "gpio3_15",
  "gpio3_16",
  "gpio3_14",
  "gpio3_20",
  "gpio3_18", 
  
  "pru0";

 fragment@0 {
  target = <&am33xx_pinmux>;
  __overlay__ {

   MF5_gpio_pins: MF5_gpio_pins {
    pinctrl-single,pins = <
/*     0x018     mmc      J8.3   gpio1_6  */       
/*     0x01C     mmc      J8.4   gpio1_7  */       
/*     0x008     mmc      J8.5   gpio1_2  */       
/*     0x00C     mmc      J8.6   gpio1_3  */       
     0x090     0x3F  /* J8.7   gpio2_2  */       
     0x094     0x3F  /* J8.8   gpio2_3  */       
     0x09C     0x3F  /* J8.9   gpio2_5  */       
     0x098     0x3F  /* J8.10  gpio2_4  */       
     0x034     0x3F  /* J8.11  gpio1_13 */       
     0x030     0x3F  /* J8.12  gpio1_12 */       
     0x024     0x3F  /* J8.13  gpio0_23 */       
     0x028     0x3F  /* J8.14  gpio0_26 */       
     0x03C     0x3F  /* J8.15  gpio1_15 */       
     0x038     0x3F  /* J8.16  gpio1_14 */       
     0x02C     0x3F  /* J8.17  gpio0_27 */       
     0x08C     0x3F  /* J8.18  gpio2_1  */       
     0x020     0x3F  /* J8.19  gpio0_22 */       
/*     0x084     mmc      J8.20  gpio1_31 */       
/*     0x080     mmc      J8.21  gpio1_30 */       
/*     0x014     mmc      J8.22  gpio1_5  */       
/*     0x010     mmc      J8.23  gpio1_4  */       
/*     0x004     mmc      J8.24  gpio1_1  */       
/*     0x000     mmc      J8.25  gpio1_0  */       
     0x07C     0x3F  /* J8.26  gpio1_29 */       
/*     0x0E0     0x3F     J8.27  gpio2_22 */       
/*     0x0E8     0x3F     J8.28  gpio2_24 */       
/*     0x0E4     0x3F     J8.29  gpio2_23 */       
/*     0x0EC     0x3F     J8.30  gpio2_25 */       
/*     0x0D8     0x3F     J8.31  gpio0_10 */       
/*     0x0DC     0x3F     J8.32  gpio0_11 */       
/*     0x0D4     0x3F     J8.33  gpio0_9  */       
/*     0x0CC     0x3F     J8.34  gpio2_17 */       
/*     0x0D0     0x3F     J8.35  gpio0_8  */       
/*     0x0C8     0x3F     J8.36  gpio2_16 */       
/*     0x0C0     0x3F     J8.37  gpio2_14 */       
/*     0x0C4     ???      J8.38  gpio2_15 */       
/*     0x0B8     0x3F     J8.39  gpio2_12 */       
/*     0x0BC     0x3F     J8.40  gpio2_13 */       
/*     0x0B0     0x3F     J8.41  gpio2_10 */       
/*     0x0B4     0x3F     J8.42  gpio2_11 */       
/*     0x0A8     0x3F     J8.43  gpio2_8  */       
/*     0x0AC     0x3F     J8.44  gpio2_9  */       
/*     0x0A0     0x3F     J8.45  gpio2_6  */       
/*     0x0A4     0x3F     J8.46  gpio2_7  */       
                                   
     0x070     0x3F  /* J9.11  gpio0_30 */       
     0x078     0x3F  /* J9.12  gpio1_28 */       
     0x074     0x3F  /* J9.13  gpio0_31 */       
/*     0x048     0x3F     J9.14  gpio1_18 */       
     0x040     0x3F  /* J9.15  gpio1_16 */       
     0x04C     0x3F  /* J9.16  gpio1_19 */       
/*     0x15C     0x3F     J9.17  gpio0_5  */       
/*     0x158     0x3F     J9.18  gpio0_4  */       
/*     0x17C     N/C      J9.19  gpio0_13 */       
/*     0x178     N/C      J9.20  gpio0_12 */       
/*     0x154     0x3F     J9.21  gpio0_3  */       
/*     0x150     0x3F     J9.22  gpio0_2  */       
     0x044     0x3F  /* J9.23  gpio1_17 */       
     0x184     0x3F  /* J9.24  gpio0_15 */       
     0x1AC     0x3F  /* J9.25  gpio3_21 */       
     0x180     0x3F  /* J9.26  gpio0_14 */       
     0x1A4     0x3F  /* J9.27  gpio3_19 */       
     0x19C     0x3F  /* J9.28  gpio3_17 */       
     0x194     0x3F  /* J9.29  gpio3_15 */       
     0x198     0x3F  /* J9.30  gpio3_16 */       
     0x190     0x3F  /* J9.31  gpio3_14 */          
     0x1A8     0x3F  /* J9.41  gpio3_20 */       
     0x1A0     0x3F  /* J9.42  gpio3_18  */       
    >;
   };
  };
 };
        
 fragment@1 {
  target = <&ocp>;
  __overlay__ {

   MF5_gpio {
    compatible = "gpio-of-helper";
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&MF5_gpio_pins>;
                                
                                P9_15 {
                                    gpio-name = "P9_15";
                                    gpio = <&gpio2 16 0>;
                                    output;
                                    init-low;
                                    dir-changeable;
                                };

                                P9_26 {
                                    gpio-name = "P9_26";
                                    gpio = <&gpio1 14 0>;
                                    output;
                                    init-low;
                                    dir-changeable;
                                };

   };
                };
 };

        fragment@2 {
                target = <&pruss>;
                __overlay__ {

                        status = "okay";

                };
        };

};


Se añadido un pequeño cambio al archivo BBB-LCNC-MF5-00A0.dts. Al archivo se le añade el control de inicializar los pines P9.15 y P9.26 como salida en estado bajo. Añadiendo los pines mensionados como salida en estado bajo, se evita tener que desconectar la fuente para no calentar los extrusores hasta que inicie Machinekit.

Para poder visualizar los pines se usa el controlador gpio-of-helper. Cada pin necesita un nombre, para poder usar el gpio se debe poner el número de gpio desfasado en 1, finalmente se pone si se quiere usar como salida o entrada. En el caso de ser salida se debe poner si se quiere en estado bajo o alto.

Ejemplo:

 fragment@1 {
  target = <&ocp>;
  __overlay__ {

   MF5_gpio {
    compatible = "gpio-of-helper";
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&MF5_gpio_pins>;
                                //P9.15
                                Extrusor0 {
                                    gpio-name = "MF5:Extrusor0";
                                    gpio = <&gpio2 16 0>;
                                    output;
                                    init-low;
                                    dir-changeable;
                                };
                                //P9.26
                                Extrusor1 {
                                    gpio-name = "MF5:Extrusor1";
                                    gpio = <&gpio1 14 0>;
                                    output;
                                    init-low;
                                    dir-changeable;
                                };

   };
                };
 };

target = <&ocp> -> define que se podrá visualizar la configuración de los pines en la siguiente dirección "/sys/devices/ocp.*/"

compatible = "gpio-of-helper" -> indica que se usará el controlador gpio-of-helper.

pinctrl-names = "default" -> indica que los pines se configurán por defecto.

pinctrl-0 = <&MF5_gpio_pins> -> indica que se va usar los pines configuados en MF5_gpio_pins.

P9_15 y P9_26 son funciones, puede ir con cualquier nombre ejemplo Extrusor0 y Extrusor1.

gpio-name indica el nombre con el que va a apraecer en "/sys/devices/ocp.3/MF5_gpio.*/status"

En gpio se pone el gpio desfasado 1, P9.15 "gpio1_16" quedaría "gpio2 16 0" lo mismo con P9.26.

Se puede poner al gpio como salida o como entrada, input para entrada y output para salida.

Si se usa como salida se puede poner el estado con el cuál se quiere inicializar el gpio, en alto "init-high" o en bajo "init-low".

dir-changeable permite cambiar el gpio como output o input.

Para que inicie al reiniciar, se debe agregar el archivo DTO a /etc/default/capemgr, ver este link para entender mejor DVK530-LCD7.



Al prender o reiniciar la Beaglebone Black se podrá ver la función MF5_gpio con la dirección en salida usando "cat /sys/devices/ocp.*/MF5_gpio.14/status". Para poder obtener el estado del gpio (alto o bajo), se usa "cat /sys/class/gpio/gpio48/value" si se quiere ver el valor de P9.15 gpio1_16 (1*32+16=48). Para P9.26 se realiza lo mismo.

 

Se recomienda ver los siguientes tutoriales para poder entender:

Device Tree Overlay personalizada para Machinekit y LCD 7"
Configurar los pines gpio para usar con Machinekit. 

Como usar el componente AT PID para encontrar los valores de PID.

Para poder usar el componente AT PID se necesita entender como funciona. En el siguiente link At_pid esta la información de como usar este componente.

El componente AT PID inicia por defecto con los siguientes valores.

pin in float deadband = 0.0 "Amount of error that will be ignored";
pin in float maxerror = 0.0 "Limit on error";
pin in float maxerrorI = 0.0 "Limit on error integrator";
pin in float maxerrorD = 0.0 "Limit on error differentiator";
pin in float maxcmdD = 0.0 "Limit on command differentiator";
pin in float maxcmdDD = 0.0 "Limit on command 2nd derivative";

pin io float bias = 0.0 "Constant offset on output";
pin io float Pgain = 1.0 "Proportional gain";
pin io float Igain = 0.0 "Integral gain";
pin io float Dgain = 0.0 "Derivative gain";
pin io float FF0 = 0.0 "Zeroth order Feedfoioard gain";
pin io float FF1 = 0.0 "First order Feedforward gain";
pin io float FF2 = 0.0 "Second order Feedforward gain";
pin io float maxoutput = 0.0 "Limit on output value";
pin io float tuneEffort = 0.5 " Control effort for limit cycle.";
pin io u32 tuneCycles = 50;
pin io u32 tuneType = 0;

pin out float errorI "Integral of error";
pin out float errorD "Derivative of error";
pin out float commandD "Derivative of the command";
pin out float commandDD "2nd derivative of the command";
pin out float ultimateGain "Calc by auto-tune from limit cycle.";
pin io float ultimatePeriod  "Calc by auto-tune from limit cycle.";


pin in bit enable = 0 "Enable/disabled the PID loop";
pin in float command = 0.0 "Commanded value";
pin in float feedback = 0.0 "Feedback input";
pin out float error "Current error";
pin out float output "Ouput value";
pin in bit tuneMode = 0  "0=PID, 1=tune.";
pin io bit tuneStart = 0  "Set to 1 to start an auto-tune cycle. \
                        Clears automatically when the cycle has finished.";

 
Para poder iniciar la calibración automática de PID es necesario que tuneMode sea uno y tuneStart sea uno. Si se quiere obtener los valores de PID es necesario que tuneType sea cero de lo contrario se obtendrá la función PI con FF1 ("para uso de motores").

if(tuneType == TYPE_PID){
            // PID.
            Pgain = (0.6 * ultimateGain);
            Igain = (Pgain / (ultimatePeriod / 2.0));
            Dgain = (Pgain * (ultimatePeriod / 8.0));
            FF1 = 0;
        }else{
            // PI FF1.
            Pgain = (0.45 * ultimateGain);
            Igain = (Pgain / (ultimatePeriod / 1.2));
            Dgain = 0;

            // Scaling must be set so PID output is in user units per second.
            FF1 = 1;
        }

El componente de At_pid usa el método de Ziegler-Nichols para calcular los valores de PID. Los siguientes links indican como funciona esta configuración.

Reglas de Ziegler-Nichols.
Calibrando un controlador PID.
Guía de uso PID para Arduino.

Primero se debe realizar la siguiente configuración en el archivo .hal

# ##################################################
# PWM Signals
# ##################################################

newsig e0.temp.set   float
newsig e0.temp.meas  float
newsig bed.temp.set  float
newsig bed.temp.meas float
newsig e1.temp.set   float
newsig e1.temp.meas  float

setp hpg.pwmgen.00.pwm_period       1000000

#net spindle-speed-cmd <= motion.spindle-speed-out
#net spindle-speed-cmd => hpg.pwmgen.00.out.00.value

# P9.26 gpio0_14 Extrusor 1
setp hpg.pwmgen.00.out.01.pin       0x2E
setp hpg.pwmgen.00.out.01.enable    1
setp hpg.pwmgen.00.out.01.value     0.0

# J9.16 gpio1_19 Bed
#setp hpg.pwmgen.00.out.00.pin       0x53
#setp hpg.pwmgen.00.out.00.enable    1
#setp hpg.pwmgen.00.out.00.value     0.0

# P9.15 gpio1_16 Extrusor 0
setp hpg.pwmgen.00.out.02.pin       0x50
setp hpg.pwmgen.00.out.02.enable    1
setp hpg.pwmgen.00.out.02.value     0.0


# PID for Extruder 0 temperature control
net e0.temp.meas    <= Extruder0.Temp.meas
net e0.temp.meas    => at_pid.0.feedback => wcomp.0.in

sets e0.temp.set  0
net e0.temp.set motion.analog-out-02    => at_pid.0.command

setp wcomp.0.min 0
setp wcomp.0.max 300

net e0.temp.set => Extruder0.Temp.set
net e0.temp.done motion.digital-in-02 <= Extruder0.Temp.set.done

net enable.pid.extrusor0 at_pid.0.enable <= wcomp.0.out
net e0.heater  <= at_pid.0.output
net e0.heater  => limit1.0.in
net e0.heaterl <= limit1.0.out
net e0.heaterl => hpg.pwmgen.00.out.02.value 

# Limit heater PWM to positive values
# PWM mimics hm2 implementation, which generates output for negative values
setp limit1.0.min 0

# PID for Extruder 1 temperature control
net e1.temp.meas    <= Extruder1.Temp.meas
net e1.temp.meas    => at_pid.1.feedback => wcomp.1.in

sets e1.temp.set  0
net e1.temp.set motion.analog-out-03    => at_pid.1.command 

setp wcomp.1.min 0
setp wcomp.1.max 300

net e1.temp.set => Extruder1.Temp.set
net e1.temp.done motion.digital-in-03 <= Extruder1.Temp.set.done

net enable.pid.extrusor1 at_pid.1.enable <= wcomp.1.out
net e1.heater  <= at_pid.1.output
net e1.heater  => limit1.1.in
net e1.heaterl <= limit1.1.out
net e1.heaterl => hpg.pwmgen.00.out.01.value


# Limit heater PWM to positive values
# PWM mimics hm2 implementation, which generates output for negative values
setp limit1.1.min 0

# PID for Bed temperature control
#net bed.temp.meas    <= Therm.ch-05.value
#net bed.temp.meas    => at_pid.2.feedback => wcomp.2.in

#sets bed.temp.set  0
#net bed.temp.set     => at_pid.2.command

#setp wcomp.2.min 0
#setp wcomp.2.max 120

#net enable.pid.bed at_pid.2.enable <= wcomp.2.out
#net bed.heater  <= at_pid.2.output
#net bed.heater  => limit1.2.in
#net bed.heaterl <= limit1.2.out
#net bed.heaterl => hpg.pwmgen.00.out.00.value

# Limit heater PWM to positive values
# PWM mimics hm2 implementation, which generates output for negative values
setp limit1.1.min 0

# PID Parameters for adjusting temperature control
# Extruder0
setp at_pid.0.Pgain  1
setp at_pid.0.Igain  0
setp at_pid.0.Dgain  0
setp at_pid.0.tuneEffort 0.5
setp at_pid.0.tuneMode 1
setp at_pid.0.tuneStart 1
setp at_pid.0.tuneType 0
setp at_pid.0.tuneCycles 50
setp at_pid.0.maxoutput 0.8
#setp at_pid.0.maxerrorI 12
#setp at_pid.0.bias 0.5

# Extruder1
setp at_pid.1.Pgain  1
setp at_pid.1.Igain  0
setp at_pid.1.Dgain  0
setp at_pid.1.tuneEffort 0.5
setp at_pid.1.tuneMode 1
setp at_pid.1.tuneStart 1
setp at_pid.1.tuneType 0
setp at_pid.1.tuneCycles 50
setp at_pid.1.maxoutput 0.8
#setp at_pid.1.maxerrorI 12
#setp at_pid.1.bias 0.5

# Bed
#setp at_pid.2.Pgain  1
#setp at_pid.2.Igain  0
#setp at_pid.2.Dgain  0
#setp at_pid.2.tuneEffort 1
#setp at_pid.2.tuneMode 1
#setp at_pid.2.tuneStart 1
#setp at_pid.2.tuneType 0
#setp at_pid.2.tuneCycles 50
setp at_pid.1.maxoutput 1
#setp at_pid.2.maxerrorI 1.0
#setp at_pid.2.bias    0.5
#setp at_pid.2.enable  1

Pgain, Igain, Dgain, tuneEffort, tuneType, tuneCycles están configurados con los valores por defecto. Se los puede comentar si se desea. Lo más importante es que maxoutput se active cuando el componente at_pid haya encontrado los valores de PID, ya que de lo contrario no funcionará de forma correcta.

Pgain -> Indica la ganancia proporcional, cambiarlo con el valor P calculado.
Igain -> Indica la ganancia integral, cambiarlo con el valor I calculado.
Dgain -> Indica la ganancia derivativa, cambiarlo con el valor D calculado.
tuneEffort -> Indica el ciclo de trabajo enviado a la señal PWM, con valores muy bajos tardará mucho en calentar el extrusor y con valores altos se tendrán unos valores PID un poco inestables. Para los extrusores que calientan de forma rápida es recomendable usar valores de 0.4 a 0.6, mientras que para la cama caliente que demora en calentar usar un valor de 1.0 será perfecto.
tuneMode -> Indica si se va usar la calibración automática (1) o si se va realizar el proceso de control PID como el componente PID (0).
tuneStart -> Indica que se iniciará la calibración, cuando termina el proceso de calibración se desactiva automáticamente y mientras no se cambie el valor de tuneMode a cero no realizará el proceso de control PID con los valores encontrados.
tuneType -> Indica si se va obtener los valores PID (0) o los valores PI FF1(1).
tuneCycles -> Indica cuántos veces va a calcular los valores, entre más ciclos tenga mejor será el resultado final. Usando 30 ciclos se obtiene valores aceptables (varía la temperatura ±2 grados celsius), se recomienda usar 50 o más ciclos (varía la temperatura ±0.25-0.5 grados celsius). El amplificador max31855 tiene una resolución de 0.25 grados celsius con lo cuál sería una calibración casi perfecta (tomar en cuenta que dependiendo el tipo de termocupla se tiene un error comparado con el valor real, generalmente ±2).
maxoutput -> Indica el ciclo de trabajo con el que va a funcionar la señal PWM una vez que se haya terminado la calibración automática. Para el extrusor con un valor de 0.8 se obtiene un calentamiento rápido y un buen control PID, para la cama caliente usar un valor de 1, ya que el proceso de calentamiento es lento. Es importante poner un valor mayor a cero en maxoutput de lo contrario no funcionará de forma correcta el control PID.
maxerrorI -> Indica el error del integrador, es necesario ir aumentando el valor para disminuir el exceso de temperatura.
bias -> Indica cuanto se desea compensar en temperatura, es ideal cuando se obtiene valores menores a la temperatura asignada. Es recomendable dejarlo por defecto en 0.5 e ir compensando con maxerrorI.
enable -> Activa o desactiva el uso de At_pid.

Existen otras funciones del componente At_pid, pero no se usarán, ya que con las mencionadas anteriormente se han obtenido buenos resultados.


En la configuración del componente AT PID se indicará como funcionan los valores de PID obtenidos, y luego como cambia el control al implementar lo valores de bias y maxerrorI.

Se usará el código O descrito en el anterior tutorial para poder asignar el valor de temperatura con el que trabajarán los extrusores.

Obtener valores PID

Para poder obtener los valores correctos de PID se recomienda dejar por defecto la configuración.


Para poder observar las variable se debe ingresar a settings y luego ejecutar Halshow. Aparecerá el cuadro de la derecha que se puede observar en la imagen de abajo.




Como se puede observar la temperatura es de 20.25 para el extrusor0 y los valores de PID están Pgain 1, Igain 0, Dgain 0, bias 0, feedback 20.25 (valor de tempeartura), maxerror 0, maxerrorI 0, maxerrorD 0, maxoutput 0.8 (80% ciclo de trabajo), output -0.5 (apagado el extrusor), tuneCycles 0x32 (50 en decimal), tuneEffort 0.5 (50% cuando se calibra), tuneMode 1, tuneStart 1, tuneType 0 (PID). Los mismos valores son asignados al extrusor1, solo cambia tuneEffort a 0.8 para que pueda llegar a temperaturas mayores de 200 grados.

Al mandar el comando M104 que asigna la temperatura para el extrusor0 y el extrusor1 en el MDI se dará comienzo a la obtensión automática de los valores PID.

En el extrusor0 se determinara un valor de 180 grados celsius, ideal para trabjar con PLA (175-220 grados celsius). Para el extrusor1 se asignará un valor de 230 grados celsius, ideal para trabajar con ABS (210-250 grados celsius).

Para asignar la temperatura al extrusor0 se usa el comando M104 P180, para el extrusor1 M104 P230 T1.


En este momento los extrusores estarán calentando hasta llegar al valor de temperatura asignado y comenzará el proceso de obtener los valores de PID para los dos extrusores.



El proceso dura alrededor de unos 10 minutos para una temperatura menor a 200 grados celsius con un ciclo de trabajo de 0.5, para el segundo extrusor dura alrededor de 15 minutos con una temperatura de 230 y un ciclo de trabajo de 0.8. Esto ocurre ya que tardá mas en calentar por el ciclo de trabajo de 0.8 con lo que cada conteo tardá de subir de 227 a 230, al bajar y subir es un ciclo de conteo realizado.

Cuando el proceso termina el calentamiento de los dos extrusores termina (se pone en Standby), esto pasa ya que tuneStart esta desactivado pero tuneMode aún sigue en 1.


Si se desea realizar el control PID se debe cambiar la variable tuneMode a 0 para que comience el proceso. Esto se lo realiza usando el comando setp y la variable que querramos cambiar.

Extrusor0 => setp at_pid.0.tuneMode 0
Extrusor1 => setp at_pid.1.tuneMode 0



En el Extrusor0 con los valores de PID obtenidos cambia la temperatura entre 177 y 182.25, en el extrusor1 cambia la temperatura entre 219 y 234. Como se puede observar los valores no están muy mal pero lo que se requiere es que la temperatura que controla el componente AT PID no baje de la asiganada. Para eso lo que se debe realizar es configurar el bias a 0.5 para compensar la temperatura e ir aumentando el valor de maxerrorI para bajar el exceso.

Extrusor0 => setp at_pid.0.bias 0.5
Extrusor1 => setp at_pid.1.bias 0.5

Al colocar estos valores se obtiene los mismos resultados, esto pasa porque bias trabaja en conjunto con maxerrorI y maxerrorD (casi nunca se lo utiliza). Lo que se debe realizar es ir aumentando el maxerrorI.

Con los valores asignados de bias y los siguientes valores de maxerrorI para los extrusores.

Extrusor0 => setp at_pid.0.maxerrorI 1
Extrusor1 => setp at_pid.1.maxerrorI 3 

Se obtiene valores de temperatura para el extrusor0 de entre 180.5-181 grados celsius, y para el extrusor1 de entre 228.75-231.25 grados centigrados.

El extrusor0 estaría perfectamente calibrado mientras que el extrusor1 aun falta compensar la temperatura para que no baje de la asiganda.

Aumentando el bias del segundo extrusor a 0.6 y disminuyendo maxerrorI a 2 ya se regula la temperatura entre 230.25 a 230.75 grados celsius.




He olvidado guardar los valores PID obtenidos en la anterior configuración, con los nuevos valores de PID que pondré a continuación, ha cambiado el valor de maxerrorI en el extrusor0 a 4 y el bias se mantiene en 0.5. Para el extrusor1 el valor de maxerrorI es de 2 y el bias en 0.7.

Con esos valores se ha obtenido una temperatura de 180.75-181 grados celsius en el extrusor0 y  231-231.25 grados celsius en el extrusor1.

Como resultado final se pasa de esto:

# PID Parameters for adjusting temperature control
# Extruder0
setp at_pid.0.Pgain  1
setp at_pid.0.Igain  0
setp at_pid.0.Dgain  0
setp at_pid.0.tuneEffort 0.5
setp at_pid.0.tuneMode 1
setp at_pid.0.tuneStart 1
setp at_pid.0.tuneType 0
setp at_pid.0.tuneCycles 50
setp at_pid.0.maxoutput 0.8
#setp at_pid.0.maxerrorI 12
#setp at_pid.0.bias 0.5

# Extruder1
setp at_pid.1.Pgain  1
setp at_pid.1.Igain  0
setp at_pid.1.Dgain  0
setp at_pid.1.tuneEffort 0.8
setp at_pid.1.tuneMode 1
setp at_pid.1.tuneStart 1
setp at_pid.1.tuneType 0
setp at_pid.1.tuneCycles 50
setp at_pid.1.maxoutput 0.8
#setp at_pid.1.maxerrorI 12
#setp at_pid.1.bias 0.5

a esto:

# PID Parameters for adjusting temperature control
# Extruder0
setp at_pid.0.Pgain  0.05076038
setp at_pid.0.Igain  0.03180257
setp at_pid.0.Dgain  0.02025478
setp at_pid.0.tuneEffort 0.5
setp at_pid.0.tuneMode 0
setp at_pid.0.tuneStart 0
setp at_pid.0.tuneType 0
setp at_pid.0.tuneCycles 50
setp at_pid.0.maxoutput 0.8
setp at_pid.0.maxerrorI 4
setp at_pid.0.bias 0.5

# Extruder1
setp at_pid.1.Pgain  0.0596831
setp at_pid.1.Igain  0.0327806
setp at_pid.1.Dgain  0.02716601
setp at_pid.1.tuneEffort 0.8
setp at_pid.1.tuneMode 0
setp at_pid.1.tuneStart 0
setp at_pid.1.tuneType 0
setp at_pid.1.tuneCycles 50
setp at_pid.1.maxoutput 0.8
setp at_pid.1.maxerrorI 2
setp at_pid.1.bias 0.7

Conclusión: Al cambiar de temperatura se puede descalibrar con los valores de PID obtenidos en la temperatura asignada en el momento de la calibración, pero para no tener que hacer los mismos pasos se puede usar la compensación de bias junto con el maxerrorI y poder calibrar la temperatura a lo que se requiera. Cuanta más temperatura se requiera tuneEffort debe ser mayor de lo contrario tardaría demasiado en llegar a temperaturas altas, lo mismo ocurre con maxoutput se debe dejar con un valor con el cúal no caliente demasiado rápido ni tampoco demasiado lento. La variable maxoutput y tuneEffot no tiene nada que ver ya que tuneEffort se usa solo cuando de realiza la calibración mientras que maxoutput se usa cuando se realiza el control PID. Para realizar el control PID tuneMode y tuneStart deben valer 0 (False).

A continuación dejo los archivos que he usado para esta configuración.

MF5-LCD7

Nota: Leer el archivo README, copiar la carpeta MF5-LCD7 a machinekit/configs y dar permisos de ejecucción con chmod +x a setup.MF5-DTO.sh

No hay comentarios.:

Publicar un comentario