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