jueves, 31 de diciembre de 2015

Configurar archivo .ini y .hal (PID) para usar librería MAX31855 con gmoccapy_lcd7

Para continuar con este tutorial se debe haber creado los arhivos de los siguientes tutoriales:

GUI Temperatura.
Librería MAX31855.
Componente HAL MAX31855.

Configuración archivo .ini

En el archivo .ini se pondrá la Gui de temperatura y el archivo postguihal necesarios para leer la temperatura y realizar las conexiones.

[DISPLAY]

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


#EMBED_TAB_NAME = right_side_panel
#EMBED_TAB_LOCATION = box_right
#EMBED_TAB_COMMAND = gladevcp -x {XID} ReadTemp.glade

EMBED_TAB_NAME = Temperatura
EMBED_TAB_LOCATION = ntb_user_tabs
EMBED_TAB_COMMAND = gladevcp -x {XID} ReadTemp.glade

En este caso se visualizará la temperatura en las pestañas de gmoccapy.

[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 =   joypad.hal
HALUI = halui

POSTGUI_HALFILE =       3D.postgui.hal

Se cargan los archivos .hal que se utilizarán, joypad y halui son para poder controlar machinekit con un mando de juegos en mi caso con el control del Xbox 360. Se realizará esta configuración en tutoriales posteriores.

Configuración Archivo .hal

En el archivo .hal se debe aumentar y modificar algunas líneas.

En este caso se va a leer dos extrusores (termocuplas) con el amplificador MAX31855 y se usará el módulo de PID para controlar la temperatura.

loadrt pid count=3
loadrt limit1 count=3
loadusr -Wn Extruder0 hal_temp_max31855 -n Extruder0 -b SPI0 -num 1 -i 0.3 
loadusr -Wn Extruder1 hal_temp_max31855 -n Extruder1 -b SPI0 -num 2 -i 0.3
 
Se añade el pid al servo-thread

addf pid.0.do-pid-calcs                   servo-thread
addf pid.1.do-pid-calcs                   servo-thread
addf pid.2.do-pid-calcs                   servo-thread
addf limit1.0                             servo-thread
addf limit1.1                             servo-thread
addf limit1.2                             servo-thread
 
Se crean nuevas señales que controlarán los extrusores y cama caliente.

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

Se da una frecuencia para generar las señales PWM, en este caso de 1khz.

1000000ns -> 0.001s.

1/0.001 = 1khz

setp hpg.pwmgen.00.pwm_period       1000000

Se define los GPIO que van a generar las señales PWM.

# 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


Por útlimo se unen las señales con los componentes.

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

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

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

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.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    => pid.1.feedback

sets e1.temp.set  0
net e1.temp.set motion.analog-out-01   => pid.1.command

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

net e1.heater  <= pid.1.output
net e1.heater  => limit1.2.in
net e1.heaterl <= limit1.2.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.2.min 0

# PID for Bed temperature control
#net bed.temp.meas    <= Temp.Temperatura
#net bed.temp.meas    => pid.2.feedback

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

#net bed.heater  <= 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 pid.0.FF0      0
#setp pid.0.FF1      0
#setp pid.0.FF2      0
setp pid.0.Pgain  0.366693
setp pid.0.Igain  0.00001
setp pid.0.Dgain  0.9375
setp pid.0.maxerror 0.0
setp pid.0.bias    0.5
setp pid.0.enable   1

# Extruder1
#setp pid.1.FF0      0
#setp pid.1.FF1      0
#setp pid.1.FF2      0
setp pid.1.Pgain  0.366693
setp pid.1.Igain  0.00001
setp pid.1.Dgain  0.9375
setp pid.1.maxerror 0.0
setp pid.1.bias    0.5
setp pid.1.enable   1

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

Archivo Postgui  .hal.

# Include your customized HAL commands here
# Run on Gmoccapy with gladevcp panel 

net e0.temp.set  => ReadTemp.Extruder_Hal_lbl
net e0.temp.meas => ReadTemp.E0_Temp
net bed.temp.set  => ReadTemp.Bed_Hal_lbl
net bed.temp.meas => ReadTemp.Bed_Temp
net e1.temp.set  => ReadTemp.Extruder1_Hal_lbl
net e1.temp.meas => ReadTemp.E1_Temp


El siguiente esquematico se basa en el diseño de Adafruit para los MAX31855 y de CRAMPS para la conexión de los Fusores (Extrusores). A continuación dejo los links para los que deseen descargar los esquemáticos.

Adafruit MAX31855
CRAMPS





En el siguiente gif se muestra la lectura de temperatura usando el amplificador MAX31855 con termocuplas tipo K. Se calienta el primer extrusor y luego el segundo extrusor.



















Crear componente hal usando la librería MAX31855

Para poder seguir con este tutorial se recomienda leer Librería MAX31855.

El siguiente tutorial explica como crear componentes para poder cargarlos en la configuración .hal.

Crear archivo.

nano hal_temp_max31855

#!/usr/bin/python
# encoding: utf-8
"""
Temperature.py
Created by Leonardo Noguera on 2015-12-19.
"""

from drivers.MAX31855 import MAX31855

import argparse
import time
import sys

import hal        
        

def parseHandleDevice(spi_bus):
    if spi_bus != 'SPI0' and spi_bus != 'SPI1':
        print(("wrong SPI"))
        sys.exit(1)
    if spi_bus == 'SPI0':
        bus = MAX31855.SPI0
    else:
        bus = MAX31855.SPI1
    return bus

parser = argparse.ArgumentParser(description='HAL component to read MAX31855 Temperature values')
parser.add_argument('-n', '--name', help='HAL component name', required=True)
parser.add_argument('-b', '--spi_bus', help='SPI bus id', default="SPI1")
parser.add_argument('-num', '--num_devices', help='Max 2 MAX31855', default=1)
parser.add_argument('-i', '--interval', help='SPI update interval', default=0.3)
parser.add_argument('-d', '--delay', help='Delay before the SPI should be updated', default=0.0)
args = parser.parse_args()

updateInterval = float(args.interval)
delayInterval = float(args.delay)
error = True
watchdog = True

bus = parseHandleDevice(args.spi_bus)

if (int(args.num_devices) == 1):
    cs = 0
elif (int(args.num_devices) == 2):
    cs = 1
else:
    print("Only two Max31855 are supported")
    sys.exit(1)     

thermocouple = MAX31855(bus=int(bus),spi_cs=int(cs))

# Initialize HAL
h = hal.component(args.name)
halThermocouple = h.newpin("Temp.meas", hal.HAL_FLOAT, hal.HAL_OUT)
halTemperatureSet =  h.newpin("Temp.set", hal.HAL_FLOAT, hal.HAL_IN)
halTempPinActive = h.newpin("Temp.set.done", hal.HAL_BIT, hal.HAL_OUT)
halErrorRead = h.newpin("error", hal.HAL_BIT, hal.HAL_OUT)
halNoErrorRead = h.newpin("no-error", hal.HAL_BIT, hal.HAL_OUT)
halWatchdogRead = h.newpin("watchdog", hal.HAL_BIT, hal.HAL_OUT)
h.ready()

halErrorRead.value = error
halNoErrorRead.value = not error
halWatchdogRead.value = watchdog

try:
    time.sleep(delayInterval)
    while (True):
        try:
            if (error):                
                error = False
              
            temp = thermocouple.readTempC()
            if (temp == None):
                try:
                    # The MAX31855 reported an error, print it:
                    if thermocouple.error == thermocouple.SHORT_TO_GND:
                        print "Thermocouple shorted to GND"
                        

                    elif thermocouple.error == thermocouple.SHORT_TO_VCC:
                        print "Thermocouple shorted to VCC"
                        
                except:
                    if thermocouple.error == thermocouple.OPEN_CIRCUIT:
                        print "Thermocouple not connected"

                    print(("exiting HAL component " + args.name))
                    h.exit()
            else: 
                halThermocouple.value = float("{:0.2f}".format(temp))
            
                if (halThermocouple.value >= halTemperatureSet.value):
                    halTempPinActive.value = 1
                else: halTempPinActive.value = 0
         
        except IOError as e:
            error = True 
            thermocouple.close()
          
        halErrorRead.value = error
        halNoErrorRead.value = not error
        watchdog = not watchdog
        halWatchdogRead.value = watchdog
        time.sleep(updateInterval)

except:
    print(("exiting HAL component " + args.name))
    h.exit()

Lo que hace el siguiente archivo es importar la librería MAX31855, verificar que SPI se quiere usar, por defecto SPI1. Lo que sigue son los argumentos que se pueden usar, siendo obligatorio dar un nombre para el componente.

Usando num = 1 o num = 2, se puede leer un MAX31855 enviando un cero a cs y con una compuerta NOT se obtiene acceso a un segundo MAX31855 mandando un 1 y la compueta NOT convirtiendola en un 0 para que se habilite el segundo MAX31855. Soporta un máximo de 4 MAX31855 usando SPI0 y SPI1. Si se necesitará de más MAX31855 se debería cambiar la librería para que se simule por software la lectura de SPI y habilitar la seleccion del chip (cs) con cualquier GPIO. Ver como ejemplo Adafruit MAX31855.

En el siguiente paso se crea las señales hal que se encargarán de leer la temperatura, adquirir el valor de temperatura proporcionado por "código g" y determinar si la temperatura que se esta leyendo ha sobrepasado la temperatura enviada para seguir con el código G. Esto se explicará en el proximo tutorial al hablar de código G remapeado y uso de PID.

Por último se lee la temperatura y en el caso de no estar conectada la termocupla o este a circuitada GND o VCC se imprimirá lo que retorne, excepto la temperatura que se gaurdará en la variable "halThermocouple.value".

Para entender mejor lo que se ha realizado, se recomienda leer los componentes hal de las librerías de Machinekit. Hal user components.

El código de arriba se lo guardará con el nombre de hal_temp_max31855, luego se le dará permisos de ejecución y finalmente se lo copiará a /usr/bin para poder usarlo con Machinekit.

sudo chmod +x hal_temp_max31855 
sudo cp hal_temp_max31855 /usr/bin

Probar componente hal_temp_max31855.

En mi caso se cargará el componente de la siguiente manera:

loadusr -Wn Extruder0 hal_temp_max31855 -n Extruder0 -b SPI0 -num 1 -i 0.3

Donde loadusr indicá que cargará un componente creado, -Wn se usará para identificar al componente con un nombre, hal_temp_max31855 será el componente que se cargara con -n que es el nombre que se le dará, -b para escoger que se quiere trabajar con SPI0 o SPI1, -num 1 para mandar un cero a cs, -i para dar un tiempo de actualización 300ms.

Como requisito para que funcione es neceserio que se haya Habilitado SPI0 o SPI1 (device tree overlay).

Para probar componentes o archivos se puede usar el ejecutable "halrun" en el terminal

halrun
loadusr -Wn Extruder0 hal_temp_max31855 -n Extruder0 -b SPI0 -num 1 -i 0.3
show pin

Cada vez que se de la orden de show pin se verán los cambios de temperatura.













Librería Max31855 para leer temperatura con termocuplas usando Machinekit

Este tutorial se centra en poder leer la temperatura con el amplificador MAX31855 a través de una termocupla. Lo primero que se necesita es copiar la librería modificada a la carpeta de drivers que maneja Machinekit, donde estan varias librerías para controlar otros dispositivos como el MCP23017, ADS7828,  PCA9685.

En el transcurso de este tutorial se dará una breve explicación de como usar estas librerías dentro del archivo .hal de machinekit para poder expandir los puertos de entradas y salidas en el caso del MCP23017, leer temperatura a través de los 8 canales del ADS7828 y poder generar señales PWM con el PCA9685.

La librería MAX31855 fue obtenida de PyBBIO y una pequeña porción de código de Adafruit se adapto por conflictos que se ha tenido con la librería de serbus originaría de PyBBIO; cambiando Serbus por Spidev.

nano MAX31855.py
 
"""
 MAX31855
 Copyright 2015 - Alexander Hiam <alex@graycat.io>
 A library for PyBBIO to interface with Maxim's MAX31855 thermocouple amplifier.
 MAX31855 is released as part of PyBBIO under its MIT license.
 See PyBBIO/LICENSE.txt
"""

# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# 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.

import spidev


class MAX31855(object):

  SPI0 = 1
  SPI1 = 2

  OPEN_CIRCUIT   = 1
  SHORT_TO_GND   = 2
  SHORT_TO_VCC   = 4

  def __init__(self, bus, spi_cs=0, offset=0):
    self.spi_bus = spidev.SpiDev()
    self.bus = bus
    self.spi_cs = spi_cs
    self.spi_bus.open(bus,spi_cs)
    self.offset = offset
    self.error = None

  def readTempF(self):
    """ Reads temperature, converts to Fahrenheit and returns, or 
        returns None if error detected. """
    temp = self.readTempC() 
    return temp if not temp else temp * 9.0/5.0 + 32

  def readTempC(self):
    """ Reads and returns the temperature in Celsius, or returns None
        if error detected. """
    value = self.read()
    if value == None: return None
    # Extract 14-bit signed temperature value:
    temp = (value >> 18) & 0x3fff
    # Convert 2's complement:
    if temp >= 2**13: temp -= 2**14 
    return temp*0.25 + self.offset
    
  def readTempInternal(self):
    """ Reads and returns the MAX31855 reference junction temperature 
        in Celsius, or returns None if error detected. """
    value = self.read()
    if value == None: return None
    temp = (value >> 4) & 0xfff
    # Convert 2's complement:
    if temp >= 2**11: temp -= 2**12 
    return temp*0.0625

  def read(self):
    """ Receives and returns full 32-bit map from MAX31855, or sets
        self.error and returns None if fault detected. """
    self.error = None 

    # Configure SPI bus as required by the MAX31855:
    self.spi_bus.mode = 0
    self.spi_bus.max_speed_hz = 5000000
    self.spi_bus.lsbfirst = False
    raw = bytearray(self.spi_bus.readbytes(4))   
        
    value = raw[0] << 24 | raw[1] << 16 | raw[2] << 8 | raw[3] 

    if (value & (1<<16)):
      # Fault bit set, save error code and return None:
      self.error = value & 0b111
      return None

    return value

  def close(self):
    self.spi_bus.close()

En el siguiente tutorial se explicará como se usará la librería MAX31855 con Machinekit, creando un archivo que se usará como componente hal.

Para eso hay que escribir python -v e importar cualquier librería de Machinekit del siguiente link Machinekit Drivers.

python -v
from drivers import MCP23017
#saldrán varias rutas lo que interesa es que ha localizado la carpeta drivers,
#es ahi donde se debe copiar la librería MAX31855.py

sudo cp MAX31855.py /usr/lib/python2.7/dist-packages/drivers

Comprobamos la librería MAX31855.py

python
from drivers import MAX31855

Se ne se obtiene errores se a realizado de forma correcta los pasos. La siguiente parte es crear los archivos DTO para usar SPIDEV.

Para poder usar la librería Spidev se debe exportar el device tree overlay de SPI0 o SPI1, según el que se vaya a usar. En este caso se usará el SPI0 con do como entrada y d1 como salida. Para más información revisar el siguiente link BBB-SPIDEV.

Crear el archivo

nano BB-SPI0-01-00A0.dts

Pegar lo siguiente y guardar ctrl+o

/dts-v1/;
/plugin/;

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

    /* identification */
    part-number = "spi0pinmux";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            spi0_pins_s0: spi0_pins_s0 {
                pinctrl-single,pins = <
                  0x150 0x30  /* spi0_sclk, INPUT_PULLUP | MODE0 */
                  0x154 0x30  /* spi0_d0, INPUT_PULLUP | MODE0 */
                  0x158 0x10  /* spi0_d1, OUTPUT_PULLUP | MODE0 */
                  0x15c 0x10  /* spi0_cs0, OUTPUT_PULLUP | MODE0 */
                >;
            };
        };
    };

    fragment@1 {
        target = <&spi0>;
        __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;

             status = "okay";
             pinctrl-names = "default";
             pinctrl-0 = <&spi0_pins_s0>;

             spidev@0 {
                 spi-max-frequency = <24000000>;
                 reg = <0>;
                 compatible = "spidev";
             };
             spidev@1 {
                 spi-max-frequency = <24000000>;
                 reg = <1>;
                 compatible = "spidev";
             };            
        };
    };
};


spidev@0 permite usar cs (chip select) con 0
spidev@1 permite usar cs (chip select) con 1

Ahora hay que compilar el archivo usando dtc.

dtc -O dtb -o BB-SPI0-01-00A0.dtbo -b 0 -@ BB-SPI0-01-00A0.dts

Si no se ha obtenido ningún error, se procede a copiar el archivo a /lib/firmware

sudo cp BB-SPI0-01-00A0.dtbo /lib/firmware/

Para poder usar SPIDEV hay que habilitar el device tree overlay

sudo su
cd /lib/firmware
echo BB-SPI0-01 > /sys/devices/bone_capemgr.*/slots

Comprobar que se habilito SPI0

cat /sys/devices/bone_capemgr.*/slots
ls /dev/spidev*
ls /sys/bus/spi/devices/

Con el comando cat se obtiene lo siguiente:

 0: 54:PF---
 1: 55:PF---
 2: 56:PF---
 3: 57:PF---
 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
 6: ff:P-O-L Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BBB-LCNC-MF5
 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-SPI0-01

Usando ls en "/dev/spidev*":

/dev/spidev1.0  /dev/spidev1.1

Usando ls en "ls /sys/bus/spi/devices/":

spi1.0  spi1.1
   
Con lo anterior se verifica que SPI0 se puede usar con cs=0 y cs=1 y se ha cargado correctamente. Si se hubiese cargado SPI1 los valores serían spi2.0 y spi2.1.

El siguiente link facilita la información del dts de SPI0 y SPI1 -> Adafruit Overlays.

Para no repetir el paso anterior cada vez que se reinicia la Beaglebone Black, hay que habilitar SPI a través del script principal de Machinekit. Asi cuando se use Machinekit se exportará de forma automática.

# Make sure required device tree overlay(s) are loaded
for DTBO in BBB-LCNC-MF5 BB-SPI0-01; do

 if grep -q $DTBO $SLOTS ; then
  echo $DTBO overlay found
 else
  echo Loading $DTBO overlay
  sudo -A su -c "echo $DTBO > $SLOTS" || dtbo_err
  sleep 1
 fi
done;

BBB-LCNC-MF5 es mi device tree overlay personalizado para poder ejecutar Machinekit con pantallas LCD. Revisar el siguiente link para poder utilizar mi DTO personalizado BBB-LCNC-MF5.
   
Nota: Otra opción es hacer que reinicie la Beaglebone Black con el SPI que se necesite, revisar el siguiente link DTO LCD7, al final se explica. En futuros tutoriales se explicará como cargar toda la información de los device tree overlays desde una memoria EEPROM para que se configure los GPIO y demás funciones desde el arranque de la BBB.

martes, 8 de diciembre de 2015

Gui básica con Glade y Gladevcp integrada a Gmoccapy


Lo primero y bastante importante es saber como funciona la Gui Gmoccapy para lo cuál se debe entender el código de python que contiene todas las instrucciones de funcionamiento y el archivo .glade que integra los componentes de glade y gladevcp con python.


Visitar la wiki de gmoccapy para mas información.

http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Gmoccapy

En los lugares marcados con recuadros de diferentes colores se puede agregar Gui's personalizadas.

- Recuadro color azul es llamado box_left.

- Recuadro color verde es llamado box_custom_1.

- Recuadro color rojo es llamado box_custom_2.

- Recuadro color morada es llamado box_custom_3.

- Recuadro color naranja es llamado box_custom_4.

- Recuadro color marrón es llamado box_right.

Existen otros que se los puede reemplazar como es en el caso de usar gmoccapy  plasma.





- Recuadro de color negro box_coolant_and_spindle, contiene a box_cooling y box_spindle.

- Recuadro de color azul es box_cooling.

- Recuadro de color naranja es box_spindle.

- Recuadro de color rojo es box_vel_info.

Nota: Tool information es reemplazado por Signals y lo que se hace es colocar el archivo glade que se desee reemplazando en frm_tool_info que es una parte de todo el box_tool_and_code_info (Tool information, Gcode y Program).

Las dos siguientes es para agredar pestañas ya sea en la pantalla donde se visualiza el código G (ntb_preview) o en donde se puede visualizar en modo completo (ntb_user_tabs).




Nota: Para poder entender de mejor manera se recomienda ver la configuración de los archivos .ini de gmoccapy.


La interfáz que se creará es para poder leer la temperatura de una impresora 3D reemplazando esta Gui con la antigua 3D.Temps.panel.xml (pyvcp) usada en la Interfáz gráfica de Axis en CRAMPS.

Correr Glade (Instalación)

glade-3

Primero se guardará con el nombre ReadTemp.glade y se irá guardando constantemente para evitar perdidas del trabajo si se cerrara glade.

- Crear Ventana
- Agregar Frame
- Agregar Vertical Box ->6
- Agregar Horizontal Box -> 2 saltando un Vertical Box










- Agregar Label en la parte izquiera de los Horizontal Box creados y HAL Label en la parte derecha de los Horizontal Box creados.

- Agregar HAL Hbar -> 3 en los Vertical Box restantes.




Terminado esto se procede a configurar los componentes agregados.

- En window1 no se modificará nada.
- En frame1 se modificará el nombre y la alineación de la etiqueta para centarla.



- En la etiqueta de Frame 1 se renombrará el componente y asignará el título que va a aparecer



En la alineación del Frame se cambiarán unos parámetros para dar mejor presentación.




Con esto quedará de la siguiente forma:



En mi caso acostumbro a renombrar todos los nombres de los componentes.

- vbox1 -> ReadTemp_vbx
- hbox1 -> Extruder_lbl_hbx
- hbox2 -> Bed_lbl_hbx
- hbox3 -> Extruder2_lbl_hbx

Los nombres pueden ser cualquiera los uso asi porque lbl representa a label; y vbx o hbx a vertical box y horizontal box. Lo demás es para darse cuenta que ese hbox pertenece a extruder o bed, etc.

Ahora viene la parte más importante y es la de dar nombre correcto a los componentes Hal Label y HAL_Hbar que se van a usar con el archivo .hal de CRAMPS.hal, los nombres pueden ser cuailquiera pero luego se los debe conectar con el archivo .hal.

- hal_hbar1 -> E0_Temp
- hal_hbar2 -> Bed_Temp
- hal_hbar3 -> E1_Temp

Lo mismo se realiza con las etiquetas, al final quedá de la siguiente forma.


El último paso es configurar las etiquetas y las barras horizontales que darán la lectura de temperatura.

Para las etiquetas deshabilitar expand y darles un título. Para los Horizontal box tambien deshabiltar el expand.




Para las etiquetas Hal se dará un formato de Hal pin type: 1 en la parte de configuración. Se lo realiza para que pueda recibir datos flotantes.

Para las barras horizontales también deshabilitar Expand, forzar la altura, ancho y cambiar la escala.



Terminado todo el diseño quedará algo así:



No hay que preocuparse que al ejecutar el archivo glade con gladevcp se verá que la venta se rescala al tamaño máximo configurado en el ancho y alto de las barras horizontales. Intentar cambiar los valores de ancho y alto para que se note la diferencia (force height, force width). Guardar.

Ejecutando gladevcp mostrado en el anterior tutorial se obtiene.







Donde se puede apreciar que se ha dimensionado la ventana al tamaño asignado por las barras horizontales.

Creando el archivo .hal para poder vincular los componentes de gladevcp con las señales de machinekit (linuxcnc).

# Include your customized HAL commands here
# Run on Gmoccapy with gladevcp panel 

net e0.temp.set  => ReadTemp.Extruder_Hal_lbl
net e0.temp.meas => ReadTemp.E0_Temp
net bed.temp.set  => ReadTemp.Bed_Hal_lbl
net bed.temp.meas => ReadTemp.Bed_Temp

guardar con cualquier nombre ejemplo 3D.postgui.hal


Si se mira el archivo.hal de CRAMPS se crean las señales e0.temp.set, e0.temp.meas donde el primero da el valor que se esta usando de PID y el segundo indica el valor que el ADC esta leyendo. Lo mismo para las demás señales.

Cuando se haya añadido el archivo .hal creado al archivo .ini de la CRAMPS se podrá ejecutar el archivo glade integrado en este caso a la GUI gmoccapy_lcd7 modificada por mi para pantallas lcd de 7 pulgadas con resolución de 800x480. gmoccapy_lcd7.


En el archivo .ini de CRAMPS se cambiaría lo siguiente:

[DISPLAY]

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

EMBED_TAB_NAME = right_side_panel
EMBED_TAB_LOCATION = box_right
EMBED_TAB_COMMAND = gladevcp -x {XID} ReadTemp.glade

Se añade el archivo glade creado al box_right de gmoccapy explicado en la parte superior y anteriores tutoriales.

[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 =        CRAMPS.hal

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

POSTGUI_HALFILE =       3D.postgui.hal

En este caso el archivo anterior donde se unen las señales hal con glade se lo llamo de la misma forma que el designado en CRAMPS. se debe agregar el archivo .hal y .glade en la misma carpeta donde se encuentran los otros archivos de CRAMPS en la beaglebone black.

El resultado es el siguiente:


Gmoccapy_lcd7 se ha modificado para que presente el archivo glade que captura box_right, solo cuando se realizá un full screen, ya que al ser menor la resolución se distorciona los iconos si se abriera con el panel principal mas el archivo glade.

Sin la opción de pantalla completa de gmoccapy desaparece el cuadro de lectura de temperatura para que no ocurra lo anteriormente explicado.



Si se quiere utilizar la configuración CRAMPS hay que deshabilitar el audio del hdmi en /boo/uEnv.txt.


Si se desea comprobar las aplicaciones en la computadora donde se esta diseñando solo es necesario ir a la carpeta de gmoccapy donde se guardan las configuraciones de gmoccpay y agregar el diseño dentro de la misma carpeta. No olvidarse de correr el scripts de linuxcnc si se copia a la carpeta de configuración de linuxcnc, caso contrario que e use Machinekit correr con machinekit y copiar a la carpeta de configuración de machinekit donde se encuentre gmoccapy.

Resultados con gmoccapy modificando en mi caso está en ~/linuxcnc-mirror/configs/sim/gmoccapy/gmoccapy.ini.

Esta es la ruta donde se deben guardar los archivos .glade o python u otros, tambien se puede crear un carpeta en  ~/linuxcnc-mirror/configs/ y guardar ahi los archivos con los que querramos explorar. En este ejemplo no se usa el archivo .hal ya que no hay lectura ADC como en el caso de la Beaglebone Black que esta configurado en el archivo .CRAMPS con un archivo python. Este es solo de simulación para poder ver como esta quedando el diseño de glade con gmoccapy; en el caso de querer usar gmoccapy_lcd7 en el PC, descargar de github y copiar a las carpetas bin, share de la ruta  ~/linuxcnc-mirror los archivos correspondientes. Utilizar en display gmoccapy_lcd7.

[DISPLAY]

DISPLAY = gmoccapy

EMBED_TAB_NAME = right_side_panel
EMBED_TAB_LOCATION = box_right
EMBED_TAB_COMMAND = gladevcp -x {XID} ReadTemp.glade


Como se ve no hay cambios al estar sin full screen y con full screen se mantiene la ventana de box_right. No mide la temperatura al solo usar el archivo .glade.


Para obtener el archivo glade en una ventana separada se escribe lo siguiente.

[DISPLAY]

DISPLAY = gmoccapy

EMBED_TAB_NAME = right_side_panel
EMBED_TAB_LOCATION = box_right
EMBED_TAB_COMMAND = gladevcp -g 64x697+0+0 ReadTemp.glade

Donde  se define anchoxaltura+desplazamiento X+desplaamiento Y



Utilizando gmoccapy_lcd7 en PC.

cd gmoccapy_lcd7/
cp bin/gmoccapy_lcd7 ~/linuxcnc-mirror/bin/
chmod a+x ~/linuxcnc-mirror/bin/gmoccapy_lcd7
cp -r share/gmoccapy_lcd7/ ~/linuxcnc-mirror/share/
sudo apt-get update
sudo apt-get install matchbox
sudo cp keyboard-cnc.xml /usr/share/matchbox-keyboard
sudo chmod a+x /usr/share/matchbox-keyboard/keyboard-cnc.xml


Se obtiene los mismo resultados que el anterior, con esto ya se puede comenzar a ver cuales son los cambios que e han hecho de la gmoccapy, tento en el archivo .glade como python (gmoccapy_lcd7 y gmoccapy en bin).

En este link ARM.BeagleBone.CRAMPS.tar.xz se podrá descargar la carpeta CRAMPS que contiene todos los archivos incluido ReadTemp.glade creado en este tutorial.


lunes, 7 de diciembre de 2015

Instalación de Glade y Gladevcp en Debian (Jessie).


Se debe instalar machinekit para poder ocupar gladevcp con Glade.

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


En este caso se instalara machinekit como simulador.

sudo apt-get install machinekit-posix

El siguiente paso será instalar Glade con soporte de librerías Gtk2. Ya que el nuevo Glade usa Gtk3, el cuál no es compatible con los componentes de gladevcp usados para interacturar con los componentes HAL de linuxcnc.

El código de glade se lo puede descargar del siguiente link Glade

Se utilizará el último disponible -> glade3-3.8.5.tar.xz

Al terminar la descarga se lo descomprime con el comando tar.

tar -xvf glade3-3.8.5.tar.xz

Antes de compilar el programa se debe instalar algunas librerías necesarias para correr glade junto con el parche de gladevcp.

sudo apt-get install gnome-common devhelp libglade2-dev libgtk2.0-dev python-gtk2-dev \
gnome-doc-utils gtk-doc-tools

Compilación e instalación

./autogen.sh
./configure
make -j`nproc`
sudo make install
sudo ldconfig

Incluir archivos de gladevcp en glade.

Descargar del siguiente link glade3

tar -xvf glade3.tar.xz
#copiar carpeta glade3 a /usr/local/share para obtener componentes de gladevcp
sudo cp -R glade3 /usr/local/share/

Al finalizar se ejecuta glade

glade-3

Si todo se realizó de forma correcta debe aparecer lo siguiente en la parte inferior izquierda de glade.



Ya se puede crear Gui's. Pero existe un pequeño problema con machinekit que impide ejecutar las aplicaciones usando el comando de gladevcp por lo que se realizará una compilación del código de linuxcnc para poder comprobar las Gui's que se haya creado con glade.

Librerías necesarias para poder compilar LinuxCNC.

sudo apt-get install libpth-dev dvipng tcl-dev tk-dev tcl8.5-dev tk8.5-dev bwidget libxaw7-dev \
libncurses5-dev libreadline-dev asciidoc source-highlight dblatex groff python-dev python-tk \
python-lxml libglu1-mesa-dev libgl1-mesa-swx11-dev libgtk2.0-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

Librería necesaria para solucionar problema de audio en gmoccapy.

sudo apt-get install gstreamer0.10-plugins-base

Obtener código de LinuxCNC.

cd 
git clone https://github.com/jepler/linuxcnc-mirror.git
cd linuxcnc-mirror/src
./autogen.sh
#Para ver opciones de configuración ./configure --help
./configure --enable-simulator
make -j`nproc`
sudo make setuid

Al ejecutar el script que habilita el uso de linuxcnc ya se podrá comenzar a probar los programas con el gladevcp de linuxcnc.

cd linuxcnc-mirror
. ./scripts/rip-environment
linuxcnc

Para probar los archivos con gladevcp no hay que cerrar el terminal que ejecutó el script de linuxcnc, ya que en este se ejecutará todo lo que se necesite usar de linuxcnc, una vez cerrado el terminal hay que volver a realizar el paso anterior para habilitar linuxcnc.

#Probando archivos de gladevcp
cd ~/linuxcnc-mirror/configs/apps/gladevcp
gladevcp gladevcp-test.ui






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