Skip to content

CNC Hardware, Firmware & Software

Subpáginas

Proyectos de referencia

Lectura obligatoria

Mini impresora 3D

Este es un proyecto similar al anterior, pero agrega un extrusor al eje vertical! 😎

Robots pipeteadores

Resumen del proyecto - TLDR

  1. Armar un Arduino **mini**CNC con partes recicladas, que sepa dibujar.
  2. Armar un Arduino CNC simple, pero en serio, que use un minitorno Dremel como herramienta.
  3. Usar software libre cada etapa.

Resultados:

  • Controlador basado en Arduino Uno con GRBL y el CNC shield 3.0.
  • Diseños en Inkscape (grabados, drilling) KiCAD (circuitos) o FreeCAD (modelos 3D).
  • Generación de GCODE con OpenBuildsCAM, pcb2gcode, y otros.
  • Envío de GCODE a GRBL a través de bCNC (UGS está bueno también).

Arduino miniCNC

Proyecto miniCNC en reGOSH 2019 (ver la wiki).

Quizás podríamos haber continuado con uno de estos:

Acá está en un artículo de hackaday:

Acá hay opciones en un grupo de FB:

{{:proyectos:diy:cnc:20200628-030644.png?0x300}}

Mejoras

Actuador lineal en 3D

https://www.thingiverse.com/thing:1765496

20201207-072311.png

Otros proyectos

Mini plotter con motores 28byj:

Arduino CNC

Usamos el CNC shield 3.0 "clone".

Toda la info está muy bien documentada en el sitio oficial: https://www.zyltech.com/arduino-cnc-shield-instructions/

La correspondencia entre pines del arduino y del shield se puede ver en este diagrama: https://blog.protoneer.co.nz/arduino-cnc-shield/#jp-carousel-1664

20220308-211622.png

Parts and Design

v0.1

Empece con los modelos de srferrete.

Arduino CNC Shield + GRBL + 3D printed parts:

v0.3.1-A

Nuevos modelos, un remix importante del anterior:

20200624-012701.png

20200624-012813.png

La idea es hacerlo mas robusto: bajando la altura de el carrito del eje Y, agregando dos varillas al eje X, y rehaciendo el eje Z para que el Dremel no genere tanto torque al cortar.

Queda pendiente achicar el area de corte; eso haria que las varillas se flexionen menos.

v0.6 - Robor pipeteador y Dremel CNC

Este fue uno de los primeros prototipos de "robot pipeteador" que armé.

El proyecto siguió acá: https://gitlab.com/pipettin-bot/

20200903-234123.png

v0.6 - Dremel CNC model B

Toda la estructura de la última versión se flexiona bajo el peso del Dremel y luego se levanta al tocar una pieza con la fresa.

No parece facil solucionar esto, pero quizas se puede hacer más robusta la estructura.

20200905-143836.png 20200905-143805.png

  • Modelo B2: agrega más material al eje X y al eje Z. También baja la rosca del eje Z respecto a la mecha del Dremel.
  • Modelo B3: lo mismo, pero además agregando un carrito extra al eje X, que ayudaria a que el eje Z no se flexione ni se desplace en X/Y al cortar. Desventaja: hay que sacar las dos varillas de arriba.

0.7

20201201-134825.png

Si bien avancé un poco más con estos diseños, finalmente los abandoné, y reemplacé por otra geometría:

nz1jia.png

Power, feedrates and Microstepping

Ahora estoy corriendo todo a 12 V, con microstepping ⅛.

Leer:

Resumen:

  • El microstepping baja el torque máximo de los motores.
  • Es mejor usar un voltaje justo por debajo del voltaje máximo de los drivers (24V para A4988 o DRV8825).
  • La frecuencia maxima típica del paso es ~30kHz (aunque en teoría GRBL llega a 100 KHz) que a MS de ⅛ son como 20 vueltas por segundo.

Building and Uploading GRBL

on Arch Linux

Instrucciones: https://github.com/gnea/grbl/wiki/Compiling-Grbl

Si el compilador de Arch actual no sirve para compilar GRBL para arduino (porque ocupa demasiado espacio), hay que instalar un paquete viejo:

  sudo pacman -U https://archive.archlinux.org/packages/a/avr-gcc/avr-gcc-8.3.0-1-x86_64.pkg.tar.xz

Actualmente no tengo este problema.

From a headless RPi using ssh

  • Enable X11 forwarding on the RPi ssh server.
  • ssh -X pi@raspberryIP.
  • APT install arduino.
  • Run arduino. The gui should open. Set the correct port and board.
  • Add the GRBL library as a directory (the top level grbl directory with the doc, build and grbl subdirectories).
  • Open the GRBL upload example and upload it.

Troubleshooting

https://stackoverflow.com/questions/19765037/arduino-sketch-upload-issue-avrdude-stk500-recv-programmer-is-not-respondi

Error: avrdude: stk500_recv(): programmer is not responding.

O algo como not in sync.

Mi arduino tiene un capacitor en los pines de "abort" del cnc shield por otro motivo. Hay que sacarlo y reiniciar el Arduino para que el error se vaya.

Limit-switch wiring

La guía de GRBL es genial:

Z-axis limit switch

Troubleshooting: https://www.instructables.com/id/End-Stop-Limit-Switch-Problems/

Para que funcione el Z-end limit switch (end stop) tuve que deshabilitar variable spindle el config.h de la librería de Arduino de GRBL. Esto es porque el pin layout de GRBL cambio en la version 0.9 cuando agregaron la funcionalidad del variable spindle. Deshabilitarla revierte el pin layout a la forma compatible con el CNC Shield 3.0.

Cruzando los cables con una modificación de hardware esto ya no es un problema.

Z-axis probe

Tutoriales:

Wiring: https://crcit.net/c/99f1dd1943ae49debf53f9f1f2e57a29

  • El switch simboliza al probe.
  • GND va a conectado a la "base" del probe (o al cobre del PCB).
  • El lado del SCL va conectado a la punta o "spindle" del CNC (con un cocodrilo xej).

probe_circuit.png

Otros probes tipo "touch":

Wiring para el "tip probe" del robot pipeteador:

  • Placa PCB virgen al GND.
  • Tip cortado con cable dupont pegado al costado (y pin doblado).

Comandos para probar:

$H
G91 G0 Z-50
G38.2 Z-5 F200
G92 Z2.1
G90 G0 Z20
  1. Moverse rápido un poco por encima de la sonda.
  2. "Sondear" hacia abajo 5 mm como mucho.
  3. Configurar la altura actual como "cero" (en realidad, setear la altura actual al "alto de la sonda").
  4. Moverse 20 mm por encima del cero.

Para un cubo de 50 mm de alto (51.7 con sonda):

$H
G91 G0 Z-50
G38.2 Z-5 F200
G92 Z51.7
G90 G0 Z70

XY limit switches

Puse mascara de homing $23=3 para que haga homing en el X0;Y0 y puse los limit switches en el lugar a donde fue a hacer homing (al mirar esto esta bueno tener el dedo sobre el boton de reset por si algo anda mal).

Modificacion con end-stops de Makerbot

Para usar en paralelo dos modulos de Makerbot con su LED habilitado (o sea conectando los 3 pines) en el CNC shield, hay que cortar el pin NC (normal connected) en uno de los módulos del par en paralelo.

Esto es porque, al activar el interruptor, el VCC de un endstop queda conectado directamente a GND del otro endstop, produciendo un corto.

Hay un poco mas de info en la parte de variable spindle mas abajo.

En el diagrama se ve mejor:

20210217-180115.png

Leer:

YZ limit switches en paralelo para gantry

En el caso del doble eje Y, hay dos limit switches en paralelo (el Y y el Z) y solo uno se activa a la vez, porque el eje Z hace homing primero, y el Y después.

El NC de cada interruptor (que esta conectado a 5V) mantiene "alto" el pin "sensor" que comparten.

Pero cuando un switch se activa, baja el voltaje del pin sensor a 0V, mientras el otro interruptor sigue manteniendo el pin sensor a 5V sin resistor de por medio.

O sea, se produce un cortocircuito, y el Arduino se reinicia.

Para solucionar este problema, hay que cortar la patita "NC" de los limit switch que vayan en paralelo (ver foto a continuacion).

image823.png

La recomendacion general es cortar todas las patitas NC.

Monitorear limit switch

Para debuguear los limit switch, usar $10=16 y ver este instructivo. Ese setting es para el status report de GRBL < 1.1x, para 1.1+ el status report es 0, 1 o 2.

Para ver los cambios hay que habilitar el "verbose output" en el UGS clasico.

También se puede armar un script en Python: https://gitlab.com/pipettin-bot/pipettin-grbl/-/blob/master/grbl/scripts/simple_status.py

Ajuste Vref Pololu

Guides:

Esto me ayudó cuando uno de los motores del eje Y perdía pasos.

Mi motor es "LKD42BYGHW811", parece ser de 2.5A. Ahora Vref está en 1.65V, que corresponde a un límite de ~3.3A, así que ya estoy pasado. Quizás el problema sea la fuente, pero el voltaje no baja considerablemente.

Puse los DRV8825 en 1.170V aproximadamente. Es un octavo de vuelta en sentido horario.

Los útlimos A4988 que compré venían en 0.6V y era demasiado bajo. Los dejé en 1.1V, que es casi el máximo que podía obtener girando el tornillito.

Los pololus que hay en TECSCI son similares a estos:

20211208-103350.png

Los tutos anteriores estan caidos, aca hay otros:

Las mediciones dieron 0.8 Ohm, pero los resistores son de 200 Ohm según la inscripción. Puede ser que ese número pequeño sea algo del circuito en total, y no solo de esas resistencias.

Refrigeración de los controladores

Realmente se estaban calentando bastante, así que por las dudas le puse un ventilador arriba mientras hago las pruebas.

Me encanta improvisar.

20200424-075821.png

Problemas de Endstops por EMI

Problemas de Endstops por Interferencia electromagnética.

Tuve problemas usando un cable de stepper para un end-stop. No pude encontrar otra causa que el cable mismo: los cables que vienen con los sensores de fin de carrera del mismo largo no tienen este problema.

Consejos generales sobre electronica, alimentacion y ruido:

Más allá de eso, sigue siendo buena idea agregar "shielding" contra EMI, para que la electrónica sea menos sensible a interferencia (que venga del mismo CNC o de fuentes externas).

Otra cosa para hacer es "trenzar" o enroscar los cables, como si fueran un ADN. Eso también ayuda a que el cable del stepper tenga menos efecto sobre el del endstop.

Un google rápido da información útil:

En teoria para que funcione, el "shielding" tiene que conectarse a ground:

Aca usaron cables de ethernet para los limit switches, que por defecto vienen con shielding:

La solución más simple es soldar un capacitor de 0.47uF entre GND y cada pin sensor del endstop:

La otra es usar endstops "normal closed", que son mucho menos sensibles a EMI, y además se los considera más seguros, porque en cuanto se desconectan por estar dañados, se disparan las alarmas del endstop.

GCODEs de GBRL

https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands

  • $H - Run homing cycle
  • G90 para movimientos en coordenadas absolutas, ejemplo: G90 G0 X0 Y0 Z0
  • G91 para movimientos incrementales, relativas a la posición actual, ejemplo: G91 G0 Z1
  • G92 para modificar el origen de coordenadas, ejemplo: G92 X0 Y355 Z29
    • De forma que ahora se puede mover desde: G90 G0 X0 Y0 Z32
    • De forma que ahora se puede mover hasta: G90 G0 X325 Y355 Z-5 (por debajo de la mesa de corte)

Modal Group Member Words


Motion Mode G0, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80 Coordinate System Select G54, G55, G56, G57, G58, G59 Plane Select G17, G18, G19 Distance Mode G90, G91 Arc IJK Distance Mode G91.1 Feed Rate Mode G93, G94 Units Mode G20, G21 Cutter Radius Compensation G40 Tool Length Offset G43.1, G49 Program Mode M0, M1, M2, M30 Spindle State M3, M4, M5 Coolant State M7, M8, M9

Supported Non-Modal Commands

G4, G10 L2, G10 L20, G28, G30, G28.1, G30.1, G53, G92, G92.1

Errores de GRBL

Ver lista en su Wiki: https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface

Configuración de GRBL

Imprimir configuración actual con: $$

Ver:

Description Opción Valor de referencia Valores que usé miniCNC v2 Comentario


Step pulse, microseconds 0 10 10 10
Step idle delay, milliseconds 1 25 255 25
Step port invert, mask 2 0 0 0
Direction port invert, mask 3 0 1 0
Step enable invert, boolean 4 0 0 0
Limit pins invert, boolean 5 0 0 0
Probe pin invert, boolean 6 0 0 0
Status report, mask 10 1 1 1
Junction deviation, mm 11 0.010 0.010 0.010
Arc tolerance, mm 12 0.002 0.002 0.002
Report inches, boolean 13 0 0 0
Soft limits, boolean 20 0 1 1
Hard limits, boolean 21 0 1 1
Homing cycle, boolean 22 1 1 1
Homing dir invert, mask 23 0 0 3 (mask 00000011 inv. XY) Homing feed, mm/min 24 25.000 25.000 50.000
Homing seek, mm/min 25 500.000 500.000 1000.000
Homing debounce, milliseconds 26 250 250 250
Homing pull-off, mm 27 1.000 3 3.000
Max spindle speed, RPM 30 1000 1000 1000
Min spindle speed, RPM 31 0 0 0
Laser mode, boolean 32 0 0 0
X steps/mm 100 250.000 250.000 250.000
Y steps/mm 101 250.000 250.000 250.000
Z steps/mm 102 250.000 250.000 250.000 V2: microstep igual al XY. X Max rate, mm/min 110 500.000 500.000 1000.000
Y Max rate, mm/min 111 500.000 500.000 1000.000
Z Max rate, mm/min 112 500.000 500.000 500.000
X Acceleration, mm/sec² 120 10.000 10.000 20.000
Y Acceleration, mm/sec² 121 10.000 10.000 20.000
Z Acceleration, mm/sec² 122 10.000 10.000 10.000
X Max travel, mm 130 200.000 328.000 200.000
Y Max travel, mm 131 200.000 358.000 200.000
Z Max travel, mm 132 200.000 37.000 33.500 29.5 con mecha x ej.

Mi configuración:

  • Tuve que invertir el motor X y cambiar de lado el sensor de fin de carrera del eje X (opción 3). Como estaba originalmente, GRBL hacia bien el homing cycle, pero el muy gil del software pensaba que tenía lugar para moverse en la misma dirección en la que va el sensor (y nada de lugar en la dirección donde si había lugar para moverse).
  • Para habilitar los soft limits antes tiene que estar encendido el homing cycle también (opción 22) y tiene que quedarse encendido).
  • El valor por defecto de de la opción 27 no fue suficiente.
  • Para el gantry se dice que: "Highly recommend keeping the motors always enabled to ensure the gantry stays square with the 1 setting".

Obs: la opción 10 con valor 16 sirve para probar los limit switches, ver lo que está escrito más arriba.

Configuración del orgien de coordenadas

El GRBL pone su origen de coordenadas de manera que el espacio de trabajo puede estar en posiciones de XYZ con valores positivos o negativos. Por comodidad en la generación del GCODE, uso G92 para dejar todo el espacio de trabajo en valores positivos de posición en todos los ejes.

Nota: los valores del comando G92 dependen de en que direccion se hizo el homing, y de si alguno de los ejes está invertido.

El G92 que hay que usar depende de en que lugar del espacio de trabajo se haga el homing. Si $23=0 entonces la maquina queda en X0, Y0, pero si está en $23=3 entonces queda en X-100, Y-100 (imaginando que 100 es el X/Y max configurado).

$23=3 es útil porque la máquina hace homing en el punto respecto al cual todas las coordenadas están en espacio "más positivo". Después de aplicar un comando del estilo G92 X0 Y0 todo el espacio de trabajo estará en coordenadas positivas.

$H ; Run homing cycle
G92 X0 Y0 Z29 ; esto pone el punto de homing como la coordenada X0 Y0 Z29

Más abajo hay detalles y explicaciones sobre G92.

Nuevas partes para el CNC

Ahora que actualice las partes, tengo 43 mm de movimiento en el eje Z (son 40 mm contando que 3 mm se pierden alejandose del limit switch). Para no complicarmela acorte los ejes X e Y a 250 mm:

$H ; Run homing cycle
G92 X0 Y247 Z40 ; esto pone el punto de homing como la coordenada X0 Y250 Z39

Opción Description Valor de referencia Valores que usé


27 Homing pull-off, mm 1.000 3 130 X Max travel, mm 200.000 250.000 131 Y Max travel, mm 200.000 250.000 132 Z Max travel, mm 200.000 40.000

Stepper wiring y sistema de coordenadas

Ahora digamos que necesito que el eje Y tenga coordenadas positivas "hacia abajo":

20200903-231153.png

Para lograr esto hay que tener bien dos cosas:

  • Cableado de los motores.
  • Configuración de la dirección de los steppers en GRBL.

El primer problema que tuve es que los steppers y cables que tienen no son todos "estándar". Así que tuve que cruzar algunos cables y dar vuelta fichas para que todo quede andando como se espera por configuración de GRBL estándar. Después, cambiando $3 (invert stepper dir), $5 (invert limit switch) y $23 (invert homing dir) se consigue la configuración deseada. En mi caso:

text1330-3.png

En el PDF que armé (sistema_de_coordenadas.pdf) la tercera configuración es la que va.

Ver más abajo la configuración de GRBL para profundizar con este tema.

CoreXY stepper wiring

Ver: https://discord.com/channels/627982902738681876/687774244918263852/1012058494163243050

CAM Software y Generadores de GCODE

Generación de GCODE con scripts de Python "simples" del proyecto Linux CNC: https://github.com/LinuxCNC/simple-gcode-generators

Además de las opciones abajo, también usé http://jscut.org/ pero es dificil configurar bien las coordenadas del eje z.

Se puede resolver este tema de las coordenadas negativas con G92:

KiCAD y pcb2gcode

Ver: proyectos/diy/cnc/kicad_pcb

Inkscape SVG + jscut

Paso 1: hacer un diseno en Inkscape y pasarlo a "path".

Paso 2: usar JScut para generar el GCODE (ver detalles en su seccion).

Paso 3: usar UGS para configurar GRBL y enviar el GCODE.

FreeCAD Path Workbench

Puede cavar superficies "planas", o sea, no puede hacer una montañita realmente.

Lo que tiene de bueno es que lo único que tuve que hacer para que el GCODE quedara bien es agregar un comando G92 para que el espacio de trabajo de GRBL quedara en coordenadas positivas.

Obviamente en FreeCAD hay que asegurarse de hacer lo mismo con los modelos.

PyCAM

Está hecho en Python2, pero en Arch usa Python3 por defecto. Hay que hacer un par de cosas para que funcione bien (ver instrucciones).

Instrucciones:

  • Instalar dependencias http://pycam.sourceforge.net/requirements/
    • Python bindings to OpenGL (Arch: python2-opengl y AUR python2-gtkglext).
    • python3-gi Python bindings for gobject-introspection libraries (Arch: gobject-introspection ??)
    • python3-opengl GTK graphical user interface library -- gir bindings (Arch: ??)
    • python-gtk2
  • Bajar https://github.com/SebKuzminsky/pycam/releases
    • Modificar el archivo "pycam" para que la primera línea sea #!/usr/bin/python2 en vez de #/usr/bin/env python. En Arch Linux python3 es la versión que se usa por defecto, el tipo que hizo pycam solo estaba pensando en su Ubuntu.

Hay data sobre como usarlo en su sitio, por ejemplo:

Blender CAM

https://github.com/vilemduha/blendercam/wiki/

La extensión para Blender 2.8 anda lo suficientemente bien como para hacer las pruebas.

Primero hay que instalar el plugin como dice la web oficial: https://github.com/vilemduha/blendercam/wiki

Luego, para que ande, hay que entrar a utils.py y cambiar todas las ocurrencias de time.clock() por otra función; esa se eliminó de python3.

Para empezar a usarlo, abrir Blender, acceder al tab-menú "Rendering" y en el menú desplegable de "Render engine" seleccionar "Cam".

Importante: el punto más bajo del modelo tiene que estar por encima de la altura mínima del "Working Area". Además, para que no corte al pedo, se puede setear "operation depth start" igual a la altura máxima del modelo (no sé por qué no hace esto por defecto).

Luego, con todo bien configurado en las opciones de Blendercam, se exporta el archivo .ngc con el gcode.

Luego solamente hará falta cambiar el "header" y el "footer" del .ngc para que haga el homing cycle al principio con $H, y configure bien el origen de coordenadas con G92, entre otras cosas (ver archivos en blender_example_with_header_and_footer.zip).

Agregar G92 es necesario porque normalmente GBRL opera en coordenadas negativas para todos los ejes (no solo para el Z) y varios programas tiran su output solamente en coordenadas positivas:

"Why is Grbl in all negative coordinates after homing? Or it so annoying and not what I'm used to! When homing is enabled, Grbl sets all of the machine space in negative space. This may seem unusual to people who own 3D printers or newbies, but this is how it has been historically in CNC mills (and due to a misunderstanding how to use work coordinate systems and tool offsets...)"

Reemplazando la parte del principio del gcode con el header evitamos problemas con eso:

; Custom header, it must replace the original!

$H ; Homing cycle

G92 X0 Y355 Z0 ; Setup offests, so X and Y operate in positive space only.

G21 ; units (mm)

G17 ; plane select (XY)

G90 ; distance mode (absolute)

G0X0Y0Z00 ; move to origin

Footer, para volver al inicio al terminar:

; Custom footer
G0X0Y0Z00 ; return to origin

OpenBuilds CAM

https://software.openbuilds.com/

20201129-094738.png

Parece bueno!

Solo que para el "continuous drill" el plunge está buggueado: el movimiento rápido de bajada inicial a Z0 es lenta (F10) y la bajada de agujerear a Z-5 que debería ser lenta es rápida (F1000). Ver issue.

G0 Z10
G0 X2.8540 Y56.5253

G0 Z0
G1 F10 Z0.0000
G1 F1000 X2.8540 Y56.5253 Z-5.0000 S1000
G1 F1000 X2.8540 Y56.5253 Z0.0000 S1000

Lo edité en sublime text con una regex:

20201129-104738.png

G1 F1000 (.* Z-5.*)
G1 F50 \1

JScut.org

Example files and settings: 3.53mm_dot_test.zip

Tool settings

20200627-150243.png

Ver: diametro-del-eje-de-la-fresa

Material settings

Configrurar el material:

  • Espesor del material (20 mm por ejemplo).
  • Z-origin en bottom.
  • Clearance en mas de 5 mm por ejemplo.

Como armar la mesa:

  1. La mesa debe estar en la coordenada Z0 (o quizas Z-1 seriviria?).
  2. Poner el material sobre la mesa, de forma que la superficie superior del material este a una altura tal que coincida con la coordenada Z09 (JScut va a cortar desde esa capa y hacia abajo, hasta Max Cut Depth).
  3. Asegurar el material a la mesa de alguna manera.

20200623-181753.png

Gcode settings

Use "zero lower left" en JScut para tener todo en positivo en esta configuracion.

20200623-181841.png

Hay que asegurarse de que el sistema de referencia este bien configurado; para que todas las coordenadas XY sean positivas con origen en el X0 Y0 (porque tengo configurado asi el GRBL).

Despues de generar el path en JScut, hay que editar el gcode. Por ejemplo:

$H ; homing cycle
G92 X0 Y247 Z40 ; puede variar, en general para X o Y es: MAXIMO - HOMING PULL-OFF
G0 X60 Y55 Z2 ; esta es la esquina de la base que puse, la superficie esta en Z = 2-3 mm
G92 X0 Y0 Z0 ; esto pondria el origen bien, pero el Z0 es muy alto, deberia ser Z-0.5 para estar justo encima

screenshot_2020-06-27_18-45-54.png

Entonces mi header completo seria:

$H
G92 X0 Y247 Z40
G0 X60 Y55 Z2.5
G92 X0 Y0 Z0

Agregarle lo anterior al inicio del GCODE de JScut.

Area chica

Para la tablita de madera que puse en el CNC con area achicada, los settings son estos:

$H
G92 X-115 Y-10 Z30.5

Como ademas le cambie los limit switches y la homing mask, solo hace falta ese par de comandos para que todo quede en orden.

Quizas ademas pueda hacer algo en los settings respecto de $H para ni siquiera tener que usar G92.

El CNC no le da bola al feedrate que pongo en JScut, pero con el override en UGS a 1000% anduvo mucho mejor.

Resultado

El agujero quedo bien! peeero las dimensiones no son perfectas:

  • Diametro en X: 3.5 mm
  • Diametro en Y: 3.7 mm

Creo que es porque las varillas guia del eje Z estan flojas (necesito varillas mas largas).

20200623-182218.png

G-Code Sender

El UGS está bien, pero hay muchos más:

Autonivelado

Para hacer grabados y PCBs, es importante tener bien nivelada la superficie. Pero es un bardo, asi que los programas que mandan el gcode tienen una funcion para recalcular alturas en base a mediciones con el probe de GRBL.

Opciones:

Ya que bCNC funciona bien, me quedo con ese :)

Ver también:

UGS

Se puede instalar en el RPi y usar con joystick/jogging:

bCNC

Parece estar bueno, esta escrito en python.

Requisitos:

sudo apt install python-pip
sudo apt install libjpeg-dev zlib1g-dev  # Pillow dependencies
sudo apt install python-tk               # bCNC dependency

Opciones de instalación:

pip2 install --upgrade bCNC
# pip2 install --upgrade git+https://github.com/vlachoudis/bCNC
# pip2 install . #in git directory
# python2 -m pip install --upgrade bCNC

Para hacerlo headless, primero entrar por ssh con la opción "-X":

ssh -X pi@raspberry
python2 -m bCNC

Y lo mismo para configurar el joystick con qjoypad.

Jogging y Joystick key mapping

Por defecto se puede hacer click en el área "blanca" de bCNC y eso manda comandos:

bCNC Jogging Keyboard keys:

  • pan +X
  • pan -X
  • pan +Y
  • pan -Y
  • pan +Z
  • pan -Z
  • < + > or < = > Increase step by one unit (=current decade)
  • < - > or < _ > Decrease step by one unit (=current decade)
  • < 1 > Set as step the step1 (default 0.1) value from the configuration
  • < 2 > Set as step the step2 (default 1) value from the configuration
  • < 3 > Set as step the step3 (default 10) value from the configuration
  • <*> Multiply step by x10
  • Divide step by /10

Se puede conectar un joystick al Raspberry Pi y usarlo para mandar esas teclas:

sudo apt install qjoypad

20200823-144649.png

En la chromebook me faltaban algunas teclas asi que usé el teclado virtual "Onboard" que se ve ahí.

bCNC en GalliumOS
sudo apt install python-pip
sudo apt install python-tk               # bCNC dependency
pip2 install opencv-python==4.2.0.32 bcnc

chilipeppr

Se puede examinar y madnar el GCODE por web usando http://chilipeppr.com/grbl (o http://chilipeppr.com/jpadie)

OpenBuilds CAM

Es de los mejorcitos.

Obs: la última vez que miré, todavía tenía un bug en los feedrates pero se puede esquviar.

Fresas y Motor del Spindle

El Dremel 3000 gira entre 5000 RPM y 320000 RPM. Según la teoría del fresado, girar demasiado rápido y avanzar muy lento va a romper cualquier fresa, porque se funden.

Con el Dremel CNC podría cortar polyfoam tranquilamente, pero el EMDF y el aluminio son complicados.

Sin embargo, es posible:

  • Info sobre bits/fresas: https://youtu.be/239aFAqYBpQ?t=321
    • 1 Flute Router Bit
    • Tungsten steel (cemented carbide)
    • 3.175 mm Shank diameter
    • 3.175 mm Cutting edge diameter
    • 17 mm Cutting edge Length
    • 40mm Overall Length
  • En esta guía, recomiendan fresas "true" end-mill, en vez de las cuadradas.

En mercadolibre hay opciones de "metal duro". Según un documento de la marca "Ditoma" son aleaciones de carburo de tungsteno con cobalto. El documento entero es muy educativo: ditoma-metal_duro-fresas-mechas-integrales-metal-duro.pdf.

Las fresas integrales de metal duro (carburo de tungsteno) se utilizan entonces, especialmente, para operaciones de ranurado, planeado, perforado, desbaste y acabado de piezas metálicas.

Las fresas sólidas de metal duro son fabricadas, generalmente, de carburo de tungsteno aleado con cobalto (Co).

En mercadolibre hay opciones:

Diametro del eje de la fresa

El minitorno Dremel solo acepta fresas con diámetro de eje hasta 3.2 mm.

Acrílico

Para agujerear acrílico (o plásticos) no da igual la fresa.

Usé una de 1 filo y 1 mm de diámetro para agujerear una tapa de acrílico.

https://articulo.mercadolibre.com.ar/MLA-779424761-fresa-cnc-router-1-filo-metal-duro-1mm-corte-util-4mm-wood-_JM

Opciones

Estas podrian servir:

{{:proyectos:diy:cnc:20200627-153001.png?0x200}} {{:proyectos:diy:cnc:20200627-153123.png?0x200}}

Fresa Cim Tek BW-C22ER

La fresa de 4 mmde shaft no se puede agarrar con los mandriles del dremel 300 que tengo. Tuve que hacer un hack horrible con cinta y pistola de goma para que quede agarrada.

  • Punta de las fresas: Esferica (ball nose).
  • Material: Metal duro (carburo de tungsteno).
  • Revestidas: Si TIALN.
  • Diametro: Ø 2 mm
  • Cabo: Ø 4 mm
  • Largo Total: 50 mm

La ball-nose que compre tiene 4 mm de diametro de "shaft" pero el Dremel solo acepta hasta 3.2 mm.

Tener en cuenta para la proxima!

Fresas para PCB

Parece que se usan unas en forma de "V" para los circuitos y unas normales para hacer los agujeros.

https://listado.mercadolibre.com.ar/fresa-cnc-pcb_TiempoEnvio_ProximoDia

Ver:

Laser NEJE 40640

El último marco CNC (2022/03) tiene doble motor en Z y en Y.

  • El Y está duplicado con los jumpers, porque el modo gantry no es compatible con tener el variable spindle pin (para el laser). * El Z está duplicado con un segundo CNC shield, puenteando los pines de 5V, GND, STEP, y DIR con cablecitos dupont.

D11 es el Z- axis pin del CNC shield clone, de ahi sale el PWM "variable spindle" para el láser.

Gantry mode tiene que estar deshabilitado.

\$32=1 habilita el "laser mode" de GRBL: https://github.com/gnea/grbl/blob/master/doc/markdown/laser_mode.md

\$30=100 dice que el max spindle speed (o el maximo del laser en este caso) corresponde a un comando tipo S100. Es importante que el feed en el GCODE corresponda al setting de máximo feed de GRBL.

bCNC config, solapa "CAM":

  • material=maderita: feed 50 (la mitad de \$30), plunge feed 500 (para que se mueva rapido en Z) y depth increment 0. * stock=default: todo en cero, material=maderita (el material creado arriba). * end mill=NEJE-A40640-Laser: type=engraving, shape=V-cutting, material=solid carbide, coating=None, diameter=0.1, mount axis=1.0, flutes=1, length=1, angle=0, stepover=20. No sé si algo de esto es importante. * botón Config: cambiar/quitar cosas del header y footer que molestan.

  • Header GCODE: quitar el movimiento en Z y poner el M3 o M4 del spindle/laser en S50 para que coincida con un porcentaje de \$30.

    • M4 S20 (M4 es "Dynamic Laser Power Mode", puede ser M3 ("Constant Laser Power Mode") para que obedezca los comandos S del GCODE program).
    • Remover lo demás.
  • Footer gcode:
    • M5 (deshabilitar laser).
    • Remover lo demás.

bCNC text:

  1. CAM tab 2. "CAM" dropdown menu (below the leftmost icon set) -> Generator -> Text 3. Text options:

  2. Font=/usr/share/fonts/truetype/ubuntu/Ubuntu-C.ttf

  3. working depth = 0
  4. font size = 10
  5. close contours=true
  6. iamge chars width = 80 (default)

  7. Tocar el botón ancho arriba de las options que dice "Text" para generar el texto.

Antes de hacerlo andar, centrar la maquina sobre la pieza, y apretar XYZ=0 en el tab de "Control".

Trubleshooting

Me pasó que el láser, de repente, no pasaba de 4% cuando usaba el variable spindle. Sin importar que M3 SXX le mandara o que $30 configurara.

El problema se solucionó ajustando los cables dupont que conectaban D11/GND con TTL/GND en el módulo de control del láser. Parece que estaban meido sueltos.

Variable Spindle PWM para controlar un Servo

Antecedentes:

Hasta no hackear mi CNC Shield v3.00 para que sea compatible con GRBL v0.9+ esto es imposible. Ver mas arriba para notas sobre esto.

No es tan trivial hacerlo con Arduino y GRBL:

La frecuencia del PWM del pin en GRBL es más alta que la que entienden los servomotores tipo "hobby".

Por defecto los servos básicos funcionan con PWM a 50 Hz (T=20 milisegundos) pero tienen cierta tolerancia (ref.).

Lo importante es que el "duty cycle" (el tiempo con voltaje alto) esté entre 0.5 ms y 2.5 ms (readme).

Pero el variable spindle de GRBL usa por defecto 0.98kHz (T~1 ms). Hay que bajarlo 20 veces para estar en el rango. Si le pudiera bajar la frecuencia 4 veces (para tener un duty cycle máximo de 4 ms) quizás alcanzaria.

Comandos GRBL para el spindle

M3 - start the spindle clockwise at the S speed.
M4 - start the spindle counterclockwise at the S speed.
M5 - stop the spindle.

M3 S1000; would set CW rotation at 1000 rpm

Cableado

Como este: https://lastminuteengineers.com/servo-motor-arduino-tutorial/

El pin de "spindle enable" en el CNC shield 3.0 (modificado para poder usar el variable spindle) debería ser el "variable spindle" y va al cable amarillo de mi servo.

Alimentación: 5V al cable rojo (internet dice que hasta 7 esta bien)

20200816-155806.png

Timers e interrupts en PWM

"A timer is a counter with a clock input"

Segun entiendo el PWM se genera activando o desactivando el voltaje del pin en determinados momentos del contador.

El contador tiene cierto "tamaño" que determina cuantas cuentas puede contar. Un oscilador envia una cuenta al contador de acuerdo a su frecuencia caracteristica. El reloj del sistema anda a 16 MHz, y diferentes timers pueden contar mas o menos veces antes de "llenarse" y empezar de nuevo:

  • Timer 0: 8-bit (0-255)
  • Timer 1: 16-bit (0-65535)
  • Timer 2: 8-bit (0-255)

Como la frecuencia del reloj es la misma para todos, timer1 se llena mas lento que el timer0 y el timer2.

Hay 3 timers, y la frecuencia del PWM que puede generar cada uno depende del reloj del sistema y de algunos parametros que se pueden configurar para cada timer. Los principales parametros son "Prescaler" y "PWM mode".

Para el timer 2 que usa el variable spindle PWM, los parametros son:

  • Prescaler: por defecto Arduino lo inicia en 1/64, GRBL tambien.
  • PWM mode: por defecto Arduino lo inicia en "Phase Correct PWM", pero GRBL lo pone en "fast PWM mode".

Quizas podria cambiarlo a "Phase Correct PWM" para bajar la frecuencia a la mitad. Aunque no se que efecto podria tener eso en otras cosas. El timer 2 tambien afecta el pin 3, que se usa para el stepper.

Para mas informacion, leer: https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Variable Spindle PWM Frecuency para Servo

Antecedentes:

El archivo cpu_map.h tiene la configuracion de los timers:

// Prescaled, 8-bit Fast PWM mode.
    #define SPINDLE_TCCRA_INIT_MASK   ((1<<WGM20) | (1<<WGM21))  // Configures fast PWM mode.
    // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS20)               // Disable prescaler -> 62.5kHz
    // #define SPINDLE_TCCRB_INIT_MASK   (1<<CS21)               // 1/8 prescaler -> 7.8kHz (Used in v0.9)
    // #define SPINDLE_TCCRB_INIT_MASK   ((1<<CS21) | (1<<CS20)) // 1/32 prescaler -> 1.96kHz
    #define SPINDLE_TCCRB_INIT_MASK      (1<<CS22)               // 1/64 prescaler -> 0.98kHz (J-tech laser)

Que despues se usa en spindle_control.c:

    SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK; // Configure PWM output compare timer
    SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK;

Esos son los registros TCCR2A y TCCR2B, definidos con ese otro nombre en cpu_map.h:

    #define SPINDLE_TCCRA_REGISTER    TCCR2A
    #define SPINDLE_TCCRB_REGISTER    TCCR2B

Usa timer 2 por defecto. Ese timer tiene outputs en dos pines del Arduino:

  • Pin 11: Timer 2 "A” output (OC2A) - normalmente "Variable spindle PWM".
  • Pin 3: Timer 2 "B” output (OC2B) - normalmente "[motor] Step pulse".

20200627-223606.png

Cambios al codigo de GRBL

La frecuencia del timer 2 se cambia en el registro TCCR2B con los bits CS22, CS21 y CS20:

20200628-013554.png

Para cambiar el timer de prescaler 64 a 1024 podria hacer esto:

// Prescaled, 8-bit Fast PWM mode timer 2.
    #define SPINDLE_TCCRA_INIT_MASK   ((1<<WGM20) | (1<<WGM21))  // Configures fast PWM mode.
    #define SPINDLE_TCCRB_INIT_MASK   ((1<<CS22) | (1<<CS21) | (1<<CS20)) // 1/1024 prescaler

Aca hay info de como fue eso y otras alternativas:

El problemita del 50% duty cycle en el pin 11 solo aparece con fast mode "with OCRA" (WGM flags 111). Por suerte GRBL usa el fast mode "normal" (WGM 011 creo), asi que no es un obstaculo.

En ese thread se dijo:

I don't use an AVR but wouldn't setting the prescaler to 1024, MINIMUM_SPINDLE_PWM roughly 15, PWM_MAX_VALUE roughly 23, give you something rather coarse but usable?

~1ms to ~1.5ms, 61Hz update rate

Calculo de frecuencia con prescaler 1024 en fast mode:

Output A frequency: 16 MHz / (1024 * 256)  = ~61.03 Hz

Es casi lo tipico del servo ~50 Hz, un poco mas seguro no lastima.

Entonces, cada bit del timer vale:

Period = 1 / 61 Hz ~ 16.4 ms
Counter tick time = 16.4 ms / 256 ticks por periodo ~ 0.06 ms (para 1 "clock tick" del timer de 8 bits)

Entonces el rango de bits para tener pulsos de 0.5 ms a 2.5 ms es:

0.5 ms ~ 8 ticks
2.5 ms ~ 41 ticks

Eso significa que deberia configurar el PWM en GRBL tal que:

#define SPINDLE_PWM_MAX_VALUE 255 // cpu_map.h // Don't change. 328p fast PWM mode fixes top value as 255.
#define SPINDLE_PWM_MIN_VALUE 8   // config.h

Y el max/min de RPMs podria reflejar ese rango directamente:

#define RPM_MAX  255.0   // config.h
#define RPM_MIN  8.0    // config.h

De esta forma cubro mas o menos todo el rango de duty cycle de un servo estandar.

Deberia chequear que mi servo responda tambien entre 0.5 ms y 2.5 ms

Deberia chequear las cuentas, hice varios redondeos.

Podria probar con prescaler 256 (f ~ 240 Hz, T ~ 4.1 ms), para tener 0.016 ms por tick. Asi, el rango de valores de PWM que puedo configurar se agranda a 31-156, aumentando la resolucion. Pero no se si funcionara bien eso, hasta 100 Hz parece que andan pero no se a 240 Hz.

Mejoras

No perder pasos: https://hackaday.com/2016/06/01/mechaduino-closed-loop-stepper-servos-for-everyone/

Conseguir extra digital pins: https://www.instructables.com/id/How-to-add-6-extra-pins-to-your-Arduino-with-no-ex/

Z-Probing alternatives

Además de la placa de cobre, se pueden usar otras cosas.

  • Un dinamómetro/celda de carga para medir fuerza.
  • Un end-stop simple, mecánico u óptico.
  • Un sensor tipo "BLTouch".

Square gantry

Esto es incompatible con el control del servo, pero en teoria no es imposible: https://blog.protoneer.co.nz/arduino-cnc-shield-v3-00-assembly-guide/#4THAXIS

Incompatibilidad con variable spindle

// Variable spindle/laser mode IS supported, but only for one config option.
// NOTE: Protoneer CNC Shield v3.51 has A.STP and A.DIR wired to pins A4 and A3 respectively. Coolant pin A3 is moved to D13, replacing spindle direction.
// NOTE: Arduino CNC Shield Clone (Originally Protoneer v3.0) has A.STP and A.DIR wired to D12 and D13, respectively. With the limit pins and stepper enable pin on this same port,the spindle enable pin had to be moved and spindle direction pin deleted. The spindle enable pin now resides on A3, replacing coolant enable. Coolant enable is bumped over to pin A4 (not used/reserved). Spindle enable is used far more and this pin setup helps facilitate users to integrate this feature without arguably too much work. 
//
// Variable spindle (i.e. laser mode) does NOT work with this shield as configured.

En config.h sobre activar variable spindle:

// NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch!

20200628-095925.png20200628-095837.png

Eso no es un problema tan grave, se puede solucionar alterando el shield para cruzar los cables.

Segun la documentacion de GRBL, el gantry no funciona junto al variable spindle en el CNC Shield v3.00:

// Variable spindle (i.e. laser mode) does NOT work with this shield as configured. While variable spindle technically can work with this shield, it requires too many changes for most user setups to accomodate. It would best be implemented by sharing all limit switches on pins D9/D10 (as [X1,Z]/[X2,Y] or [X,Y2]/[Y1,Z]), home each axis independently, and updating lots of code to ensure everything is running correctly.

Para habilitar el gantry sin el variable spindle, en config.h, encontrar la linea:

  #define VARIABLE_SPINDLE // Default enabled. Comment to disable.

Y comentarla para deshabilitar el variable spindle:

  //#define VARIABLE_SPINDLE // Default enabled. Comment to disable.

Luego activar el gantry:

#define ENABLE_DUAL_AXIS
#define DUAL_AXIS_SELECT  Y_AXIS
#define DUAL_AXIS_CONFIG_CNC_SHIELD_CLONE

Variable spindle y limit switches para gantry squaring

Mi CNC tiene dos motores para el eje Y, pero solo un limit switch (end-stop). GRBL 1.1h permite configurar dos end-stop para un solo eje.

Los limit switches de makerbot tipo NO (normal open) tienen un problema. Al conectarse en paralelo y activarse, resetean el Arduino. Por algún motivo, a los switches que van en paralelo hay que cortarles el pin NC (que no se usa en la configuración NO) y así todo funciona.

  • Los release notes de 1.1h y el config.h tienen algo de info.
  • La documentación del Arduino CNC Shield v3.0 puede ayudar.

Este modo de GRBL reconfigura los pins de la configuracion sin variable spindle de esta manera:

20191117-111541.png

Hay que poner los jumper en los pins que corresponden a los marcados en rojo en la figura.

Nota: se pierde el pin de "spindle direction" en esta configuración.

Square gantry con Variable Spindle HACK

La solucion facil es no usar el dual axis, y simplemente reflejar el eje Y en el motor A.

Work in progress...

Please note, grbl v.09 has moved one of the limit switch pins!!

Leer la parte del CNC Shield en:

Estuve usando la version 1.1h. El intercambio de pins entre Z-limit y spindle ocurrio en la version v0.9. El CNC shield v3.10+ dice ser compatible con este cambio:

Arduino CNC Shield V3.10 – GRBL v0.9 compatible (PWM Spindle + Soft limits)

Ahora la pregunta es: cual tengo yo? Tengo la 3.00 y, lamentablemente, no alcanza:

Version 3.10+
Added Support for GRBL 0.9v with PWM Spindle.

Y realmente es asi:

JCDaniel:
Fol older shield boards like mine (Ver. 3.00), just coment this line and the pin layout wil be not switched.

Necesito una 3.10+, o hackear la que tengo.

Para habilitar el variable spindle de nuevo deberia:

  • Cruzar los cables de los pines D11 y D12 para que coincidan con el shield viejo. Eso haria que se pueda usar el variable spindle tal cual.
  • Lidiar con el tema del Z limit switch. Esa seria la incompatibilidad con el gantry.

20200628-114036.png

Desafortunadamente parece que el ENABLE_DUAL_AXIS esta metido en varias partes:

20200628-114352.png

Parece dificil asi que podria intentar hackear el shield mas todavia.

Diagramas de circuito - Shield clonado 3.00

20200628-115324.png 20200628-122511.png {{:proyectos:diy:cnc:20200628-122821.png?0x200}} {{:proyectos:diy:cnc:20200628-122917.png?0x200}}

Diagramas de circuito - Shield original 3.51

{{:proyectos:diy:cnc:20200628-121011.png?0x200}} {{:proyectos:diy:cnc:20200628-130244.png?0x200}} 20200628-121904.png20200628-121913.png {{:proyectos:diy:cnc:20200628-122101.png?0x200}}

Cloning the whole board

20200816-081016.png

http://diyprojects.eu/how-run-two-cnc-shields-cloned-on-one-arduino/

Múltiples herramientas

Estructura

Tiene mucho flex, achicando todo y poniendo más barras quizás mejore.

Eje X

Para el carrito del eje X (el de movimiento horizontal de un solo motor, y sobre el que se monta el eje Z vertical) por ahi sería mejor disponer 4 varillas de metal en la forma 2 (o 6).

20200528-114114.png

Lina dijo:

cuando tienes un material rígido fijado en 4 puntos q estan distribuidos como un cuadrado, lo que se resiste al movimiento de flexión, lo que Arriostra, es la tensión que se genera sobre todo en lasdiagones al interior de esecuadrado,

si quito uno de esos puntos de fijación, ya no tengo la resistencia diagonal

Eje Y

Para el eje Y (con dos motores en escuadra, sobre el que el eje X se monta) no hay mucho lugar para mejorar, contribuye poco al flex.

Pero el lugar donde se monta el eje X es lo que mas se mueve de todo. Lina pensó lo siguiente:

20200528-114745.png

Y podría agregarse una varilla a la base:

20200528-115343.png

Eje Z

Habría que modificarlo para que funcione con el diseño 2 (o 6) del eje X.

Podría dejar fijo un lado de los extremos del eje a lo que sujeta el Dremel, y dejar que se desplacen sobre los rulemanes, fijos sobre el carrito del eje X. Aunque le daría más rango, podría no ser tan robusto, ya que en el diseño actual los ejes están fijos en ambos extremos al carrito del eje X, y solo el soporte del eje Z se desplaza.

Version II

Falta achicarlo en XY y cortar varillas.

20200628-002723.png

CNCs basados en control directo por Raspberry Pi

GPIO directio a los stepper drivers

pigpio note

At the moment pigpio on the Pi4B is experimental. I am not sure if the DMA channels being used are safe. The Pi4B defaults are primary channel 7, secondary channel 6. If these channels do not work you will have to experiment. You can set the channels used by the pigpio daemon by invoking it with the -d and -e options, e.g. sudo pigpiod -d 5 -e 8 to specify primary 5, secondary 8.