Autor Tema: Conectar un arduino con el EMC  (Leído 8966 veces)

Desconectado Jbecerra

  • Aprendiz
  • *
  • Join Date: Feb 2011
  • Mensajes: 772
  • Ubicación: Mairena del Alcor, Sevilla.
Conectar un arduino con el EMC
« en: 20 Agosto 2011, 14:49 »
Hola.
 Uso el EMC para mover un brazo scara y tengo ya todas las lineas disponibles en el puerto paralelo ocupadas, asi que le he puesto una tarjeta arduino y asi tengo mas entradas salidas disponibles en el EMC.
 Encontré por la web http://emergent.unpy.net/01198594294 que explica perfectamente bien como hacerlo y nos añade 6 entradas analógicas de 10 bits, 6 salidas analógicas de 8 bits(puede ser usadas para PWM)  y otras 6 lineas de entrada salida.
 Seguí todos los pasos ( y muchos tropiezos que no digo, jeje ) y al final me funciono como esperaba, queria compartirlo, asi que hice una pequeña traduccion del sitio y la expongo aquí.

“ Basandome en un proyecto anterior he desarrollado un interface entre el HAL y una tarjeta arduino para tener :
   - 6 Entradas analogicas
   - 6 salidas PWM de 8 bits - salidas analogicas.
   - 6 salidas entradas digitales.
   - Licencia GPL para las fuentes.

El driver consta de un sketch de arduino, aqui llamado (halintf.pde) y un componente HAL en el espacio de usuario ( Userspace Component ) escrito en Python. (arduino.py)

Lo primero es cargar el sketch en el GUI del arduino, compilarlo y transferirlo a la tarjeta. El programa se queda en la memoria flash del micro del arduino hasta que no se cambie.

Ahora, si no tienes aun instalado el python-serial toca instalarlo usando apt-get o Synaptic Package Manager. Si el comando python -c ‘import serial’.

Luego copiar el fichero arduino.py a un directorio que este en ell PATH con nombre arduino ( sin extension y hacerlo ejecutable con chmod +x arduino.

Hace falta otro fichero arduino-vcp.hal que ira en el emc. tendremos que editarlo y poner el puerto serie (USB) donde este conectado el arduino.

En el mismo directorio donde esta ese fichero creamos otro fichero arduino-vcp.xml  que es un fichero de definición de la ventana que nos abrirá el emc cuando ejecutemos la orden halrun arduino-vcp.hal.
La correspondencia de pines del arduino con los del hal son :
Entrada analogica 0, 1, 2, 3, 4 y 5   -> arduino.analog-in-##
Entrada o salida digital 2, 4, 7, 8, 12 y 13 -> arduino.digital-out-## o arduino.digital-in-##
PWM 3, 5, 6, 9, 10 y 11 arduino.analog-out-##


Los ficheros que usa son estos:

halintf.pde

//   HAL userspace component to interface with Arduino board
//   Copyright (C) 2007 Jeff Epler <jepler@unpythonic.net>
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

void setup() {
    Serial.begin(9600);
}   

uint8_t adc=0;
uint8_t firstbyte=0;
uint8_t pinmap[6] = {2,4,7,8,12,13};
uint8_t dacpinmap[6] = {3,5,6,9,10,11};
void loop() {
  while(Serial.available()) {
        uint8_t byte = Serial.read();
        if(((firstbyte & 0x80) == 0x80) && ((byte & 0x80) == 0)) {
            // got a packet
            uint16_t payload = (firstbyte << 7) | byte;
            uint8_t address = (firstbyte >> 4) & 7;
            uint8_t dac = payload & 0xff;
            uint8_t dir = (payload & 0x100) == 0x100;
            uint8_t out = (payload & 0x200) == 0x200;
            if(address < 6) {
                analogWrite(dacpinmap[address], dac);
                digitalWrite(pinmap[address], out);
                pinMode(pinmap[address], dir);
            }
        }
        firstbyte = byte;
    }
    uint16_t v = analogRead(adc) | (adc << 11);
    if(digitalRead(pinmap[adc])) v |= (1<<10);
    Serial.print((v >> 7) | 0x80, BYTE);
    Serial.print(v & 0x7f, BYTE);
    adc = (adc + 1) % 6;
}

arduino.py
#!/usr/bin/python
#    HAL userspace component to interface with Arduino board
#    Copyright (C) 2007 Jeff Epler <jepler@unpythonic.net>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
import serial
import hal
import sys
import time

def encode(addr, data):
    if data < 0 or data > 2048: raise ValueError, "data %02d out of range" % data
    if addr < 0 or addr > 8: raise ValueError, "address %02d out of range" % addr
    b1 = 0x80 | (addr << 4) | (data >> 7)
    b2 = data & 0x7f
    return chr(b1) + chr(b2)

PORT = "/dev/ttyUSB0"

if len(sys.argv) > 1:
    PORT = sys.argv[1]

if len(sys.argv) > 2:
    nout = int(sys.argv[2])
else:
    nout = 6

if nout > 6 or nout < 0:
    raise SystemExit, "Number of digital outputs must be from 0 to 6"

pinmap = [2,4,7,8,12,13]
dacpinmap = [3,5,6,9,10,11]

ser = serial.Serial(PORT, 9600, timeout=2)

c = hal.component("arduino")
for port in range(6):
    c.newpin("analog-in-%02d" % port, hal.HAL_FLOAT, hal.HAL_OUT)
    c.newparam("analog-in-%02d-offset" % port, hal.HAL_FLOAT, hal.HAL_RW)
    c.newparam("analog-in-%02d-gain" % port, hal.HAL_FLOAT, hal.HAL_RW)
    c.newpin("analog-out-%02d" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_IN)
    c.newparam("analog-out-%02d-offset" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW)
    c.newparam("analog-out-%02d-scale" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW)
    c['analog-in-%02d-gain' % port] = 1.0
    c['analog-out-%02d-scale' % dacpinmap[port]] = 1.0
for port in range(nout):
    c.newpin("digital-out-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_IN)
    c.newparam("digital-out-%02d-invert" % pinmap[port], hal.HAL_BIT, hal.HAL_RW)
for port in range(nout, 6):
    c.newpin("digital-in-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT)
    c.newpin("digital-in-%02d-not" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT)
    c.newparam("digital-in-%02d-pullup" % pinmap[port], hal.HAL_BIT, hal.HAL_RW)
c.ready()

firstbyte = 0
state = 0
try:
    while 1:
        while ser.inWaiting():
            byte = ord(ser.read())
            if firstbyte & 0x80 == 0x80 and byte & 0x80 == 0:
                v = (firstbyte << 7) | byte
                port = (v >> 11) & 7

                if port >= nout:
                    b = v & 1024
                    c['digital-in-%02d' % pinmap[port]] = b != 0
                    c['digital-in-%02d-not' % pinmap[port]] = b == 0

                gain = c['analog-in-%02d-gain' % port] or 1.
                offset = c['analog-in-%02d-offset' % port]
                value = (v & 1023) / 1023. * 5.0 * gain + offset
                c['analog-in-%02d' % port] = value

            firstbyte = byte
       
        scale = c['analog-out-%02d-scale' % dacpinmap[state]] or 1.
        offset = c['analog-out-%02d-offset' % dacpinmap[state]]
        data = (c['analog-out-%02d' % dacpinmap[state]] - offset) / scale / 5
        data = int(data * 255 + 0.5)
        if data < 0: data = 0
        if data > 255: data = 255
        if state < nout:
            out = not c['digital-out-%02d' % pinmap[state]]
            invert = not c['digital-out-%02d-invert' % pinmap[state]]
            if out != invert:
                data |= 0x200
            data = data | 0x100
        else:
            pullup = c['digital-in-%02d-pullup' % pinmap[state]]
            if pullup:
                data |= 0x200
        data = data | (state << 11)
        ser.write(chr(0x80 | (data >> 7)))
        ser.write(chr(data & 0x7f))
        state = (state+1) % 6
        time.sleep(.001)
except (KeyboardInterrupt,):
    raise SystemExit, 0



arduino-vcp.hal

loadusr -W arduino /dev/ttyUSB0 3
loadusr -Wn arduino-vcp pyvcp arduino-vcp.xml

show pin arduino-vcp

net ain0 arduino.analog-in-00 => arduino-vcp.analog-in-00 arduino-vcp.analog-in-00b
net ain1 arduino.analog-in-01 => arduino-vcp.analog-in-01 arduino-vcp.analog-in-01b
net ain2 arduino.analog-in-02 => arduino-vcp.analog-in-02 arduino-vcp.analog-in-02b
net ain3 arduino.analog-in-03 => arduino-vcp.analog-in-03 arduino-vcp.analog-in-03b
net ain4 arduino.analog-in-04 => arduino-vcp.analog-in-04 arduino-vcp.analog-in-04b
net ain5 arduino.analog-in-05 => arduino-vcp.analog-in-05 arduino-vcp.analog-in-05b

net din0 arduino.digital-in-08 => arduino-vcp.digital-in-08
net din1 arduino.digital-in-12 => arduino-vcp.digital-in-12
net din2 arduino.digital-in-13 => arduino-vcp.digital-in-13

net aout0 arduino.analog-out-03 => arduino-vcp.analog-out-03-f
net aout1 arduino.analog-out-05 => arduino-vcp.analog-out-05-f
net aout2 arduino.analog-out-06 => arduino-vcp.analog-out-06-f
net aout3 arduino.analog-out-09 => arduino-vcp.analog-out-09-f
net aout4 arduino.analog-out-10 => arduino-vcp.analog-out-10-f
net aout5 arduino.analog-out-11 => arduino-vcp.analog-out-11-f

net dout0 arduino.digital-out-02 <= arduino-vcp.digital-out-02
net dout1 arduino.digital-out-04 <= arduino-vcp.digital-out-04
net dout2 arduino.digital-out-07 <= arduino-vcp.digital-out-07

setp arduino.digital-in-08-pullup 1
setp arduino.digital-in-12-pullup 1
setp arduino.digital-in-13-pullup 1

waitusr arduino-vcp

arduino-vcp.xml   

<pyvcp>
<table>
<tablesticky sticky="n"/>
<tablerow/>
<label text="digital-in-08" font="helvetica -12 bold"/>
<label text="digital-in-12" font="helvetica -12 bold"/>
<label text="digital-in-13" font="helvetica -12 bold"/>
<label text="digital-out-02" font="helvetica -12 bold"/>
<label text="digital-out-04" font="helvetica -12 bold"/>
<label text="digital-out-07" font="helvetica -12 bold"/>
<tablerow/>
<led halpin="digital-in-08"/>
<led halpin="digital-in-12"/>
<led halpin="digital-in-13"/>
<checkbutton halpin="digital-out-02"/>
<checkbutton halpin="digital-out-04"/>
<checkbutton halpin="digital-out-07"/>
<tablerow/>
<label text="analog-in-00" font="helvetica -12 bold"/>
<label text="analog-in-01" font="helvetica -12 bold"/>
<label text="analog-in-02" font="helvetica -12 bold"/>
<label text="analog-in-03" font="helvetica -12 bold"/>
<label text="analog-in-04" font="helvetica -12 bold"/>
<label text="analog-in-05" font="helvetica -12 bold"/>
<tablerow/>
<number halpin="analog-in-00" format="-2.4f"/>
<number halpin="analog-in-01" format="-2.4f"/>
<number halpin="analog-in-02" format="-2.4f"/>
<number halpin="analog-in-03" format="-2.4f"/>
<number halpin="analog-in-04" format="-2.4f"/>
<number halpin="analog-in-05" format="-2.4f"/>
<tablerow/>
<bar halpin="analog-in-00b" min_="0" max_="5"/>
<bar halpin="analog-in-01b" min_="0" max_="5"/>
<bar halpin="analog-in-02b" min_="0" max_="5"/>
<bar halpin="analog-in-03b" min_="0" max_="5"/>
<bar halpin="analog-in-04b" min_="0" max_="5"/>
<bar halpin="analog-in-05b" min_="0" max_="5"/>
<tablerow/>
<label text="analog-out-03" font="helvetica -12 bold"/>
<label text="analog-out-05" font="helvetica -12 bold"/>
<label text="analog-out-06" font="helvetica -12 bold"/>
<label text="analog-out-09" font="helvetica -12 bold"/>
<label text="analog-out-10" font="helvetica -12 bold"/>
<label text="analog-out-11" font="helvetica -12 bold"/>
<tablerow/>
<scale resolution="0.1" halpin="analog-out-03" min_="0" max_="5" orient="h"/>
<scale resolution="0.1" halpin="analog-out-05" min_="0" max_="5" orient="h"/>
<scale resolution="0.1" halpin="analog-out-06" min_="0" max_="5" orient="h"/>
<scale resolution="0.1" halpin="analog-out-09" min_="0" max_="5" orient="h"/>
<scale resolution="0.1" halpin="analog-out-10" min_="0" max_="5" orient="h"/>
<scale resolution="0.1" halpin="analog-out-11" min_="0" max_="5" orient="h"/>
</table>
</pyvcp>

Animo al personal a montarlo y probarlo.

A mi me funciona bien, tan solo añadir el fichero hal creado a la configuración del brazo y conectarles los pins que quiero usar.
« última modificación: 26 Agosto 2011, 19:34 por Jbecerra »
Torno chino 280 -700, Fresadora BF-20. Ceneados.Con Linuxcnc.

Desconectado Jbecerra

  • Aprendiz
  • *
  • Join Date: Feb 2011
  • Mensajes: 772
  • Ubicación: Mairena del Alcor, Sevilla.
Re:Conectar un arduino con el EMC
« Respuesta #1 en: 20 Agosto 2011, 19:10 »
Tan solo un par de potenciometro y ya se puede probar.





Parte de la ventana que muestra el fichero arduino-vcp.xml    con los valores leídos.




Manrique:fotos editadas para que se vean grandes
« última modificación: 08 Febrero 2012, 16:34 por Manrique »
Torno chino 280 -700, Fresadora BF-20. Ceneados.Con Linuxcnc.

Desconectado Vider

  • Aprendiz
  • *
  • Join Date: Sep 2009
  • Mensajes: 1795
  • Ubicación: Madriles
Re:Conectar un arduino con el EMC
« Respuesta #2 en: 26 Agosto 2011, 12:14 »
Muy interesante veo que ya tienes dominada la parte del HAL
Bridgeport Series I convertirda a CNC, Colchester Chipmaster 5x20, Sierra cinta S121G y muy poco tiempo para usarlos ...

Desconectado AndresAlgeciras

  • Aprendiz
  • *
  • Join Date: Oct 2009
  • Mensajes: 1031
  • Ubicación: Algeciras (Cádiz)
Re:Conectar un arduino con el EMC
« Respuesta #3 en: 26 Agosto 2011, 12:21 »
Aunque "aun" me suene a chino, cualquier intento por compartir conocimientos es de agradecer.

Saludos.

Andrés
Torno Quantum D210x400 Vario; Taladro-Fresador Optimun BF 20 Vario; Sierra de cinta Optimun Opti S 130 GH; Fresadora Jarbe, con cabezal fresador universal, cabezal mortajador, mesa horizontal  y cabezal divisor universal; Soldadora TIG WSME-200; Esmeriladora Optimun QSM 150.

Desconectado Jbecerra

  • Aprendiz
  • *
  • Join Date: Feb 2011
  • Mensajes: 772
  • Ubicación: Mairena del Alcor, Sevilla.
Re:Conectar un arduino con el EMC
« Respuesta #4 en: 26 Agosto 2011, 19:42 »
Muy interesante veo que ya tienes dominada la parte del HAL

Ojala, jaja me vapulea por todas partes, pero ya entrara en cintura ;)

Andres si puedo concretarte alguna de las cosas dímelo, no soy muy buen explicador.
Torno chino 280 -700, Fresadora BF-20. Ceneados.Con Linuxcnc.

ESTEVE

  • Visitante
Re:Conectar un arduino con el EMC
« Respuesta #5 en: 06 Septiembre 2011, 18:15 »
MUY BUENO EL INVENTILLO, VOY A PROBAR A VER QUE TAL

Pablito

  • Visitante
Re:Conectar un arduino con el EMC
« Respuesta #6 en: 08 Febrero 2012, 09:51 »
Hola Jbecerra, estoy pensando como abordar el retrofit de una fresadora controlada por EMC, me seduce mucho la idea de hacerlo con un arduino por la simplicidad del asunto. Estos bichitos tienen alguna limitacion frente a una tarjeta de control ( por ejemplo una mesa) a la hora por ejemplo de sacar suficientes Khz o salidas/entradas digitales y/o analogicas?? Mi idea es mover 3 servos y captar señal de 3 regletas para que EMC haga lazo cerrado con la posicion real de la herramienta, de regletas no me he leido nada asi que no se si la señal que trabajan es digital o analogica.

Muchas gracias.

Desconectado varoniberico

  • Aprendiz
  • *
  • Join Date: Mar 2011
  • Mensajes: 1568
  • Ubicación: Torrevieja (Alicante) España
Re:Conectar un arduino con el EMC
« Respuesta #7 en: 08 Febrero 2012, 14:17 »
Hola Jbecerra  estoy siguiendo con muco interés tus hilos sobre EMC pues todavía no me he decidido por Mach3 o EMC. Una pregunta: ¿ que coste tiene las tarjetas  ARDUINO, Son rápidas, Tienen fallos? .
Bueno en realidad son tres preguntas Je je je...
 Y ahora una pequeña sugerencia, cuando edites los mensajes al insertar [IMAGE] por ejemplo la  anterior , Esta es la dirección: http://img845.imageshack.us/img845/2373/img2366oo.th.jpg
Elimina el sufijo .th de thumbnails o miniaturas y se editara la imagen en todo su esplendor, evitando tener que abrir otra ventana en image shack
Un saludo y animo con el ECM. .palmas .palmas .palmas .palmas
"Nadie esta tan vació como aquel que esta lleno de si mismo."

ESTEVE

  • Visitante
Re:Conectar un arduino con el EMC
« Respuesta #8 en: 09 Febrero 2012, 13:56 »
A este tipejo habra que cortarle las orejas, jeje, sabe mucho.
Felisitations por los logros jose.

Desconectado Vider

  • Aprendiz
  • *
  • Join Date: Sep 2009
  • Mensajes: 1795
  • Ubicación: Madriles
Re:Conectar un arduino con el EMC
« Respuesta #9 en: 09 Febrero 2012, 18:16 »
Un ejemplo muy interesante, muchas gracias,

Me ha sorprendido el programa del arduino, muy simple, compacto y legible, como tiene que ser, y lo dice uno del gremio de los picapica
Bridgeport Series I convertirda a CNC, Colchester Chipmaster 5x20, Sierra cinta S121G y muy poco tiempo para usarlos ...

Desconectado fleming

  • Aprendiz
  • *
  • Join Date: Dic 2009
  • Mensajes: 737
  • Ubicación: BCN-A Coruña (cuando puedo)
Re:Conectar un arduino con el EMC
« Respuesta #10 en: 09 Febrero 2012, 18:53 »
Gracias por el aporte, a seguir con el hilo... la verdad es que HAL, si lo dominas, tiene posibilidades casi infinitas.
¿ que coste tiene las tarjetas  ARDUINO, Son rápidas, Tienen fallos? .
De 20 a 30 y te lo puedes hacer por menos de 10.
http://www.bricogeek.com/shop/5-arduino

Fallos? los de programación (usea los tuyos jejejeje) y en cuanto a la velocidad... bueno, no son la alegría de la huerta... microcontrolador de 8 bits a 16Mhz, que para interactuar con nosotros los humanos nos llega... ahora para las máquinas y aplicaciones que requieran velocidad y sincronismo... no creo que se le pueda pedir gran cosa (cuellos de botella en la comunicación serie y la es un micro de 8bits-16Mhz), pero es la mar de resultón!!

Desconectado varoniberico

  • Aprendiz
  • *
  • Join Date: Mar 2011
  • Mensajes: 1568
  • Ubicación: Torrevieja (Alicante) España
Re:Conectar un arduino con el EMC
« Respuesta #11 en: 09 Febrero 2012, 19:34 »
fleming Yo creía que la Alegría de la Huerta era de Murcia pero ya veo que La Coruña también hay, Je je je...
No entiendo muy bien esta frase De 20 a 30 y te lo puedes hacer por menos de 10 lo de 20 o 30 es el coste en la pagina del enlace y lo de 10 ???? , te refieres ha hacer las placas y todo el montaje uno mismo comprando los materiales sueltos...
Un saludo y gracias por el aporte a los dos.  .palmas .palmas .palmas .palmas .palmas .palmas
"Nadie esta tan vació como aquel que esta lleno de si mismo."

Desconectado fleming

  • Aprendiz
  • *
  • Join Date: Dic 2009
  • Mensajes: 737
  • Ubicación: BCN-A Coruña (cuando puedo)
Re:Conectar un arduino con el EMC
« Respuesta #12 en: 10 Febrero 2012, 10:36 »
Cuando digo "on the cheap". me refiero a tener que tirar de reciclaje y desde luego no con los acabados de una placa comercial:
Para que el arduino funcione solo necesitas (además de los componentes pasivos que no llegan a 1€:
-Microcontrolador 4 o 5 €
-Oscilador: 0.5€
Pero para esto necesitarás un programador para cargar bootloader del ARDUINO (Atmel, el fabricante del microcontrolador, te lo venderá completamente vacío, y tú tendrás que cargarle el "programa" del arduino).... Peeeeero, como siempre en esta vida tenemos a nuestros amigos de los ojos rasgados, que nos venden el pac completo (micro pre-programado, y oscilador por unos 8€)
Pero necesitarás además una fuente de alimentación de 5V (todos los cargadores de móvil con conector USB dan 5V), sino tendrás que añadirle un regulador (pero la fuente de alimentación no te la quita nadie... aunque lo puede alimentar del USB directamente) En Este ejemplo utiliza el regulador, pero te lo puedes ahorrar si encuentras la forma de darle los 5V (habelas ahilas, mais non creo nelas...(as meigas)(*1)...
Peeero (jajaja, este es como todo en la vida, todo son peros...) si quieres comunicarlo con un PC, tendrás que meterle un integrado más:
Si tu ordenador tiene puerto serie, el MAX232 más pasivos.
Si tu ordenador solo tiene USB, pues el FT232 más pasivos.

Además del tiempo, etc.
Para hacer uno, no compensa, pero si tiene que hacer muchos... la cosa ya va siendo interesante...

Saludos





N.del T.: (1*) haberlas, las hay, pero no creo en ellas (las brujas) Dicho popular gallego. (añado traducción, que no quiero incumplir las normas del foro :P :P )