Edit: Un billet sur une version plus récente de GRBL est disponible : http://www.civade.com/post/2014/01/02/Arduino-et-GRBL-l-incontournable-solution-pour-piloter-une-petite-CNC.

Introduction: la CNC sur arduino

freeduino_proto0603-2.jpgArduino est une petite carte électronique open hardware, avec son environnement de développement open source, qui permet très simplement de développer en C et de tester en envoyant par un lien USB sur la plateforme. Déjà abordée à plusieurs reprises dans ce blog ( http://www.civade.com/tag/arduino ), cette plateforme permet très facilement, grâce à une fantastique bibliothèque de code, de faire pratiquement n'importe quoi ... a condition de faire tenir son programme dans les 32Ko de flash et les 2Ko du processeur ATMEGA368.

C'est aussi facilement abordable pour un programmeur qui veut se mettre au 'matériel' grâce à la simplicité de mise en œuvre des entrées sorties, qu'à un électronicien qui veut se mettre au logiciel grâce aux nombreux exemples livrés ou disponibles sur l'Arduino Playground ( http://www.arduino.cc/playground/ ).

Petite visite en vidéo avant de voir le détail:

Choix du micrologiciel :

Bien sur dans un aussi petit processeur, il n'est pas question de disposer d'une interpolateur de Gcode haut de gamme comme celui intégré dans EMC2 ou Mach3, mais plus d'avoir un compromis acceptable. Par contre, cela permettrait de s'affranchir des contraintes de temps réel, si difficile à obtenir sur PC. En effet, tout le calcul de pas et d'accélération étant confié à un processeur dédié, indépendant, et n'ayant pas à gérer l'environnement graphique de l'utilisateur, cela simplifier l'approche.

J'ai testé plusieurs solutions d'interpolateur de Gcode pour Arduino, et la plus rapide et fonctionnelle semble Grbl (http://dank.bengler.no/-/page/show/5470_grbl ).

Entièrement écrit en C , et optimisé pour tenir parti de fonctionnalités intégrées à l'ATMEGA368 (timers, pwm, etc..), Il est paramétrable par la liaison série (accélération, nombre de pas par mm pour chaque axe, etc..) et reçoit le Gcode par le même canal.

Il a été sélectionné par Jonathan Ward, du département 'Machines That Make' du MIT pour son projet 'MTM Snap' ( http://mtm.cba.mit.edu/machines/mtm_snap-lock/ ) et par Synthetos comme moteur d'une shield commerciale de moteurs pas à pas nommée Grblshield ( https://www.synthetos.com/wiki/index.php?title=Projects:grblShield ).

Simen Svale Skogsrud, l'auteur du logiciel, a fait un travail remarquable d'optimisation. Il est toutefois à l'heure de l'écriture de cet article, en plein déménagement (info Twitter!), et ne peut travailler sur le projet depuis une paire de mois. Cette info serait anodine si il n'y avait pas quelques bugs bloquants dans la dernière version, seule à supporter les arcs de cercles.

Heureusement Riley Porter et Alden Hart (Synthetos) ont apporté les corrections requises au logiciel et les ont proposées à Simen pour intégration. Il y a donc fort à parier que les prochaines versions 'Officielles' de Grbl intègreront ces correctifs.

Dans les corrections faites ;

  • L'accélération : très buggée sur Grbl 0.6b, et très fonctionnelle sur la version de Synthetos
  • Une assignation des broches légèrement différente;
  • La gestion de la désactivation des moteurs lorsqu'il n'y a pas de commandes en cours d'exécution (enable);
  • Une gestion de polarité de la broche enable inversée (et cela ne vas pas nécessairement nous rendre service... voir plus loin);
  • Une gestion des broches 'step' inversée également (même remarque que précédemment);
  • Divers petits 'bug fxes'.

Pré requis :

Configuration :

Il va tout d'abord falloir récupérer la dernière version de l'environnement de développement Arduino sur le site officiel (http://arduino.cc/en/Main/Software) et l'installer. Je ne donne pas de mode opératoire détaillé, celui-ci étant déjà très largement documenté.

L'environnement étant installé, nous allons ensuite paramétrer l'ordinateur pour pouvoir utiliser le compilateur C pour AVR en ligne de commande. Cette manipulation est nécessaire, car le programme que nous allons envoyer à l'Arduino n'est pas un sketch Arduino, mais bien un programme en C AVR, optimisé pour le processeur. Mais afin de nous éviter d'installer une chaine de compilation complète, nous allons utiliser cette qui est installée dans l'environnement Arduino, et qui est utilisée lors de la compilation de Sketches de façon transparente par celui-ci.

Pour ce faire, il va nous falloir ajouter ce chemin à la variable d'environnement $PATH de notre OS.

Sur Mac, éditer le ficher .bash_profile dans la racine de votre compte et ajouter les lignes suivantes :

# pour utiliser l'environnement Arduino comme compilateur avr
export PATH=$PATH:/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin

puis lancer la main la commande pour éviter de relancer un shell

export PATH=$PATH:/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin

Sur Windows, faire :

  • Appuyer simultanément sur les touches "Windows" + "Pause"
  • aller dans l'onglet "Avancé",
  • cliquez sur le bouton "variables d'environnement"
  • Modifier la variable d'environnement PATH pour ajouter ";C:\Program Files\arduino-0022\hardware\tools\avr\bin;C:\Program Files\arduino-0022\hardware\tools\avr\utils\bin" à la fin.
  • Noubliez pas le ';' de séparation :

Sur Linux éditer le ficher .bash_profile dans la racine de votre compte et ajouter de quoi appeler le sous répertoire bin contenant les exe du compilateur AVR.

Récupération du firmware

Le firmware choisi est le fork réalisé par Synthetos de Grbl. La page d'accueil du projet est ici : https://www.synthetos.com/wiki/index.php?title=Projects:grblShield.

Les sources du projet sont à récupérer sur GITHub : https://github.com/synthetos/grblShield. Prendre l'archive TGZ disponible. Le fichier ressemblera à ceci : synthetos-grblShield-bc5e96e.tar.gz. Le décompresser.

Configuration du firmware

Le micrologiciel que nous allons envoyer sur l'Arduino est dans le sous répertoire synthetos-grblShield-bc5e96e/firmware . Nous allons procéder à quelques modifications / configurations.

  • Éditer le fichier config.h, passer le baudrate à 38400 bauds :

Avant:

#define BAUD_RATE 9600

Après:

#define BAUD_RATE 38400
  • Éditer le fichier settings.c pour réactiver l'invert mask par défaut. Pour ce faire, commenter la ligne
//#define DEFAULT_STEPPING_INVERT_MASK 0x1C     //@grblshield/

et décommenter la ligne

#define DEFAULT_STEPPING_INVERT_MASK 0
  • Éditer le fichier protocol.c afin de mettre en place un hack (affichage de la ligne start) afin de rendre grbl compatible avec replicatorG, Cela nous sera utile lors des tests. (en gras, l'ajout)
 void protocol_init()
 {
   beginSerial(BAUD_RATE);
   printPgmString(PSTR("\r\nGrbl " GRBL_VERSION));
   printPgmString(PSTR("\r\nstart"));
   printPgmString(PSTR("\r\n"));
 }
 

Et enfin, pour faire en sorte que le signal enable soit actif à 1, dans stepper.c, remplacer :

 static void set_step_events_per_minute(uint32_t steps_per_minute);
 void st_wake_up() {
   STEPPERS_ENABLE_PORT &= ~(1<<STEPPERS_ENABLE_BIT);
   ENABLE_STEPPER_DRIVER_INTERRUPT();
 }
 void st_disable_steppers() {    //@grblshield/
   STEPPERS_ENABLE_PORT |= (1<<STEPPERS_ENABLE_BIT);
   DISABLE_STEPPER_DRIVER_INTERRUPT();
 }
 

Par :

 static void set_step_events_per_minute(uint32_t steps_per_minute);
 void st_wake_up() {
   STEPPERS_ENABLE_PORT |= (1<<STEPPERS_ENABLE_BIT);
   ENABLE_STEPPER_DRIVER_INTERRUPT();
 }
 void st_disable_steppers() {    //@grblshield/
   STEPPERS_ENABLE_PORT &= ~(1<<STEPPERS_ENABLE_BIT);
   DISABLE_STEPPER_DRIVER_INTERRUPT();
 }
  • Enfin, il va nous falloir paramétrer notre Makefile afin qu'il sache sur quel port série sera vue l'Arduino. Pour ce faire, il va nous falloir :

Remplacer la ligne :

PROGRAMMER = -c avrisp2 -P usb

par (sous windows)

PROGRAMMER = -C "C:\Program Files\arduino-0022\hardware\tools\avr\etc\avrdude.conf" -c stk500v1 -P COM5 -b57600

ou (sous OSX)

PROGRAMMER = -c stk500v1 -P /dev/tty.usbserial-A7006R7r -b57600

Bien sur le nom du port série (derrière option -P) est à remplacer en fonction de votre config...

Build et programmation du firmware

Nettoyer les résultats d'une éventuelle précédente compilation :

make clean

Compiler et programmer à la volée :

make flash

Ceci nous donne le résultat suivant (ici, sous windows), ou l'on voit la copmpilation puis la programmation de l'Arduino, ert enfin la vérification:

compilation.jpg

Connexions et Tests

Premiers tests et paramétrage de l'Arduino :

Pour ces premiers tests, il va nous falloir raccorder l'Arduino au micro ordinateur. Le plus simple est ensuite de lancer l'environnement de développement Arduino, et sélectionner le port série sur lequel est raccordé la carte dans le menu "Tools/Serial port".

Nous allons ensuite cliquer sur l'icone "serial monitor" (à droite) et changer la vitesse de connexion pour mettre 38400 bauds (en bas à droite du serial monitor), valeur que nous avons changé avant la recompilation.

L'écran nous affiche :

Grbl 0.6b
start
'$' to dump current settings

La carte est prête à recevoir des commandes. Nous allons maintenant examiner les paramètres de la carte. Pour ce faire, il suffit de lancer la commande "$" et de faire entrée. Un liste des variables avec les paramètres courants est affichée:

$0 = 640.0 (steps/mm x)
$1 = 640.0 (steps/mm y)
$2 = 640.0 (steps/mm z)
$3 = 3 (microseconds step pulse)
$4 = 480.0 (mm/min default feed rate)
$5 = 480.0 (mm/min default seek rate)
$6 = 0.100 (mm/arc segment)
$7 = 0 (step port invert mask. binary = 0)
$8 = 100.0 (acceleration in mm/sec^2)
$9 = 300.0 (max instant cornering speed change in delta mm/min)
'$x=value' to set parameter or just '$' to dump current settings
ok

Grbl fonctionne avec un certain nombre de variables internes, qui sont sauvegardées en e2prom, de façon à résister à l'extinction. Pour changer la valeur d'une variable, c'est simple. Il suffit de taper "nom de la variable"=valeur. Le séparateur décimal est un '.' ainsi, pour indiquer que la résolution de l'axe X est de 220,5 pas par millimètre, il suffit de taper :

$0=220.5

Ici, j'ai programmé la carte pour gérer une vis sans fin de 5mm / tour, des moteurs à 200 pas par tour, et un contrôleur fonctionnant en micropas (1/16e de pas). Dans ce cas, il faudra 200 x 16 = 3200 pas pour faire 5mm. La valeur à indiquer en résolution des axes est donc de 3200 / 5mm = 640 pas / mm (paramètres $0 $1 $2).

La largeur d’impulsion de pas est réglable également. Ici, j'ai indiqué 3 microsecondes par impulsion ($3)

$4 et $5 sont réservés pour régler les vitesses par défaut en usinage ($4) et en déplacement rapide ($5);

$6 sert à régler la résolution des arcs. Ceux ci sont en effet rendus comme de petits segments de droite. La taille de ces segments est indiquée ici`;

$7 permet de mettre un masque d'inversion des signaux de pas et de direction pour chaque axe. Pour chacun d'entre eux devant être inversé, prendre la valeur ci dessous, en faire la somme et l'assigner à $7:

  • Pas X : 1
  • Pas Y : 2
  • Pas Z : 4
  • Direction X : 8
  • Direction Y : 16
  • Direction Z : 32

Ainsi pour inverser la direction de X et Y, il suffirait de mettre 24 (16+8) dans $7.

$8 permet de régler l'accélération MAX.

Et enfin, $9 permet de régler la valeur au dessus de laquelle, lors du passage d'une vitesse à une autre, on passera par le gestionnaire d'accélération au lieu de faire un changement de vitesse instantané.

Après avoir paramétré la carte avec vos valeurs, nous voila prêts pour la suite.

Câblage de la carte aux contrôleurs pas à pas

Tel que le code a été modifié puis compilé, tous les signaux sont en logique positive, c'est à dire que les impulsions de pas sont données à l'état 1 (5V), idem pour le signal enable, qui valide avec un 5V les déplacements du moteur. Il va donc falloir maintenant raccorder notre carte arduino à un contrôleur pas à pas qui va gérer la puissance . Voici la fonction des différentes broches de l'Arduino (réglages par défaut de la version 0.6b modifiée par Synthetos) :

Fonction Broche Arduino Commentaire
Step X Digital 2 Impulsion de pas axe X
Dir X Digital 5 Direction axe X
Step Y Digital 3 " " Y
Dir Y Digital 6 " " Y
Step Z Digital 4 " " Z
Dir Z Digital 7 " " Z
Stepper enable Digital 8 Activation des tous les axes
Limite X Digital 9 Contact de limite d'axe X
Limite Y Digital 10 Contact de limite d'axe Y
Limite Z Digital 11 Contact de limite d'axe Z
Broche active Digital 12 Démarre la broche
Direction Broche Digital 13 Change le sens de rotation de la broche

Tests avec le serial monitor

Après avoir raccordé nos contrôleurs à l'Arduino (ne pas oublier de raccorder aussi une masse!), les moteurs aux contrôleurs, et alimenté le tout, on va pouvoir passer aux essais. Le plus simple est de la faire toujours avec l'environnement Arduino et le serial monitor. Taper les commandes suivantes pour vérifier le bon fonctionnement :

G90
G00 X100 F50

Le moteur de l'axe X va faire un déplacement de 100mm à 50 mm / minutes... Pour tester l'axe Y :

G00 Y100.0 F400

Cette fois c'est le moteur de l'axe Y qui va se déplacer de 100mm, mais à 400 mm par minute. En ainsi de suite pour l'axe Z. Il est ainsi possible de tester la vitesse max, la vitesse d'accélératon, etc..

A noter que l'Arduino répond "ok" a chaque fois qu'une commande a été comprise et exécuté. La faible quantité de mémoire ram disponible sur le processeur de l'Arduino ne permet que de mettre une ligne de Gcode en tampon.

Il est donc nécessaire de 'streamer' le gcode à l'aide d'un programme, qui devra attendre le retour de l'Arduino ('ok') avant de renvoyer une autre commande. Pas pratique... Un script Ryby est livré avec la version originale de Grbl, qui a cet usage.

Tests avec ReplicatorG

Une autre méthode de test est d'utiliser ReplicatorG, le logiciel conçu pour piloter les imprimantes 3D Makerbot. Écrit en Java, et basé sur le code de l'environnement de l'Arduino, ce programme a le bon gout de fonctionner aussi bien sur Windows, Linux et OSX.

La première choses à faire est de le télécharger et l'installer à partir de http://code.google.com/p/replicatorg/downloads/list.

Après l'avoir installé, il va nous falloir créer une configuration spécifique pour l'Arduino. Il existe plusieurs 'drivers' dans ReplicatorG. L'un d'entre eux nous intéresse particulièrement puisqu'il est conçu pour passer le Gcode au port série ligne par ligne, en attendant de recevoir le message "ok" avant d'envoyer la ligne suivante.

C'est ce driver que nous allons exploiter. Mais pour cela il va nous falloir créer une config de machine. Sur ReplicatorG, elles sont stockées dans le sous répertoire machines, sous forme de fichier XML.

A cet effet, j'ai créé une config : arduino-grbl.xml. Il suffit de copier ce ficher dans le sous répertoire "Machines et lancer ReplicatorG.

Lors du 1er lancement, ReplicatorG indique qu'aucune machine n'est connectée :

not-connected.png

Nous allons ensuite sélectionner le pilote que nous venons tout juste d'installer. Pour ce faire, aller dans le menu "Machine", puis "Driver", et sélectionner "Grbl 38400 bauds" :

choix-driver.png

Enfin, la dernière étape consiste à sélectionner le port série sur lequel votre arduino est connectée dans le menu "Machine" puis "Serial Port".

connect.pngCliquer ensuite sur le bouton "connect" (avant dernier à droite) afin d'initialiser la connexion avec la machine.

La machine est alors connectée et le bandeau supérieur passe en vert : grbl.jpg

L'icone de control panel (les 4 fleches) vous permet ensuite d'accéder à un panneau de contrôle autorisant la commande manuelle de la machine. panel.jpg

Il y a plus d'explications en images dans la vidéo ci dessus...

Envoi de programme Gcode en production : solution performante et rapide en python

Comme on l'a vu, si c'est simple de tester du gcode soit en tapant des commandes à la main dans un terminal série, soit en l'envoyant avec ReplicatorG, il va néanmoins nous falloir trouver une solution plus pratique pour la mise en production. Cette solution doit être simple, multiplateforme, et ne nécessiter que peu de connaissance en informatique.

J'ai clairement abandonné le script écrit en Ruby livré avec Grbl. En effet, si Ruby fonctionne nativement sur Mac et Linux, il est très lent sous windows et il n'y a aucune façon simple d'installer la librairie 'serial' nécessaire pour la communication avec l'Arduino. Je suis arrivé au bout, mais quelle galère et quel manque de perf....

Sur le site Contraptor, j'ai trouvé une un script nommé 'stream.py' sur cette page.

Python est natif sur mac et Linux, et assez facile à installer sous Windows. De plus, la librairie serial s'installe très facilement sous Windows puisqu'il s'agit d'un install.exe. Python est donc un bon choix.

Sous Windows, il faut l'installer à partir de http://www.python.org/download/. Il va également nous falloir installer la librairie serial ( http://sourceforge.net/projects/pyserial/ ) qui va assurer la communication avec l'Arduino.

Après l'installation sous Windows, les fichiers .py sont automatiquement associés à Python.

J'ai modifié le script stream.py décrit ci dessus afin :

  • De supporter le passage d'un paramètre : le nom du fichier à streamer
  • De sortir un message d'information quand le fichier n'est pas passé en paramètres
  • De revoir les temps de timeout lors de la connexion à l'Arduino, et la boucle qui vide le buffer de réception du port série.
  • De demander l'appui sur une touche à la fin du streaming du fichier afin de pouvoir lire le résultat de l'exécution du programme Gcode
  • D'ajouter des commentaires et exemples de paramétrage de la variable 'port_id' pour mieux comprendre comment utiliser ce script sur PC/Mac/Linux
  • De traiter le cas d'un gcode non supporté ("error: Unsupported statement"), qui n'était pas traité dans la version initiale. Quand on rencontre une erreur, désormais on continue l'exécution.

Ma version du stream.py peut être téléchargée ici : stream.py. Voici également un petit fichier gcode pour faire des tests : test.gcode

Avant utilisation, le fichier stream.py doit être paramétré pour refléter le port série sur lequel est branché l'arduino, et le type de plateforme. Tout est dans les commentaires.

Ensuite, il est très facile à utiliser. Sous linux ou mac, il suffit de lancer la commande suivante pour lancer le streaming :

stream.py nom_du_fichier_a_streamer.gcode

Su PC c'est désormais encore plus simple puisqu'il suffit de placer le script python sur le bureau, et de drag'n dropper le fichier gcode dessus... (voir vidéo ci dessus). Le script prendra automatiquement en paramètre le fichier Gcode qu'on lui soumet par ce biais. L'attente d'appui d'une touche à la fin permettra de lire le résultat d’exécution avant la fermeture de la fenêtre.

Il y a une démo de fonctionnement sous Linux et Windows dans la vidéo en début d'article.

Envoi de programme Gcode en production : solution utilisant processing

Jonathan Ward, du MIT, propose une application en Processing pour faire le boulot (http://mtm.cba.mit.edu/machines/mtm_snap-lock/build/software.html ). Cela nécessite d'installer tout d'abord Processing, opération simple à partir des archives disponibles sur l'espace de télépchargement du site éponyme : http://processing.org/download/

L'interface est décevante, en mode texte, aussi ais-je rapidement laissé tombé. gctrl.png

Un lecteur du blog, m'a toutefois signalé une article sur une conversion de MF70 réalisée avec GRBL: http://www.thebox.myzen.co.uk/Hardware/CNC_Conversion.html. L'auteur a notamment eu la bonne idée de développer un panneau de contrôle également écrit en processing.

Les sources sont disponibles ici: http://www.thebox.myzen.co.uk/Hardware/CNC_Conversion_files/Processing_CNC.zip

Celui-ci est assez complet et ergonomiquement plaisant à utiliser. Il dispose de contrôles manuels et d'une fonction de streaming de Gcode.

En voici une copie d'écran :

cnc_controller.png

Sa compilation sous processing ne pose qu'un seul probleme : il faut préalablement avoir téléchargé la librairie ControlIP5 à partir de http://www.sojamo.de/controlP5, et l'avoir décompressé dans un sous dossier 'libraries' du dossier de projets Processing. C'est cette librairie qui va gérer l'affichage graphique du control panel.

Je ne l'ai pas encore testé en conditions réelles, je le ferai dès que je serai à proximité de ma maquette...

D'ici là, bonne bidouille...