lunes, 7 de septiembre de 2015

Configurar archivo .hal machinekit

El archivo .hal se encarga de configurar los componentes de hardware que se usarán en machinekit, la ventaja que se tiene de poder usar el archivo .hal es que nos permite enlazar los componentes de hardware a machinekit sin tener que compilar las librerías. Las librerías que se usa en la Beaglebone Black se encuentra en la ruta "/usr/lib/linuxcnc/xenomai", al ser las librerías de c (.c) y ensamblador (.p) compiadas tienen una extension .so usada en linux (en windows la extensión es .dll).

Lo primero que se necesita para que el archivo .hal ejecute los pines que se van a usar es cargar el script .sh que contiene toda la información necesaria de los pines que se van a usar. Revisar el tutorial de Configurar los pines gpio para usar con Machinekit.

# Launch the setup script to make sure hardware setup looks good
loadusr -w ../setup.MF5-DTO.sh

Luego de cargar el script se necesita cargar las librerías necesarias para que funcione la máquina, las variables que contienen los parámetros con los que se cargarán se encuentran en el archivo .ini.
loadrt trivkins es la encarga de configurar machinekit para usarse como fresadora, torno y sus derivados. Existen otros tipos de configuración para robot scara, puma, etc. KINS.
loadrt tp es una función que se añadío, en este link se explica un poco de lo que hace http://www.linuxcnc.org/index.php/english/forum/10-advanced-configuration/27368-new-trajectory-planner-testersprograms-wanted.
loadrt para:
[EMCMOT]EMCMOT, servo_period_nsec=[EMCMOT]SERVO_PERIOD, num_joints=[TRAJ]AXES, tp=tp kins=trivkins. Son variables que están en el archivo .ini con sus respectivos valores, dichos valores se usarán en el archivo .hal. tp =tp y kins=trivkins serán las variables que se pueden usar en el archivo .hal con dicho nombre.

hal_bb_gpio se encarga de configurar los pines como entrada o salida, es muy importante que en esta parte solo se use los pines que van a funcionar en modo de 1 o 0, en input esta puesto los finales de carrera (switch) que están configurados en el script en los pines de P8.7 (X Max), P8.8 (X Min), P8.9 (Y Max), P8.10 (Y Min), P8.17 (Estop), P9.11 (Z Max), P9.13 (Z Min) y como salida están los pines P8.18 (Led), P8.19 (Axis Enable), P8.26 (ESTOP Out), P9.23 (Machine Power). Los valores que estan con 100 + num_pin  pertenecen al header P8 donde num_pin es el número de pin del 1 al 46, en el header P9 se usan el valor de 200 + num_pin, tambien hay como configurar con los valores de 800 + num_pin  para Header P8 y 900 + num_pin para el Header P9. En esta configuración nunca hay que poner los pines que vamos a usar para la generación de step/dir o pwm ya que de lo contrario no funcionará bien cuando los utilicemos.  

[PRUCONF](DRIVER) es la variable que manda a llamar a la librería hal_pru_generic.
prucode es la variable que cargara el archivo pru_generic.bin donde HAL_RTMOD_DIR = EMC2_RTLIB_DIR, EMC2_RTLIB_DIR = $(EMC2_RTLIB_BASE_DIR)/$(RTDIR_EXT), RTDIR_EXT continene los threads que se usarán. Bueno en definitiva que daría que HAL_RTMOD_DIR es el path /usr/lib/linuxcnc y al estar [PRUCONF](PRUBIN)=xenomai/pru_generic.bin el path final sería /usr/lib/linuxcnc/xenomai/pru_generic.bin si se usará la imagen de machinekit, de lo contrario sería /home/username/machinekit/lib/linuxcnc/xenomai/pru_generic.bin. Para poder entender mejor esto hay que revisar los archivos que crean las rutas e instalan los archivos en las carpetas correspondientes. Los archivos Makefile y Submakefile.

[PRUCONF](CONFIG) contiene la información de cuantos ejes y señales pwm se va usar.

halname es el nombre que se le va a dar a la estructura [PRUCONF](DRIVER) o hal_pru_generic.pwmgen que se utilizaba antes de que modificaran el archivo .c de hal_pru_generic, mas abajo se indica la diferncia de esto.

Por último loadusr ejecuta programas externos que se van a usar, estos pueden ser como el programa python que usan en la impresora 3d para leer la temperatura ReadTemp.py. Donde Therm es el nombre que se le asigna, -n es el nombre de la componente, --num_chan el número de sensores que se va a leer, -t asigna que tabla del archivo se va a usar (depende del modelo de termistor que se va a usar), -a indica que pin del ADC de la Beaglebone Black se usará.

En la CRAMPS y BeBoPr el archivo ReadTemp.py fue reemplazado por el archivo hal_temp_bbb que se encuentra en la ruta /usr/bin como ejecutable.

# ###################################
# Core EMC/HAL Loads
# ###################################

# kinematics
loadrt trivkins

# motion controller, get name and thread periods from ini file
# trajectory planner
loadrt tp
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES tp=tp kins=trivkins


# load low-level drivers
# uncertain about P9-17 to 20, these are I2C channels - are these needed if we want to use BB-IO to talk to them?
loadrt hal_bb_gpio input_pins=107,108,109,110,117,211,213 output_pins= 118,119,126,223
loadrt [PRUCONF](DRIVER) prucode=$(HAL_RTMOD_DIR)/[PRUCONF](PRUBIN) [PRUCONF](CONFIG) halname=hpg


# Python user-mode HAL module to read ADC value and generate a thermostat output for PWM
# t = Thermistor table (only epcos_B57560G1104 or 1 supported for now)
# a = analog input channel
loadusr -Wn Therm ./ReadTemp.py -n Therm --num_chan 2 -t 1 1 -a 4 5

# Python user-mode HAL module to read ADC value and generate a thermostat output for PWM
# c = analog input channel and thermistor table
loadusr -Wn Therm hal_temp_bbb -n Therm -c 04:epcos_B57560G1104,05:epcos_B57560G1104 -b CRAMPS 

# ################################################
# THREADS
# ################################################

addf hpg.capture-position                 servo-thread
addf bb_gpio.read                         servo-thread
addf motion-command-handler               servo-thread
addf motion-controller                    servo-thread
# revel in the free time here from not having to run PID
addf hpg.update                           servo-thread
addf bb_gpio.write                        servo-thread
 
 
La configuración de arriba es lo básico que se necesita para configurar una máquina cnc, si se quiere configurar más cosas como los encoders, pid, jog, condiciones, etc; se necesita de algunas configuraciones extra como las siguientes.


# ###################################
# Core EMC/HAL Loads
# ###################################

#encoder
loadrt encoder num_chan=1

#siganl inverter
loadrt not 

#PID
loadrt pid count=2

#Limit min max
loadrt limit1 count=2

# ################################################
# THREADS
# ################################################

#encoder
addf encoder.update-counters              servo-thread
addf encoder.capture-position             servo-thread

#signal inverter
addf not.0                                servo-thread

#PID
addf pid.0.do-pid-calcs                   servo-thread
addf pid.1.do-pid-calcs                   servo-thread

#Limit min max
addf limit1.0                             servo-thread
addf limit1.1                             servo-thread

# ################################################
# Attach (Unir señales)
# ################################################
# connect inputs to the encoder
net encA encoder.0.phase-A        <= bb_gpio.p8.in-12
net encB encoder.0.phase-B        <= bb_gpio.p8.in-13

# emergency stop (signal inverter)
net estop                                   <= bb_gpio.p8.in-17 
net estop                                   => not.0.in
net nestop                                  <= not.0.out
net nestop                                  => iocontrol.0.emc-enable-in

# PID for Extruder 0 temperature control
net e0.temp.meas    <= Therm.ch-04.value
net e0.temp.meas    => pid.0.feedback

sets e0.temp.set  0
net e0.temp.set     => pid.0.command

net e0.heater  <= pid.0.output
net e0.heater  => limit1.0.in
net e0.heaterl <= limit1.0.out
net e0.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.0.min 0

# PID for Bed temperature control
net bed.temp.meas    <= Therm.ch-05.value
net bed.temp.meas    => pid.1.feedback

sets bed.temp.set  0
net bed.temp.set     => pid.1.command

net bed.heater  <= pid.1.output
net bed.heater  => limit1.1.in
net bed.heaterl <= limit1.1.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
# Extruder
#setp pid.0.FF0      0
#setp pid.0.FF1      0
#setp pid.0.FF2      0
setp pid.0.Pgain  0.30
setp pid.0.Igain  0.00001
setp pid.0.Dgain  0.9375
setp pid.0.maxerrorI 1.0
setp pid.0.bias    0.5
setp pid.0.enable   1

# Bed
#setp pid.1.FF0      0
#setp pid.1.FF1      0
#setp pid.1.FF2      0
setp pid.1.Pgain  1
setp pid.1.Igain  0.0
setp pid.1.Dgain  0.0
setp pid.1.maxerrorI 1.0
setp pid.1.bias    0.5
setp pid.1.enable   1

Existen mas componentes que se pueden configurar en los siguientes links se puede observar algunas configuraciones e información adicional de los componentes:
Realtime Components
Control lazo cerrado velocidad taladro
Configuración Zedboard taladro, encoder, e-stop

Lo siguiente indica la configuración que se debe realizar para configurar los ejes (driver-motores). Como arriba se dijo antes se usaba la configuración [PRUCONF](DRIVER) pero ahora solo se pone como hpg seguido de la función principal, el número del eje, tipo de función y valor (conf .ini).

Antes

#Para escribir el eje que correspondia X->00 Y->01 Z->02 y asi sucesivamente.
# timing parameters
setp [PRUCONF](DRIVER).stepgen.00.dirsetup        [AXIS_0]DIRSETUP
setp [PRUCONF](DRIVER).stepgen.00.dirhold         [AXIS_0]DIRHOLD

setp [PRUCONF](DRIVER).stepgen.00.steplen         [AXIS_0]STEPLEN
setp [PRUCONF](DRIVER).stepgen.00.stepspace       [AXIS_0]STEPSPACE

setp [PRUCONF](DRIVER).stepgen.00.position-scale  [AXIS_0]SCALE

setp [PRUCONF](DRIVER).stepgen.00.maxvel          [AXIS_0]STEPGEN_MAX_VEL
setp [PRUCONF](DRIVER).stepgen.00.maxaccel        [AXIS_0]STEPGEN_MAX_ACC

#setp [PRUCONF](DRIVER).stepgen.00.step_type       0
# P8.43 PRU1.out2
setp [PRUCONF](DRIVER).stepgen.00.steppin         55
# P8.44 PRU1.out4
setp [PRUCONF](DRIVER).stepgen.00.dirpin          76

#Para las señales de pwm se hacia asi poniendo hal_pru_generic.pwmgen.00.out.número.asignación     valor.
# Bed Heater FET 1
setp hal_pru_generic.pwmgen.00.out.00.pin       77
setp hal_pru_generic.pwmgen.00.out.00.enable    1
setp hal_pru_generic.pwmgen.00.out.00.value     0.0

Ahora

# ################
# X [0] Axis
# ################

# axis enable chain
newsig emcmot.00.enable bit
sets emcmot.00.enable FALSE

net emcmot.00.enable <= axis.0.amp-enable-out
net emcmot.00.enable => hpg.stepgen.00.enable


# position command and feedback
net emcmot.00.pos-cmd <= axis.0.motor-pos-cmd
net emcmot.00.pos-cmd => hpg.stepgen.00.position-cmd

net motor.00.pos-fb <= hpg.stepgen.00.position-fb
net motor.00.pos-fb => axis.0.motor-pos-fb


# timing parameters
setp hpg.stepgen.00.dirsetup        [AXIS_0]DIRSETUP
setp hpg.stepgen.00.dirhold         [AXIS_0]DIRHOLD

setp hpg.stepgen.00.steplen         [AXIS_0]STEPLEN
setp hpg.stepgen.00.stepspace       [AXIS_0]STEPSPACE

setp hpg.stepgen.00.position-scale  [AXIS_0]SCALE

setp hpg.stepgen.00.maxvel          [AXIS_0]STEPGEN_MAX_VEL
setp hpg.stepgen.00.maxaccel        [AXIS_0]STEPGEN_MAX_ACC

#setp hpg.stepgen.00.step_type       0
# P9.31 GPIO3_14
setp hpg.stepgen.00.steppin         0x8E
# P9.29 GPIO3_15
setp hpg.stepgen.00.dirpin          0x8F

Primero se crea la variable emcmot.00.enable como bit, luego se manda el valor de false para inicializarla como FALSE (0) (puede ser FALSE o TRUE no afecta en nada), el net conecta la variable emcmot.00.enable con axis.0.amp-enable-out, luego que se recibe el valor de axis.0.amp-enable-out se manda a la variable hpg.stepgen.00.enable para decirle si se habilita o no la generación de pulsos para este eje.

Todo eso se lo puede cambiar tranquilamente escribiendo de la siguiente manera:
net EnableX axis.0.amp-enable-out => hpg.stepgen.00.enable
donde EnableX es la variable que creamos con cualquier nombre, axis.0.amp-enable-out habilita el eje siempre que se lo mande a llamar ya sea en el MDI o código G y permite la generación de pulsos en hpg.stepgen.N.enable(N=número de eje).

Para poder utilizar el MDI con el eje se usa axis.0.motor-pos-cmd y se lo enlaza a hpg.stepgen.00.enable para que todo los comandos que se esciban en MDI los mande a hpg.stepgen.00.enable. (xpos-cmd puede ser cualquier nombre)
net xpos-cmd axis.0.motor-pos-cmd => hpg.stepgen.00.position-cmd

Para saber en que posición se encuentra cada eje se utiliza axis.0.motor-pos-fb, la posición se visualiza en el DRO de linuxcnc. hpg.stepgen.00.position-fb se enlaza a axis.0.motor-pos-fb y manda la info de posición. (xpos-fb puede ser cualquier nombre)
net xpos-fb hpg.stepgen.00.position-fb => axis.0.motor-pos-fb

La parte de arriba quedaría de la siguiente forma:

# ################
# X [0] Axis
# ################

# axis enable chain
net EnableX axis.0.amp-enable-out => hpg.stepgen.00.enable

# position command and feedback
net xpos-cmd axis.0.motor-pos-cmd => hpg.stepgen.00.position-cmd

net xpos-fb hpg.stepgen.00.position-fb => axis.0.motor-pos-fb

La siguiente parte solo configura las funciones de hpg.stepgen con los valores colocados en el archivo .ini.

# timing parameters
#Para el controlador ACS606:
#[AXIS_0]DIRSETUP=5000
#[AXIS_0]DIRHOLD=6700
#[AXIS_0]STEPLEN=850
#[AXIS_0]STEPSPACE=850
#Scala para X -> [AXIS_0]SCALE=800.0
#[AXIS_0]STEPGEN_MAX_VEL=48.0
#[AXIS_0]STEPGEN_MAX_ACC=480.0
setp hpg.stepgen.00.dirsetup        [AXIS_0]DIRSETUP
setp hpg.stepgen.00.dirhold         [AXIS_0]DIRHOLD

setp hpg.stepgen.00.steplen         [AXIS_0]STEPLEN
setp hpg.stepgen.00.stepspace       [AXIS_0]STEPSPACE

setp hpg.stepgen.00.position-scale  [AXIS_0]SCALE

setp hpg.stepgen.00.maxvel          [AXIS_0]STEPGEN_MAX_VEL
setp hpg.stepgen.00.maxaccel        [AXIS_0]STEPGEN_MAX_ACC

La última parte de configuración .hal para los ejes es:

#setp hpg.stepgen.00.step_type       0
# P9.31 GPIO3_14
setp hpg.stepgen.00.steppin         0x8E
# P9.29 GPIO3_15
setp hpg.stepgen.00.dirpin          0x8F

 Esta parte es muy importante porque dependiendo del pin que queramos usar ya sea como gpio o como pru hay que colocar la dirección del pin correcto y eso se lo puede encontrar en el archivo beaglebone_pinmap.h,

Para encontrar el pin gpio que se usa en el archivo .hal se debe aplicar la siguiente fórmula:
hal_pru_generic pin = ((<gpio_bank>+1)*32)+<gpio_pin>
Para utilizar P9.31 GPIO3_14 -> ((3+1)*32)+14 = 142 en hexadecimal = 8E
Para utilizar P9.29 GPIO3_15 -> ((3+1)*32)+15 = 143 en hexadecimal = 8F

En la configuración de Cramps se lo hace de la siguiente manera:

#setp hpg.stepgen.00.step_type       0
# P8.43 PRU1.out2
setp hpg.stepgen.00.steppin        813
# P8.44 PRU1.out4
setp hpg.stepgen.00.dirpin         812

donde se aplica el siguiente código para encontar el pin.

int fixup_pin(u32 hal_pin) {
    int ret = 0;
    u32 type, p89, index;

    // Original brain-dead pin numbering
    if (hal_pin < 192) {
        ret = hal_pin;
    } else {
        type  =  hal_pin / 100;
        p89   = (hal_pin % 1000) / 100 ;
        index =  hal_pin % 100;

        // Fixup index value for P9 pins with two CPU pins attached
        if (p89 == 9) {
            if ((index == 91) || (index == 92)) {
                index = index - 50 + (47 - 41);
            } else if (index > 46) {
                index = 0;
            }
        } else if (index > 46) {
            index = 0;
        }

        switch (type) {
        case 8 :
            ret = p8_pins[index].gpio_pin_num;
            break;
        case 9 :
            ret = p9_pins[index].gpio_pin_num;
            break;
        case 18 :
            ret = p8_pins[index].pruO_pin_num;
            break;
        case 19 :
            ret = p9_pins[index].pruO_pin_num;
            break;
        case 28 :
            ret = p8_pins[index].pruI_pin_num;
            break;
        case 29 :
            ret = p9_pins[index].pruI_pin_num;
            break;
        default:
            ret = 0;
        }    

        if (ret == 0)
            HPG_ERR("Unknown pin: %d\n",(int)hal_pin);

        if (ret < 0) {
            HPG_ERR("Requested pin unavailable: %d\n",(int)hal_pin);
            ret = 0;
        }
    }

    return ret;
}

Para encontrar el pin al que pertenece el valor 813 se realizaría lo siguiente.
type=813/100 => 8.13 => 8
p89=(813mod1000)/100 => 8.13 => 8
index=813mod100 => 13

Si type es 8, case 8:
ret = p8_pins[13].gpio_pin_num => P8.13 en modo GPIO

Para encontrar el pin al que pertenece el valor 812 se realizaría lo siguiente.
type=812/100 => 8.12 => 8
p89=(812mod1000)/100 => 8.12 => 8
index=812mod100 => 12

Si type es 8, case 8:
ret = p8_pins[12].gpio_pin_num => P8.12 en modo GPIO

Para cofigurar pin como PRU para P8 sería de la siguiente forma:
P8.15
type=  1815/100 => 18.15 => 18
p89= (1815mod1000)/100 => 8.15 => 8
index= 1815mod100 => 15

Si type es 18, case 18:
ret = p8_pins[15].pruO_pin_num => P8.15 en modo pru in

Para cofigurar pin como PRU para P9 sería de la siguiente forma:
P9.31
type=  1931/100 => 19.31 => 19
p89= (1931mod1000)/100 => 9.31 => 9
index= 1931mod100 => 31

Si type es 19, case 19:
ret = p9_pins[31].pruO_pin_num => P9.31 en modo pru out

Para evitar todo este proceso lo más fácil es coger el valor directo de la pru del archivo  beaglebone_pinmap.h y colocar en el archivo .hal ya sea en decimal o hexadecimal.

La siguiente parte se usa si la máquina usa finales de carrera.

# ##################################################
# Standard I/O - EStop, Enables, Limit Switches, Etc
# ##################################################

# Create estop signal chain
# Drive software estop to hardware
net estop-out iocontrol.0.user-enable-out => bb_gpio.p8.out-26
setp bb_gpio.p8.out-26.invert 1

# Monitor estop input from hardware
net estop-loop bb_gpio.p8.in-17 => iocontrol.0.emc-enable-in
setp bb_gpio.p8.in-17.invert 1

# create signals for tool loading loopback
net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed

# Axis enable signal (active low)
net emcmot.00.enable => bb_gpio.p9.out-14
setp bb_gpio.p9.out-14.invert 1

# Machine power
# Use halui.machine.is-on instead?
net emcmot.00.enable => bb_gpio.p9.out-23

# Tie machine power signal to the CRAMPS LED
# Feel free to tie any other signal you like to the LED
net emcmot.00.enable => bb_gpio.p9.out-25

# ################
# Limit Switches
# ################
newsig limit-x-min bit
newsig limit-x-max bit
newsig limit-y-min bit
newsig limit-y-max bit
newsig limit-z-min bit
newsig limit-z-max bit

net limit-x-min <= bb_gpio.p8.in-08
net limit-x-max <= bb_gpio.p8.in-07
net limit-y-min <= bb_gpio.p8.in-10
net limit-y-max <= bb_gpio.p8.in-09
net limit-z-min <= bb_gpio.p9.in-13
net limit-z-max <= bb_gpio.p9.in-11

# Adjust as needed for your switch polarity
setp bb_gpio.p8.in-08.invert 1
setp bb_gpio.p8.in-07.invert 1
setp bb_gpio.p8.in-10.invert 1
setp bb_gpio.p8.in-09.invert 1
setp bb_gpio.p9.in-11.invert 1
setp bb_gpio.p9.in-13.invert 1

# Uncomment if you actually have limit switches setup
# You probably want to setup homing in the INI file, as well
#net limit-x-min => axis.0.home-sw-in
#net limit-x-min => axis.0.neg-lim-sw-in
#net limit-x-max => axis.0.pos-lim-sw-in
#net limit-y-min => axis.1.home-sw-in
#net limit-y-min => axis.1.neg-lim-sw-in
#net limit-y-max => axis.1.pos-lim-sw-in
#net limit-z-min => axis.2.home-sw-in
#net limit-z-min => axis.2.neg-lim-sw-in
#net limit-z-max => axis.2.pos-lim-sw-in

Primero verifica si se a quitado el boton de emergencia de machinekit, esto se puede hacer por software o por hardware con un pulsador normalemente abierto o cerrado (con invert se configura el tipo de switch 1 para NC y 0 para NA) todo depende de la configuración, cuando se explique la parte electrónica se entendera como funciona esto. Lo mismo pasa en el loop de cambio de herramienta.

Para los finales de carrera se les asigna una variable del tipo booleano  y de igual forma se puede invertir la polaridad de acuerdo al tipo de switch (final de carrera).

Por último se configura las señales PWM en la primera parte estará la configuración de señales para una impresora 3d y en la segunda parte para un taladro.

# ##################################################
# PWM and Temperature Signals
# ##################################################

# Define signals to use elsewhere (ie: M1xx codes)
# If you change any names here, lots of things will break!
newsig e0.temp.set   float
newsig e0.temp.meas  float
newsig bed.temp.set  float
newsig bed.temp.meas float


setp hpg.pwmgen.00.pwm_period       10000000

# Bed Heater FET 1
setp hpg.pwmgen.00.out.00.pin       811
setp hpg.pwmgen.00.out.00.enable    1
setp hpg.pwmgen.00.out.00.value     0.0

# E0 Heater FET 2
setp hpg.pwmgen.00.out.01.pin       915
setp hpg.pwmgen.00.out.01.enable    1
setp hpg.pwmgen.00.out.01.value     0.0

# E1 Heater FET 3
setp hpg.pwmgen.00.out.02.pin       927
setp hpg.pwmgen.00.out.02.enable    1
setp hpg.pwmgen.00.out.02.value     0.0

# E2 Heater FET 4
setp hpg.pwmgen.00.out.03.pin       921
setp hpg.pwmgen.00.out.03.enable    1
setp hpg.pwmgen.00.out.03.value     0.0

# FET 5 - Fan / LED
setp hpg.pwmgen.00.out.04.pin       941
setp hpg.pwmgen.00.out.04.enable    1
setp hpg.pwmgen.00.out.04.value     0.0

# FET 6 - Fan / LED
setp hpg.pwmgen.00.out.05.pin       922
setp hpg.pwmgen.00.out.05.enable    1
setp hpg.pwmgen.00.out.05.value     0.0

# PID for Extruder 0 temperature control
net e0.temp.meas    <= Therm.ch-04.value
net e0.temp.meas    => pid.0.feedback

sets e0.temp.set  0
net e0.temp.set     => pid.0.command

net e0.heater  <= pid.0.output
net e0.heater  => limit1.0.in
net e0.heaterl <= limit1.0.out
net e0.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.0.min 0

# PID for Bed temperature control
net bed.temp.meas    <= Therm.ch-05.value
net bed.temp.meas    => pid.1.feedback

sets bed.temp.set  0
net bed.temp.set     => pid.1.command

net bed.heater  <= pid.1.output
net bed.heater  => limit1.1.in
net bed.heaterl <= limit1.1.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
# Extruder
#setp pid.0.FF0      0
#setp pid.0.FF1      0
#setp pid.0.FF2      0
setp pid.0.Pgain  0.30
setp pid.0.Igain  0.00001
setp pid.0.Dgain  0.9375
setp pid.0.maxerrorI 1.0
setp pid.0.bias    0.5
setp pid.0.enable   1

# Bed
#setp pid.1.FF0      0
#setp pid.1.FF1      0
#setp pid.1.FF2      0
setp pid.1.Pgain  1
setp pid.1.Igain  0.0
setp pid.1.Dgain  0.0
setp pid.1.maxerrorI 1.0
setp pid.1.bias    0.5
setp pid.1.enable   1

Primero se crean las variables del extrusor y la cama caliente como flotantes ya que reciben la lectura de los sensores de temperatura con decimales.
Luego se define el valor de la frecuencia para las señales pwm.
setp hpg.pwmgen.00.pwm_period       10000000
donde 10000000 es el valor en nanosegundos si la fórmula de frecuencia es f=1/T
entonces f=1/10000000ns => f=1/0.01s => f=100hz

# Bed Heater FET 1
setp hpg.pwmgen.00.out.00.pin       811
setp hpg.pwmgen.00.out.00.enable    1
setp hpg.pwmgen.00.out.00.value     0.0

Los variables que forman parte de la función pwmgen son las siguientes:

#Datos extraidos del archivo pwmgen.c 
hpg->pwmgen.instance[i].out[j].hal.pin.enable
hpg->pwmgen.instance[i].out[j].hal.pin.value
hpg->pwmgen.instance[i].out[j].hal.pin.pin
hpg->pwmgen.instance[i].out[j].hal.pin.scale
#Configuración en el archi .hal
#Para un PWM quedaría de la siguiente forma
# Bed Heater FET 1
setp hpg.pwmgen.00.out.00.pin       811
setp hpg.pwmgen.00.out.00.enable    1
setp hpg.pwmgen.00.out.00.value     0.0
#Para un segundo PWM
# SPINDLE con 12000 RPM
setp hpg.pwmgen.00.out.00.pin       915
setp hpg.pwmgen.00.out.00.enable    1
setp hpg.pwmgen.00.out.00.scale     12000

En resumen lo que se hace es proporcionar de valores iniciales, se configura el pin, si se quiere que este habilitado (1), el valor con el que se inicializa y la escala para controlar el número de RPM.

El PID para el extrusor y cama caliente realiza el proceso de mejorar la lectura obtenida del sensor de temperatura con lazo cerrado, los valores del PID se obtienen con pruebas que estabilizen la curva (para realiazar este proceso se utiliza el componente Halscope).

Segunda Parte pwmgen:

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

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
net spindle-on motion.spindle-on => hpg.pwmgen.00.out.00.enable
# J2 PRU1.out1
setp hpg.pwmgen.00.out.00.pin       0x53
setp hpg.pwmgen.00.out.00.scale     12000

Se utiliza una frecuencia de 1khz ya que el driver permite de 1khz hasta 10 khz.
f=1/1000000ns => f=1/0.001 => f=1000hz => f=1khz

el motion.spindle-speed-out se enlaza a la variable spindle-speed-cmd para recibir los valores por comando MDI o código G y enviarlos a hpg.pwmgen.00.out.00.value.

Spindle ejemplo
Hal Tutorial
Machinekit Cramps Hal
Realtime Components
EMC2 and HAL
Linuxcnc ejemplo de configuración
stepper.hal


Hay cosas que no explicado muy bien porque aún no he realizado pruebas, pero este tutorial se ira actualizando o se hara otros tutoriales profundizando más lo que se indica aquí.

1 comentario:

  1. maestro tal vez me puedas dictar unas pequeñas clases de programacion de linuxcnc por favor te lo suplico .quiero customizar unas cosas. te lo agradecere.
    comunicate por favor
    fabatecperu@gmail.com

    ResponderBorrar