jueves, 10 de septiembre de 2015

Instalación machinekit con kernel xenomai en PC

LinuxCNC se puede instalar en Debian y Ubuntu pero Machinekit solo se puede instalar en Debian Wheezy. Yo he logrado instalar LinuxCNC en Ubuntu 12.04 LTS (Precise) pero solo sirve en Sistemas Linux con arquitectura x86 (i686).

La ventaja que se tiene de instalar LinuxCNC en Ubuntu es que en este sistema la versión de glade-gtk2 (Glade 3.8) es estable y no tiene los bugs que se presentan en Glade con Debian, estos bugs se pueden corregir con algunos trucos que se explicarán en un tutorial donde inidique como crear GUI's.
Para instalar LinuxCNC en Ubuntu hay que instalar el kernel RTAI agregando los siguientes repositorios.

Ubuntu 12.04 LTS (Precise)

sudo nano /etc/apt/sources.list
deb     http://buildbot.linuxcnc.org/ precise master-rt
deb-src http://buildbot.linuxcnc.org/ precise master-rt
sudo apt-get update
sudo apt-get install linuxcnc

Para simulación

sudo nano /etc/apt/sources.list
deb     http://buildbot.linuxcnc.org/ precise master-sim
deb-src http://buildbot.linuxcnc.org/ precise master-sim
sudo apt-get update
sudo apt-get install linuxcnc-sim

Para seleccionar kernel con el que se quiere iniciar, instalar lo siguiente:

sudo add-apt-repository ppa:danielrichter2007/grub-customizer
sudo apt-get update
sudo apt-get install grub-customizer
grub-customizer &

Por último instalar Glade 3.8.

sudo apt-get install glade-gtk2

Para realizar modificaciones en linuxcnc, recomiendo clonar de este repositorio link:

sudo apt-get install git
sudo apt-get install dpkg-dev
mkdir linuxcnc-dev
cd linuxcnc-dev
git clone git://git.linuxcnc.org/git/linuxcnc.git linuxcnc
cd linuxcnc/debian
./configure sim
cd ..
dpkg-checkbuilddeps
sudo apt-get install libpth-dev dvipng tcl-dev tk-dev tcl8.4-dev tk8.4-dev \
bwidget libxaw7-dev libncurses-dev libreadline-dev asciidoc source-highlight \
dblatex groff python-dev python-tk python-lxml libglu1-mesa-dev libgl1-mesa-swx11-dev \
libgtk2.0-dev libgnomeprintui2.2-dev autoconf libboost-python-dev texlive-lang-cyrillic \
texlive-lang-french texlive-lang-german texlive-lang-spanish texlive-lang-polish \
libmodbus-dev python-support libudev-dev libusb-1.0-0-dev 
sudo apt-get install tclx
sudo apt-get purge tcl8.4-dev tk8.4-dev
cd src
./autogen.sh
./configure --with-realtime=uspace
make
cd ..
. ./scripts/rip-environment
linuxcnc
#opcional para ejecutar directamente linuxcnc desde /scripts/rip-environment en la terminal
#crear respaldo de .bashrc
cd 
cp .bashrc .bashrc.bk
sh -c "echo 'if [ -f ~/linuxcnc-dev/linuxcnc/scripts/rip-environment ]; then\n\
    source ~/linuxcnc-dev/linuxcnc/scripts/rip-environment\n\
    echo \"Environment set up for running LinuxCNC-dev\"\n\
fi\n' >> ~/.bashrc"
linuxcnc

A continuación se va explicar como instalar Machinekit en el Sistema Debian Wheezy que se encuentra en la sección de descargas de LinuxCNC. Este se va instalar en modo simulador por usarse en una máquina virtual (VMware Workstation) y servirá para poder crear interfáz gráficas que se integrarán a la GUI gmoccapy_lcd7, utilizando glade con las librerías gtk2.

Para poder usar todas las funciones de VMware se necesita instalar "VMware Tools Installation" que se encuentra en la pestaña VM.


cd /media/cdrom0
sudo cp VMwareTools-10.0.0-2977863.tar.gz ~/Documents/
cd ~/Documents/
tar -xvf VMwareTools-10.0.0-2977863.tar.gz
cd vmware-tools-distrib/
sudo ./vmware-install.pl
sudo reboot

Escribir yes y luego seguir los pasos que van saliendo cuando diga [yes] poner yes y cuando diga [no] poner no, cuando no salga nada darle a la tecla Enter. Con eso ya se puede copiar archivos entre el sistema primario y la máquina virtual, se expande la ventana de la máquina para acomadarse al tamaño de la pantalla, se puede compartir archivos entre sistemas y muchos más.

Ahora hay que instalar el kernel que se va a usar para Machinekit y realizar los pasos que se encuentran en la página oficial Machinekit en Documentation -> Debian packages y Building From Source.

 Primero hay que configurar los repositorios para poder instalar todas las librerías que necesita Machinekit.

sudo sh -c \
    "echo 'deb http://deb.dovetail-automata.com wheezy main' > \
    /etc/apt/sources.list.d/machinekit.list; \
    apt-get update ; \
    apt-get install dovetail-automata-keyring"
sudo apt-get update 

Luego hay que instalar el kernel que se desee, en este caso se usara el kernel Xenomai para 32 bits.

sudo apt-get install linux-image-xenomai.x86-686-pae

Lo siguiente es instalar algunos paquetes necesarios para poder configurar y correr Machinekit.

sudo apt-get install libczmq-dev python-zmq libjansson-dev \
    libwebsockets-dev libxenomai-dev python-pyftpdlib 

otros (cython)

sudo sh -c \
    "echo 'deb http://ftp.us.debian.org/debian wheezy-backports main' > \
     /etc/apt/sources.list.d/wheezy-backports.list"
sudo apt-get update
sudo apt-get install -t wheezy-backports cython
sudo apt-get install bwidget
sudo apt-get update

Ahora hay que instalar git para clonar los archivos de Machinekit almacenados en github.

Nota: cuando se llegue a la parte de git clone elegir la ruta donde se quiere guardar la descarga. Lo mejor  es descargar en la ruta principal (cd ~/).

sudo apt-get install git dpkg-dev
sudo apt-get install --no-install-recommends devscripts equivs
git clone https://github.com/machinekit/machinekit.git
cd machinekit
debian/configure -px
sudo mk-build-deps -ir
cd src

Esta parte es muy importante, se va explicar como poder utilizar el kernel xenomai y configurar el modo simulación para utilizar en la máquina virtual.

./autogen.sh

Para elegir el modo de configuración existen los siguientes comandos.

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-remote      enable remote zeroMQ services
  --enable-examples      build included programming examples
  --enable-proto-js    build Javascript bindings based on https://github.com/dcodeIO/ProtoBuf.js/wiki
  --enable-shmdrv      use the common shared memory driver kernel module
  --enable-portable-parport      Build hal_parport using the ppdev ioctl instead of inb/outb
  --enable-emcweb      build the emcweb interface
  --enable-dev       build unstable development code
  --enable-nml      enable NML-using parts

Optional Features and Packages:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-platform-pc      Build for PC platform (default for x86 arch)
  --with-platform-beaglebone
                          Build for Beaglebone platform (default for ARM arch)
  --with-platform-raspberry
                          Build for Raspberry platform (default for ARM arch)
  --with-platform-zedboard
                          Build for Zedboard platform
  --with-rundir=<directory>  directory for IPC sockets and other transient files (default /tmp)
  --with-xenomai-kernel-sources="<ksrc_dir> <ksrc_dir>..."
                          directory paths of xenomai kernel source(s),
                          space-separated
  --with-rtai-kernel-sources="<ksrc_dir> <ksrc_dir>..."
                          directory paths of RTAI kernel source(s),
                          space-separated
  --with-shmdrv-kernel-sources="<ksrc_dir> <ksrc_dir>..."
                          directory paths of kernel source(s) to build shmdrv
                          module for
  --with-extra-kernel-sources="<dir> <dir>..."
                          list of extra kernel source directories to search
  --with-posix            build POSIX (simulator) non-realtime threads modules
                          (enabled by default)
  --with-rt-preempt       build RT_PREEMPT threads modules
  --with-xenomai          build Xenomai userland threads
  --with-xenomai-kernel   build Xenomai kernel-space realtime threads
                          (deprecated)
  --with-xeno-config=<path>
                          location of the xeno-config executable
  --with-rtai-kernel      build RTAI kernel-space realtime threads modules
  --with-rtai-config=<path>
                          location of the rtai-config executable
  --enable-drivers        Build hardware drivers
  --enable-usermode-pci   Build PCI drivers with usermode PCI support
  --with-libmodbus                        Specify whether or not to build
                                          the drivers that use libmodbus
                                          (defaults to "yes")
  --with-libusb-1.0                       Specify whether or not to build
                                          the drivers that use libusb-1.0
                                          (defaults to "yes")
  --with-lttng                       Specify whether or not to use
                                          the LTTNG tracing framework
                                          (defaults to "no")
  --disable-gtk        Disable the parts of LinuxCNC that depend on GTK
  --with-rmmod=</path/rmmod>              rmmod variant
  --with-insmod=</path/insmod>            insmod variant
  --with-python=<path>                    Specify the Python interpreter
  --enable-build-documentation=format   Build documentation.
                          Format may be "pdf" or "html" if only one format is desired.
  --with-tcl=DIR          directory containing tcl configuration
                          (tclConfig.sh)
  --with-tk=DIR           directory containing tk configuration (tkConfig.sh)
  --with-x                use the X Window System
  --disable-nls           don't use NLS
  --with-locale-dir=DIR   Location of the locale file(s)
                          DATADIR/locale
  --disable-python        Disable the parts of LinuxCNC that depend on Python
  --with-boost-python     specify the boost python shared library to use. For
                          instance, --with-boost-python=boost_python-py25.
                          Defaults to boost-python. If you use this then you
                          should probably set PYTHON too, to avoid using
                          multiple python versions.
  --with-boost[=ARG]      use Boost library from a standard location
                          (ARG=yes), from the specified location (ARG=<path>),
                          or disable it (ARG=no) [ARG=yes]
  --with-boost-libdir=LIB_DIR
                          Force given directory for boost libraries. Note that
                          this will override library path detection, so use
                          this parameter only if default library detection
                          fails and you know exactly where your boost
                          libraries are located.
  --with-boost-serialization[=special-lib]
                          use the Serialization library from boost - it is
                          possible to specify a certain library for the linker
                          e.g.
                          --with-boost-serialization=boost_serialization-gcc-mt-d-1_33_1
  --with-boost-thread[=special-lib]
                          use the Thread library from boost - it is possible
                          to specify a certain library for the linker e.g.
                          --with-boost-thread=boost_thread-gcc-mt
  --with-boost-system[=special-lib]
                          use the System library from boost - it is possible
                          to specify a certain library for the linker e.g.
                          --with-boost-system=boost_system-gcc-mt

En este caso hay que elegir el kernel xenomai y el modo simulación.

./configure --with-xenomai --with-posix

Ahora hay que compilar los archivos con el comando make, en caso de tener una pc con un procesador multinúcleo ejecutar "nproc" para saber el número de núcleos.

nproc
make -j#número que retorna nproc 
#o ejecutar directo
make -j`nproc`

por último ejecutar sudo make setuid y configurar lo siguiente en el caso de obtener advertencias.

sudo make setuid

Solucionar advertencias.

sudo touch /var/log/linuxcnc.log
sudo service rsyslog restart
sudo cp rtapi/rsyslogd-linuxcnc.conf /etc/rsyslog.d/linuxcnc.conf
sudo service rsyslog restart
sudo cp -i src/rtapi/shmdrv/shmdrv.rules /etc/udev/rules.d (si sale la advertencia)
sudo nano /etc/security/limits.conf
cambiar memclock de 20480 -> * - memlock 32767 #EMC2
ctrl+o y ctrl+x
sudo apt-get install avahi-daemon avahi-discover
sudo make setuid
sudo adduser <username>  xenomai -> (nombre de usuario que se haya asignado en S.O)
sudo reboot

Al reiniciar elegir el kernel xenomai, abrir terminal y escribir lo siguiente:

uname -a
sale lo siguiente -> Linux linuxcnc 3.8-1-xenomai.x86-686-pae #1 SMP Debian 3.8.13-9 i686 GNU/Linux
cd machinekit
. ./scripts/rip-environment

Con . ./scripts/rip-environment se activa la versión de Machinekit que se ha compilado, esto es muy útil para que se puedan añadir o modificar archivos, librerías, imágenes, etc; de este modo se evita dañar algún archivo del sistema de linux.

Nota: Ejecutar . ./scripts/rip-environment simpre que se quiera usar machinekit, solo es necesario volverlo a ejecutar cuando se cierra el terminal o se reinicia linux.
Si se quiere ejecutar siempre Machinekit desde la terminal de forma directa, se debe agregar una variable de entorno.

#Primero hacer un respaldo de .bashrc
cd
cp .bashrc .bashrc.bk
sh -c "echo 'if [ -f ~/machinekit/scripts/rip-environment ]; then\n\
    source ~/machinekit/scripts/rip-environment\n\
    echo \"Environment set up for running Machinekit and LinuxCNC\"\n\
fi\n' >> ~/.bashrc"

Ejecutamos linuxcnc (Machinekit)

linuxcnc

Y si todo salio bién ejecutara el programa.


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í.

miércoles, 2 de septiembre de 2015

Configurar archivo .ini machinekit

El archivo .ini va a ser el encargado de configurar todos los parámetros que van a ser usados con machinekit donde estará los archivos o librerias que se van a usar, variables que se usarán en el archivo .hal, programas externos que se quiera usar, tipos de GUI con la que se quiera inicializar, etc.

Antes de comenzar es recomendable que se revise el siguiente link para poder entender mejor las cosas.
https://github.com/machinekit/machinekit/tree/master/src/hal/drivers/hal_pru_generic

En la Beaglebone Black se necesita de programas externos hechos en c (.c) y ensamblador (.p) que son los que contienen las instrucciones necesarias para poder realizar los procesos:
- Pulso y dirección que controlan los drivers.
- Señal PWM para controlar ventiladores, taladros, etc.
- Los codificadores o encoders para poder hacer una lectura de posición con sensores de cuadratura.
- Lectura y ecritura de señales que se envian a través de las GPIO o PRUSS
- Señal de Espera hasta que la orden se haya completado.
- Procesamiento de tareas que se estan ejecutando en machinekit.

La siguiente información se encuentra en la carpeta de machinekit/src/hal/drivers/hal_pru_generic para los que deseen realizar cambios y mejorar el desempeño de las librerías. El link que dejo es de github. https://github.com/machinekit/machinekit/tree/master/src/hal/drivers/hal_pru_generic

Las secciones del archivo .ini van entre corchetes indicando su nombre y las que estan dentro de estas serán las variables.

Nota: Uno puede utilizar cualquier nombre en una sección personaliza y en la variable lo mismo, lo que se hace es que cualquier sección o variable que se ocupe utilizarla en el archivo .hal.

Ejemplo:

[miImpresora]
calentar=1
apagar=0

En el archivo hal se la puede mandar a llamar definiendo una nueva variable.
#impresora 1
newsig impresora.00.enable bit
sets impresora.00.enable   [miImpresora](calentar)
#impreora 2
newsig impresora.01.enable bit
sets impresora.01.enable   [miImpresora](apagar)

Y luego se debe enlazar con el comando net.
net impresora.00.enable <= axis.0.amp-enable-out
net impresora.00.enable => hpg.stepgen.00.enable
net impresora.01.enable <= axis.1.amp-enable-out
net impresora.01.enable => hpg.stepgen.01.enable

Bueno lo escrito en la parte superior sera explicado en una configuración avanzada de como enlazar estas variables con linuxcnc y GUI's personalizadas.

La sección de PRUCONF se utiliza en la Beaglebone Black y es la encargada de decir al archivo .ini que utilice la librería hal_pru_generic que contiene toda la información de las GPIO, STEP, DIR, PWM, Encoders, etc.

En el archivo .hal se explicará como machinekit llama a dichas librerias que se encuentran en el directorio de /usr/lib/linuxcnc/xenomai.

DRIVER es la variable que llama a la librería hal_pru_generic
CONFIG es la variable que configura num_stepgens que son los ejes que se van a usar (STEP/DIR) y num_pwmgens es el numero de señales pwm que se desea ya sea para ventiladores, láser, taladro, etc.
PRUBIN es la variable que manda a llamar a xenomai que es el kernel de machinekit para que funcione en tiempo real.

Ejemplos:

Configuración de impresora 3d con doble extrusor (2 motores pap), 3 motores (X,Y,Z), 2 ventiladores, 2 fusores (extrusor) y una cama caliente.
Los motores del extrusor los manejo con los drivers pololu que funcionan con STEP/DIR.
Los motores de los ejes X, Y, Z; los manejo con los drivers ACS606 (STEP/DIR).
Los ventiladores con 2 señales PWM.
Los fusores con 2 señales PWM.
La cama caliente con 1 señal PWM.
[PRUCONF]
DRIVER=hal_pru_generic
CONFIG=pru=1 num_stepgens=5 num_pwmgens=5
PRUBIN=xenomai/pru_generic.bin

Configuración de fresadora 3 ejes (X,Y,Z).
Los motores de los ejes X, Y, Z; los manejo con los drivers ACS606 (STEP/DIR).
El taladro lo manejo con el driver hx-ws400 (PWM).
[PRUCONF]
DRIVER=hal_pru_generic
CONFIG=pru=1 num_stepgens=3 num_pwmgens=1
PRUBIN=xenomai/pru_generic.bin

Configuración de fresadora 4 ejes (X,Y,Z).
Los motores de los ejes X, Y, Z; los manejo con los drivers ACS606 (STEP/DIR).
El cuarto motor lo manejo con el driver ST-M5045 (STEP/DIR).
El taladro lo manejo con el driver hx-ws400 (PWM).
[PRUCONF]
DRIVER=hal_pru_generic
CONFIG=pru=1 num_stepgens=4 num_pwmgens=1
PRUBIN=xenomai/pru_generic.bin

La sección de EMC se encarga de informar la versión de la configuración, el nombre de la máquina y si se quiere ejecutar machinekit con mensajes que ayudan a depurar algun error que haya.

En la GUI de gmoccapy_lcd7 no importa los nombres de version y machine ya que en el archivo python se manda el nombre de gmoccapy_lcd7 y la versión de la misma con lo que en la ventana aparece el nombre gmoccapy_lcd7 y version 1.0.

En la GUI axis si se escribe lo que se haya puesto de nombre y versión.

Ambas GUI ejecutan el modo en que se quiere usar la depuración utilizando 0 para que no se visualice los mensajes de procesos de machinekit.

[EMC]

# Version of this INI file
VERSION =               $Revision:1.0$

# Name of machine, for use with display, etc.
MACHINE =               MF5.mill.4.axis

# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
#DEBUG =                0x00000003
#DEBUG =                0x00000007
DEBUG = 0

La sección de DISPLAY en la variable DISPLAY ejecuta la GUI que se desea siempre y cuando este instalada; puede ser la axis, tkemc, gmoccapy, gscreen, touchy o la que modifique que es gmoccapy_lcd7.
La variable CYCLE_TIME va detectar cambios y actualizar los procesos cada 0.200 segundos.
La variable HELP_FILE va indicar un archivo de texto con información que puede ayudar a entender mejor machinekit, solo se usa en la GUI que este programada con tklinuxcnc como la axis.
La variable POSITION_OFFSET configura machinekit ya se con posiciones relativas o posiciones absolutas.
La variable POSITION_FEEDBACK determina si la posición que se requiere es dada por el programa machinekit o por la retroalimentación de los motores.
La variable MAX_FEED_OVERRIDE indica que porcentaje usar para manipular velocidad y aceleración de los ejes. Si se usa 1.0 dara 100% de la velocidad máxima configurada, si es 1.5 dara el 150%.
La variable PROGRAM_PREFIX indica la ruta donde se encuentran los archivos nc que pueden ser ejemplos en código G o subrutinas. Si se tiene una carpeta con los archivos de código G o subrutinas en otra ruta hay que cambiarlo.
La variable INTRO_GRAFIC indica la imagen que sale al iniciar machinekit (se la puede cambiar colocando la imagen gif en /usr/share/linuxcnc).
La variable INTRO_TIME se usa para que la imagen de introducción (machinekit.gif) se despliegue por 5 segundos.
La variable INCREMENTS contiene los valores ya sean en pulgadas o mm que se quiera usar cuando se usa un eje para desplazar. Si esta seleccionado 10 mm en la gui y se selecciona el husillo x+, este se desplazara 10 mm en la dirección positiva del punto de referencia. En la GUI gmoccapy_lcd7 solo se puede poner hasta maximo 7 valores de lo contrario no ejecutara machinekit y saldrá un mensaje de error.

[DISPLAY]

# Name of display program, e.g., tkemc
#DISPLAY =               tkemc
#DISPLAY =              axis
DISPLAY =              gmoccapy_lcd7

# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME =            0.200

# Path to help file
HELP_FILE =             tklinucnc.txt

# Initial display setting for position, RELATIVE or MACHINE
POSITION_OFFSET =       RELATIVE

# Initial display setting for position, COMMANDED or ACTUAL
POSITION_FEEDBACK =     ACTUAL

# Highest value that will be allowed for feed override, 1.0 = 100%
MAX_FEED_OVERRIDE =     1.5

# Prefix to be used
PROGRAM_PREFIX = /home/machinekit/machinekit/nc_files

# Introductory graphic
INTRO_GRAPHIC =         machinekit.gif
INTRO_TIME =            5

# Increments for the JOG section
INCREMENTS = 10 1 0.1 0.01

La sección de FILTER se usa para poder llamar a extensiones de programas que se desea usar con machinekit, el .gcode se incluyo para poder leer las subrutinas que se usan en impresora 3d con programas como el slic3r.

[FILTER]
PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
PROGRAM_EXTENSION = .py Python Script
PROGRAM_EXTENSION = .gcode RepRap Flavour GCode
gcode = gcode-to-ngc
png = image-to-gcode
gif = image-to-gcode
jpg = image-to-gcode
py = python

La sección TASK es la encargada de controlar los ciclos de actualiación cuando se pausa el programa o se manda un comando para que realice un proceso.

[TASK]

# Name of task controller program, e.g., milltask
TASK =                  milltask

# Cycle time, in seconds, that task controller will sleep between polls
CYCLE_TIME =            0.010

La sección RS274NGC se encarga de indicar el directorio de las subrutinas, codigo G y M personalizado y guardar los ultimos parámetros que machinekit uso en el archivo .var. Los parámetros del archivo .var guardan datos de la gui y de posición.

Nota: no copiar los archivos "REMAP= " al archivo .ini hay que realizar unas configuraciones para que funcionen, eso será explicado en otro tutorial.

[RS274NGC]
# Machinekit fdm subroutines path
SUBROUTINE_PATH = /usr/share/linuxcnc/ncfiles/remap-subroutines/fdm
# alternatively you can copy the subroutines a local subroutines folder
# SUBROUTINE_PATH = subroutines

# remapping Machinekit FDM GCodes
REMAP=G22 modalgroup=1 ngc=g22
REMAP=G23 modalgroup=1 ngc=g23
REMAP=G28 modalgroup=1 argspec=xyza ngc=g28
REMAP=G29 modalgroup=1 ngc=g29
REMAP=G29.1 modalgroup=1 argspec=xyz ngc=g29_1
REMAP=G29.2 modalgroup=1 argspec=xyz ngc=g29_2
REMAP=G30 modalgroup=1 argspec=pxy ngc=g30
REMAP=M104 modalgroup=10 argspec=iPt ngc=m104
REMAP=M106 modalgroup=10 argspec=iPt ngc=m106
REMAP=M107 modalgroup=10 argspec=it ngc=m107
REMAP=M109 modalgroup=10 argspec=tP ngc=m109
REMAP=M140 modalgroup=10 argspec=iP ngc=m140
REMAP=M141 modalgroup=10 argspec=iP ngc=m141
REMAP=M190 modalgroup=10 argspec=P ngc=m190
REMAP=M191 modalgroup=10 argspec=P ngc=m191
REMAP=M200 modalgroup=10 argspec=D ngc=m200
REMAP=M207 modalgroup=10 argspec=PQ ngc=m207
REMAP=M221 modalgroup=10 argspec=P ngc=m221
REMAP=M226 modalgroup=10 ngc=m226
REMAP=M280 modalgroup=10 argspec=itP ngc=m280
REMAP=M300 modalgroup=10 argspec=iqP ngc=m300
REMAP=M400 modalgroup=10 ngc=m400
REMAP=M420 modalgroup=10 argspec=itredp ngc=m420
REMAP=M700 modalgroup=10 argspec=iP ngc=m700
REMAP=M701 modalgroup=10 argspec=iP ngc=m701
REMAP=M702 modalgroup=10 argspec=iP ngc=m702
REMAP=M710 modalgroup=10 argspec=epq ngc=m710
# enable ini parameter passing
FEATURES = 4
# File containing interpreter variables
PARAMETER_FILE =        MF5-Dual-Extrusion.var

La sección EMCMOT es utilizada para interactuar con las señales I/O, Analógicas y retroalimentación de señales de posicionamiento. Para saber mas dejo el siguiente link http://www.linuxcnc.org/docs/html/config/emc2hal.html#sec:motion.
La variable que mas interesa en la de SERVO_PERIOD que se encarga de decir a machinekit que se trabaja con ese tiempo para controlar las señales de los motores (Pulso/Dirección). El valor se obtiene con una prueba de latencia que realiza machinekit en la Beaglebone Black.

[EMCMOT]

EMCMOT =                motmod

# Timeout for comm to emcmot, in seconds
COMM_TIMEOUT =          1.0

# Interval between tries to emcmot, in seconds
COMM_WAIT =             0.010

# Servo task period, in nanoseconds
SERVO_PERIOD =          1000000

La sección HAL ejecuta los archivos .hal siempre y cuando estan en la misma ruta que el archivo .ini, el archivo MF5-Dual-Extrusion va a contener toda la información para hacer funcionar la impresora 3d. Los archivos spindle_sim.hal y postgui.hal son ejemplos de que machinekit es capaz de ejecutar varios archivos .hal. Como ejemplo el archivo spindle_sim.hal tendra información de con que parámetros de desea ejecutar el taladro y a que GPIO estará unido, mientras que el archivo postgui.hal será el encargado de unir las GPIO con una GUI personalizada enlazada a la GUI principal del programa.

En un tutorial que pretendo explicar como crear GUI's enlazadas a la GUI gmoccapy_lcd7 explicaré como funciona.

[HAL]

# The run script first uses halcmd to execute any HALFILE
# files, and then to execute any individual HALCMD commands.

# list of hal config files to run through halcmd
# files are executed in the order in which they appear

HALFILE =  MF5-Dual-Extrusion.hal
HALFILE =               spindle_sim.hal

# Single file that is executed after the GUI has started.
POSTGUI_HALFILE =       postgui.hal

# list of halcmd commands to execute
# commands are executed in the order in which they appear
#HALCMD =               save neta

La sección de TRAJ es la encargada de configurar todos los parámetros con los qe va a funcionar la máqina.
La variable Axes indica el número de ejes (DIR/STEP) que va utilizar la máquina, en este caso son 5 que pertenecen a los ejes X, Y, Z y A, B extrusores.
La variable COORDINATES indica la letra en orden que se le asigna a los ejes, se puede poner X, Y, Z, A, C siendo C el extrusor número 2.
La variable LINEAR_UNITS indica si se quiere trabajar en mm, pulgandas (in) o imperiales (imperial). Según esta configuración se va asignar las unidades a la variable INCREMENT explicada arriba.
La variable ANGULAR_UNITS indica si se quiere trabajar en grados (degree), radianes (radian) o grad or gon (400 por ciclo).
La variable MAX_ANGULAR_VELOCITY es la que determina la maxima velocidad angular.
La variable DEFAULT_ANGULAR_VELOCITY determina el valor por defecto.
La variable MAX_LINEAR_VELOCITY indica la máxima velocidad lineal, es muy importante este valor ya que si se deja muy alto se genera un error "hpg: stepgen.00.maxvel is too big for current step timings & position-scale, clipping to max possible", si el valor es muy bajo al configurar la velocidad en cada eje no surtira efecto al poner valores por encima del configurado aquí.
La variable DEFAULT_VELOCITY sería la velocidad por defecto, yo lo pongo un 20% menos de la máxima velocidad.
La variable POSITION_FILE guarda los valores en los cuales se encuentra, importante cuando se cierra machinekit y se vuelve a abrir estará en la útlima posición establecida o cuando se realiza un offset de un archivo de código G estará guardado en la posición a donde se lo arrastro.
La variable NO_FORCE_HOMING=1 indica se machinekit puede mover los ejes (jogging) sin tener que hacer un homing (desplazar los ejes al punto de referencia inicial), cuando es cero se debe hacer un homing para poder mover los husillos.

[TRAJ]

AXES =                  5
COORDINATES =           X Y Z A B
LINEAR_UNITS =          mm

ANGULAR_UNITS =         degree

MAX_ANGULAR_VELOCITY = 45.00
DEFAULT_ANGULAR_VELOCITY = 4.50

MAX_LINEAR_VELOCITY = 48.0
DEFAULT_VELOCITY = 40.0

CYCLE_TIME =            0.010
POSITION_FILE = position.txt
NO_FORCE_HOMING = 1

La sección AXIS_n donde n es el número del eje, indica la configuración de cada eje.

Los eje X, Y, Z de mi máquina utilizan los driver ACS606 que controlan motores BLDC modelo BLM57180.
En la hoja técnica del motor me dice que se necesitan de 4000 pulsos para dar una revolución, por lo tanto teniendo un husillo de 5 mm de paso se calcula la escala 4000pulsos/5mm = 800 pulsos/mm y eso es una revolucion del husillo.

La variable TYPE es lineal ya que se convierte el movimento aungular del motor a lineal con los husillos.

La velocidad máxima va a ser igual a 40.0 cuando se usa la pantalla LCD, pero si no se usará la velocidad es el doble. La pantalla LCD baja la velocidad de procesamiento para las señales STEP/DIR, por el momento no he podido realizar pruebas con un sd card clase 10 o cuando me llegue mi beaglebone black rev C y ejecute desde la eMMC actualizare esta informcaión. Es importante que cada uno realice pruebas aumento la velocidad hasta que de el error mensionado arriba.

 La variable STEPGEN_MAX_VEL es un 20% mas según la configuración recomendada en machienkit.

La variable MAX_ACCELERATION yo la pongo 10 veces mayor a la velocidad pero es recomendable hacer pruebas ejecutando en modo MDI de la gui comandos y viendo si la aceleración es muy alta no desacelera a tiempo y puede pasarse de la posición requerida.

La variable STEPGEN_MAX_ACC es un 20% mas que la máxima aceleración.

La variable SCALE ya la explique arriba.

Las variables MIN_LIMIT y MAX_LIMIT determinan el recorrido máximo y minimo, si se tiene un husillo de 800 mm y las rieles tienen una distancia de 200mm  lo que va a recorrer el eje será máximo 600 mm por lo tanto se puede poner MIN_LIMIT =0 y MAX_LIMIT=600.0 o si se quiere MIN_LIMIT=100.0 y MAX_LIMIT=500.0 sabiendo que recorre en el eje negativo para llegar al punto de referencia inicial.

Las variables FERROR y MIN_FERROR determinan cuanto es el error que se requiere que haya de posicionamiento, FERROR sería el error máximo en este caso 0.5mm y MIN_FERROR hasta cuanto es la resolución máxima que llega el motor para determinar el minimo error posible como ejemplo mi motor es 4000 pulsos y el husillo 5mm entonces el minimo error que tolera es de 5mm/4000pulsos = 0.00125.

La variable HOME indica el punto de referencia del eje, en mi caso esta 0 pero estos pueden ser valores positivos o negativos, cuando se usa finales de carrera (limit switches) estos determinan la posición inicial a donde se desea que se desplace el husillo y de ahi se determina el valor de home que si el switch esta en un valor negtivo para llegar a cero el husillo podría recorrer hasta la mitad por ejemplo y el HOME_OFFSET ayudaría a que se desplace un distancia dada de donde se quedo ya se positiva o negativa.

Nota: Aún no construyo mi máquina para afirmar esto de los finales de carrera y home por lo que las variables HOME_SEARCH_VEL, HOME_LATCH_VEL, HOME_USE_INDEX no las tomaré en cuenta por ahora.

La variable HOME_IGNORE_LIMITS esta comenta por que no tengo la máquina por lo tanto no hago pruebas aún con finales de carrera. Cuando esta variables es YES o 1 quiere decir que se usarán finales de carrera.

La variable HOME_SEQUENCE determina si se quiere hacer homing a todos los husillos que están configurados con un valor de 0. Si yo pongo X, Z y A HOME_SEQUENCE=0 todos estos harán un homing y el eje Y no hara el proceso de homing.

Las variables DIRSETUP, DIRHOLD, STEPLEN y STEPSPACE usan valores que se indican en el datasheet del driver. El driver ACS606 dice que hay un tiempo de 5us entre el pulso y la dirección por lo tanto DIRSETUP es 5us=5000ns, DIRHOLD no se sabe, STEPLEN es 0.85us=850ns y STEPSPACE es 0.85us =850ns. Por lo tanto esos son los valores de configuración del driver, en la página de linuxcnc vienen los valores ya establecidos en nano segundos de los drivers más conocidos, este es el link http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Stepper_Drive_Timing.

[AXIS_0]

# 
# Step timing used in Shapeoko arduino electronics was 30 us steplen + 30 us stepspace
# That gave a 60 us step period = 16.7 KHz step freq
#
# X axis drive mechanics are:
#    blm57180 = 4000 pulses/rev
#
# so Scale = 4000 pulses / 5 mm  = 800 pulses/mm = 1 rev husillo
#
# 
#


TYPE =              LINEAR
MAX_VELOCITY =       40.0
# Set Stepgen max vel 20% higher than the axis
STEPGEN_MAX_VEL =    48.0

MAX_ACCELERATION =   400.0
# Set Stepgen max accel 10% higher than the axis
STEPGEN_MAX_ACC =    480.0

BACKLASH =           0.000

SCALE = 800.0

MIN_LIMIT =             -1.0
MAX_LIMIT =             600.0

FERROR =     0.5
MIN_FERROR = 0.00125

HOME =                  0.000
HOME_OFFSET =           0.00
#HOME_SEARCH_VEL =       0.10
#HOME_LATCH_VEL =        -0.01
#HOME_USE_INDEX =        YES
#HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 0

# these are in nanoseconds
DIRSETUP   =              5000
DIRHOLD    =              6700
STEPLEN    =              850
STEPSPACE  =              850

[AXIS_1]

# 
# Step timing used in Shapeoko arduino electronics was 30 us steplen + 30 us stepspace
# That gave a 60 us step period = 16.7 KHz step freq
#
# X axis drive mechanics are:
#    blm57180 = 4000 pulses/rev
#
# so Scale = 4000 pulses / 5 mm  = 800 pulses/mm = 1 rev husillo
#
# 
#


TYPE =              LINEAR
MAX_VELOCITY =       40.0
# Set Stepgen max vel 20% higher than the axis
STEPGEN_MAX_VEL =    48.0

MAX_ACCELERATION =   400.0
# Set Stepgen max accel 10% higher than the axis
STEPGEN_MAX_ACC =    480.0

BACKLASH =           0.000

SCALE = 800.0

MIN_LIMIT =             -1.0
MAX_LIMIT =             400.0

FERROR =     0.5
MIN_FERROR = 0.00125

HOME =                  0.000
HOME_OFFSET =           0.00
#HOME_SEARCH_VEL =       0.10
#HOME_LATCH_VEL =        -0.01
#HOME_USE_INDEX =        YES
#HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 0

# these are in nanoseconds
DIRSETUP   =              5000
DIRHOLD    =              6700
STEPLEN    =              850
STEPSPACE  =              850

[AXIS_2]

# 
# Step timing used in Shapeoko arduino electronics was 30 us steplen + 30 us stepspace
# That gave a 60 us step period = 16.7 KHz step freq
#
# X axis drive mechanics are:
#    blm57180 = 4000 pulses/rev
#
# so Scale = 4000 pulses / 5 mm  = 800 pulses/mm = 1 rev husillo
#
# 
#


TYPE =              LINEAR
MAX_VELOCITY =       40.0
# Set Stepgen max vel 20% higher than the axis
STEPGEN_MAX_VEL =    48.0

MAX_ACCELERATION =   400.0
# Set Stepgen max accel 10% higher than the axis
STEPGEN_MAX_ACC =    480.0

BACKLASH =           0.000

SCALE = 800.0

MIN_LIMIT =             -1.0
MAX_LIMIT =             200.0

FERROR =     0.5
MIN_FERROR = 0.00125

HOME =                  0.000
HOME_OFFSET =           0.00
#HOME_SEARCH_VEL =       0.10
#HOME_LATCH_VEL =        -0.01
#HOME_USE_INDEX =        YES
#HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 0

# these are in nanoseconds
DIRSETUP   =              500
DIRHOLD    =              6700
STEPLEN    =              850
STEPSPACE  =              850

Los ejes A y B del extrusor tienen la siguiente configuración, usan los driver pololu A4988.
Para calcular la escala se realiza de acuerdo a los micropasos que se configure en los drivers, ejemplo si se usa el motor con 16 micropasos se calcula 200 pasos una vuelta.

200pasos/1rev x 16micropasos/1paso = 3200 micropasos/revolución. Ahora si se extruye el filamento poniendo una revolución (por estar configurada la variable TYPE=ANGULAR) y da un valor de 40.35 mm entonces el valor del scale sería de 3200micropasos/1rev x 1rev/40.35mm=79.3060718ustep/mm.

Las variables DIRSETUP=200, DIRHOLD=200, STEPLEN=1000 y STEPSPACE=1000; están en la configuración de drivers de linuxcnc. http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Stepper_Drive_Timing

[AXIS_3]
# TBD set up as a copy of axis_2 just to have a way to test the 4th axis driver on the K9

TYPE =              ANGULAR
MAX_VELOCITY =       200.0
# Set Stepgen max vel 20% higher than the axis
STEPGEN_MAX_VEL =    240.0

MAX_ACCELERATION =   3000.0
# Set Stepgen max accel 10% higher than the axis
STEPGEN_MAX_ACC =    3600.0

BACKLASH =           0.000

SCALE = 79.3060718

MIN_LIMIT =             -9999.0
MAX_LIMIT =             99999.0

FERROR =     1.0
MIN_FERROR = 0.50

HOME =                  0.000
HOME_OFFSET =           0.00
#HOME_SEARCH_VEL =       0.10
#HOME_LATCH_VEL =        -0.01
#HOME_USE_INDEX =        YES
#HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 0

# these are in nanoseconds
DIRSETUP   =              200
DIRHOLD    =              200
STEPLEN    =              1000
STEPSPACE  =              1000

[AXIS_4]
# TBD set up as a copy of axis_2 just to have a way to test the 4th axis driver on the K9

TYPE =              ANGULAR
MAX_VELOCITY =       200.0
# Set Stepgen max vel 20% higher than the axis
STEPGEN_MAX_VEL =    240.0

MAX_ACCELERATION =   3000.0
# Set Stepgen max accel 10% higher than the axis
STEPGEN_MAX_ACC =    3600.0

BACKLASH =           0.000

SCALE = 79.3060718

MIN_LIMIT =             -9999.0
MAX_LIMIT =             99999.0

FERROR =     1.0
MIN_FERROR = 0.50

HOME =                  0.000
HOME_OFFSET =           0.00
#HOME_SEARCH_VEL =       0.10
#HOME_LATCH_VEL =        -0.01
#HOME_USE_INDEX =        YES
#HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 0

# these are in nanoseconds
DIRSETUP   =              5000
DIRHOLD    =              8000
STEPLEN    =              1500
STEPSPACE  =              1500

Los archivos de configuración .ini y .hal los subiré a github cuando termine el tutorial de configuración hal.

A continuación dejo unos videos que subi a youtube.

Impresora 3D funcionamiento (motores)

Fresadora 4 ejes funcionamiento (motores)