Featured image of post OctoPrint : Le contrôleur d'imprimante 3D

OctoPrint : Le contrôleur d'imprimante 3D

Après avoir fait 3 aller-retour de mon bureau (chambre) vers mon imprimante 3D (salon), j’installe OctoPrint pour la contrôler à distance.

Introduction

Maintenant que j’ai trouvé une place définitive pour mon imprimante 3D, il faut absolument que cette dernière soit pilotable à distance (comme les imprimantes 2D actuelles !).

Pour faire cela, je vais y connecter un Raspberry Pi, une prise connectée et une webcam.
On ne s’en rend pas compte, mais cette simple évolution comporte pas mal de petit problème à régler et c’est ce que l’on va voir ici.

Solutions

Pilotage

Comme vous l’avez vu dans le titre, je vais utiliser OctoPrint pour contrôler l’imprimante. Pour ce faire, j’utilise un RPi ou j’y installe la distribution dédiée OctoPi. La communication se fera par l’intermédiaire du port micro USB de l’imprimante.

Information

À propos d’OctoPrint

OctoPrint est un logiciel Open Source développé par Gina Häußge dans son temps libre. Depuis, cela est devenu son activité à temps plein.

Pour relier le RPi au réseau, j’utilise simplement un câble Ethernet. Les RPi que je possède n’ont pas de puce Wi-Fi intégrée…

Visualisation

On peut connecter une webcam sur le RPi, mais je ne sais pas si c’est la conjoncture actuelle ou moi qui suis une pince, mais je trouve que cela coute trop chère.
On peut aller voir du côté des caméras officielles du RPi mais ce n’est pas mieux.

Heureusement, j’ai trouvé un clone du RPi Cam pour 3 fois moins cher : Module caméra Anpro.
Il y a une nappe (interface CSI) de 1 m en plus de celle de 150 mm dans le package.

Information

Spoil

Elle fonctionne sur le RPi sans configuration !

Contrôle d’alimentation

Ma CR6-SE utilise un interrupteur mécanique pour démarrer. Le plus simple et de le mettre en position ON et d’utiliser une prise connectée pour le contrôle. Pour cela j’utilise le Shelly Plug S.
Cette prise ne nécessite pas d’être reflasher pour avoir une solution non cloud (comme tous les Shelly) et elle propose un suivi de consommation.

Le Raspberry ne va pas s’alimenter tous seul ! Pour faire une installation propre, je vais reprendre l’alimentation de l’imprimante (qui sort du 24 Volts) avec un abaisseur de tension DSN5000 qui sera relié au RPi par son port micro USB via un câble.

Pour allumé le tous, aucun problème, on lance la prise connectée et c’est bon. Par contre, pour éteindre, il faut éteindre proprement le RPi et ensuite éteindre la prise. Il faut donc que je voie si l’on peut faire cela de manière autonome.

Applications

OctoPi

Commencement

Les étapes que je ne détaille pas :

  • Télécharger OctoPi
  • Flasher la carte SD avec Etcher
  • Attribuer une IP fixe (ou réserver un bail statique)
  • Changer le mot de passe du compte pi

Une fois cela effectué, on peut accéder à l’interface via son adresse IP ou via mDNS : octopi.local.

Remarque

Setup Wizard

Accueil OctoPrint Contrôle d’accès Profil de l’imprimante : Général Profil de l’imprimante : Plateau Profil de l’imprimante : Axes Profil de l’imprimante : Tête

Bien sûr, j’ai une MAJ… : MAJ OctoPrint

Problème

En branchant le câble USB à l’imprimante, je me rends compte que le RPi alimente le circuit de l’imprimante ! 😕 On peut le voir dans la photo ci-dessous où l’on voit une LED témoin allumé alors que l’interrupteur de l’imprimante est sur OFF. Imprimante éteinte

Mes recherches sur internet mon donné une solution : Ruban électrique sur le pin V+

Je prends cela comme solution temporaire. Je vais peut-être me fabriquer un câble “data only” avec une paire de connecteurs USB typ A (mâle et femelle) pour interconnecté mon câble de connexion.

Remarque

Edit

C’est fait ! Sucre USB : data only

Test

Après avoir bien connecté mon câble USB modifié, la connexion via le bouton Auto fonctionne : Connexion automatique

Pour lancer une impression, rien de plus simple. Il suffit de cliquer sur le bouton Upload et de sélectionner votre fichier GCODE. Ce dernier apparait alors dans le menu Files.
Pour lancer l’impression, il suffit de cliquez sur le bouton adéquat : Lancement de l’impression

Information

Préchauffage

Le préchauffage se fait automatiquement. Cependant, il est différent du comportement classique de mon imprimante. En effet, OctoPrint fait d’abord chauffé le bed et ensuite la buse alors qu’en temps normal les deux se mettent en température même temps.

Intéressant, l’onglet GCode Viewer permet d’afficher virtuellement le travail d’impression : Onglet GCode Viewer

RPi Cam

Configuration

Bon, j’ai branché la caméra, allumer le RPi et j’ai directement le retour caméra qui fonctionne sans rien faire… Retour camera

Ayant mis ma caméra n’importe comment, j’ai temporairement inversé les axes afin d’avoir l’image dans le bon sens. Pour cela, il faut aller dans les paramètres (la petite clé 🔧 dans le bandeau) et dans le menu Webcam & Timelapse. Paramètre de la caméra

Maintenant c’est mieux (le “Creality” est dans le bon sens de lecture): Retour caméra à l’endroit

Intégration

Afin de la fixer proprement, j’ai imprimé un support trouvé sur Thingiverse.

J’ai pris le “Bracket.stl” du modèle 2886101 et le support caméra du 3407867 (car plus simple)

Support caméra

Alimentation du RPi

Préparation

Avant tous, j’ai préréglé le potentiomètre du module au multimètre avec une alimentation de labo afin de vérifier son fonctionnement.
Je devrais refaire la calibration après le branchement à l’alimentation pour être sûr.

Je soude donc mon bout de câble micro USB sur les bornes OUT.
Je sertis deux fils avec des cosses à œillets que j’isole avec une gaine thermorétractable. Je ne soude pas cela directement à la carte, vous comprendrez pourquoi dans la partie suivante.

Montage

Pour avoir accès au bloc d’alimentation, il faut retirer la plaque de protection.
Il y a 6 vis à démonter dont voici leurs emplacements : Emplacements des vis

Je vais donc visser mes câbles œillets sur les emplacements disponibles de V+ et V-. Bornier de connexion Je fais sortir les câbles par la même sortie que le câble qui va sur le plateau chauffant.

Le câble qui va aller au IN- va donc sur le V- et celui du IN+ sur le V+. Mise en place du câble

Comme vous pouvez le voir, j’ai fait un nœud afin de limiter la tension au bornier en cas d’arrachement.
J’ai ensuite soudé les câbles au DSN5000.

Installation de test

De ce fait, le RPi est maintenant alimenté via l’imprimante.

Sécurisation

Pour sécuriser ce module, une fois de plus, j’ai trouvé le modèle 3421285 qui possède un système pour maintenir les câbles (pour résister à l’arrachement).

Il faudrait aussi que je mette une solution pour désolidariser le module au cas où j’ai besoin de déplacer la CR6-SE. Je penche pour un connecteur Jack DC, des Anderson Powerpole (PP) ou encore des connecteurs de batterie de drone (XT ou T-Plug).

Remarque

Edit

C’est bon, le boitier est imprimé et peint avec des restes d’une peinture pour meuble. Pour le câble, je l’ai fait avec des connecteurs PP. Je préfère ceux la car on à pas besoin de les souder, on les sertis. Connexion PP

Alimentation du système

Préparation

En préparation de ma prise connectée, j’ai effectué les actions suivantes :

  • Association à mon réseau
  • Attribution d’une IP fixe
  • MAJ firmware

Ma prise est donc fonctionnelle, en l’allumant (après avoir mis mon imprimante dessus), le système démarre sans soucis.
Le problème est plutôt pour l’arrêt. Si j’éteins brusquement le RPi, je vais réduire considérablement la durée de vie de la carte SD (ne me demandez pas comment je le sais). Je ne me sens pas non plus d’éteindre l’OctoPi, attendre 2 min et d’éteindre la prise connectée…

cURLing

Heureusement pour moi l’API de la prise me permet de faire un tour de passe-passe sans recourir à un système domotique.

Dans cet API, j’ai trouvé l’attribut timer mais cette dernière n’est pas trop documentée ici.
J’ai alors trouvé un PDF où il est écrit la chose suivante :

turn=on - switch output ON
turn=off - switch output OFF
turn=toggle - reverese state
On and off can be combined with timer:
timer=X - where X is in seconds. Switch output will be turned On or OFF for X seconds and will be switched back to previews state after that.

Mes tests m’ont permis de déduire le comportement favorable suivant :

graph LR;
    A[Prise ON] --> B{"turn=on & timer=90"}
    B --> C[Prise ON]
    C -->|90 sec| D[Prise OFF]

Donc si je demande à la prise actuellement allumée de s’allumer pendant 90 secondes, elle va fonctionné pendant encore 90 secondes avant de revenir à son état précédant : prise éteinte.
C’est parfait pour moi !

La commande suivante fonctionne bien sur mon PC (lancé avec WSL) :

curl http://192.168.92.17/relay/0?turn=on&timer=90

192.168.92.17 étant l’adresse IP du Shelly Plug S.

Mon idée est donc de faire en sorte que lorsque je demande au RPi de s’éteindre, elle lance cette commande avant de faire son shutdown (en partant du principe que le RPi prend moins de 90 à s’éteindre complètement).

Pour cela, on va donc éditer la commande d’extinction d’OctoPi en allant dans le menu Server des paramètres (🔧).

On ajoute donc notre curl à la commande dont la voici au complet :

curl http://192.168.92.17/relay/0?turn=on\&timer=90 && sudo shutdown -h now

Les plus attentifs remarqueront que j’ai échappé le & par un anti-slash. C’est après avoir débuggé cela pendant un certain moment que j’ai compris que cela était nécessaire.

Édition de la commande d’extinction

Après avoir sauvegardé, il suffit de tester !
J’ai eu la bonne surprise de voir que le décompte était visible sur l’interface Web de la prise : Décompte d’extinction

Bref, ça fonctionne ! 😎

Intégration Home Assistant

OctoPrint

Bien sûr, la prise est déjà intégrée à HA via l’intégration officielle, mais pas OctoPrint ! Pour y remédier, il existe une intégration pour cela.

Avant tous, il faut générer une clé d’API sur OctoPrint. C’est dans le menu Applications Keys. Génération d’un clé d’API

Voici donc ma configuration :

  • configuration.yaml
octoprint:
  - host: !secret octoprint_ipaddr
    api_key: !secret octoprint_api_key
    bed: true
    name: OctoPrint_CR6SE
    number_of_tools: 2
    sensors:
      monitored_conditions:
        - 'Current State'
        - 'Job Percentage'

binary_sensor:
  - platform: octoprint
    name: OctoPrint_CR6SE
    monitored_conditions:
      - Printing
      - Printing Error

camera:
  - platform: mjpeg
    name: OctoPiCam_CR6SE
    still_image_url: !secret octoprint_still_image_url
    mjpeg_url: !secret octoprint_mjpeg_url
  • secrets.yaml
# OctoPrint
octoprint_ipaddr: 192.168.92.22
octoprint_api_key: A1UN2DEUX3TROIS4QUATRE5CINQ6SIXK
octoprint_still_image_url: http://192.168.92.22/webcam/?action=snapshot
octoprint_mjpeg_url: http://192.168.92.22/webcam/?action=stream

Un check de la configuration est on relance HA.
Open your Home Assistant instance and show your server controls.

Commutateur

Si vous avez bien suivi, vous comprendrez que je n’ai pas (encore) de moyen d’éteindre proprement le système via HA.

Pour cela je vais créer un switch virtuel dans lequel la commande turn_on sera l’activation du relais de la prise et turn_off fera un appel de la commande shutdown via l’API d’OctoPrint.

Je définis alors la commande d’extinction par API :

  • configuration.yaml
rest_command:
  octoprint_shutdown:
    url: !secret octoprint_shutdown_command
    method: POST
    headers: 
      X-Api-Key: !secret octoprint_api_key
  • secrets.yaml
octoprint_shutdown_command: http://192.168.92.22/api/system/commands/core/shutdown

Ensuite, je définis mon interrupteur :

  • configuration.yaml
switch:
  # Template for 3D printer (CR6-SE)
  - platform: template
    switches:
      cr6se:
        turn_on:
          service: switch.turn_on
          target:
            entity_id: switch.shellyplugscr6se
        turn_off:
          service: rest_command.octoprint_shutdown

shellyplugscr6se étant le nom de ma prise dans HA.

Sur Lovelace, j’ajoute une pile verticale de trois cartes :

type: vertical-stack
cards:
  - type: picture-glance
    title: Camera CR6-SE
    entities: []
    camera_image: camera.octopicam_cr6se
  - type: entities
    entities:
      - entity: switch.cr6se
        name: Interrupteur système
      - entity: switch.shellyplugscr6se
        name: Prise Shelly
      - entity: sensor.shellyplugscr6se_power
        name: Puissance
      - entity: sensor.shellyplugscr6se_energy
        name: Consommation
    show_header_toggle: false
  - type: 'custom:bar-card'
    entities:
      - entity: sensor.octoprint_cr6se_job_percentage
        name: Impression

Qui me donne le résultat suivant : Vertical stack Quand OctoPrint est actif, le retour caméra apparait dans la première carte.

Timelapse

Après un peut de lecture, j’ai enfin compris la configuration du plugin Octolapse. Parce que j’utilise Cura, il faut modifier quelque chose dessus pour que cela fonctionne.

Donc, une fois le plugin installé et la configuration des paramètres de l’imprimante faite, sélectionner Automatic Configuration dans la liste Slicer Type de la section Current Slicer Settings. Octolapse : Édition du profile de l’imprimante Comme l’indique le lien du warning pour Cura, il faut éditer Cura en ajoutant du GCODE en amont de celui d’impression. Cela va permettre à Octolapse d’obtenir les paramètres du slicer automatiquement (sinon il faudrait ajuster Octolapse à chaque fois qu’on change des paramètres sur Cura).

Donc, sur Cura, on va dans le menu d’édition des profils des imprimantes : Cura : Accès aux profils des imprimantes On clic donc sur notre imprimante et on clique sur Machine Settings.
On récupère le GCODE pour notre version (4.9 > 4.2) :
Cura Script for Version 4.2 or Greater
On ajoute donc ce GCODE au début du GCODE en l’inscrivant tout en haut du bloc Start G-code :

Cura : Ajout du GCODE Du fait que nous avons édité le slicer, il faudra refaire les GCODEs que vous avez déjà préparés auparavant si vous voulez qu’ils fonctionnent avec Octolapse.

Pour la configuration du plugin, je n’ai rien fait d’exceptionnel, juste une photo toutes les 10 secondes. On peut faire des photos plus intéressantes en déplaçant l’extrudeur dans un coin, mais bon, je ne suis pas Youtuber…

Une fois toutes les photos prises et l’impression terminée, Octolapse commence à générer le fichier vidéo. Comme on est sur un RPi 3, cela prend du temps… 🥱
J’ai alors décidé de désactiver cela et de le faire sur mon PC à partir des photos prises.

Du coup, je télécharge le Zip contenant les photos et je transforme cela avec ffmpeg (comme c’est le cas pour le plugin).
Voici un exemple de commande qui génère le timelapse (en utilisant x265) :

ffmpeg -pattern_type glob -i "*.jpg" -c:v libx265 -crf 18 -vf "format=yuv420p" -tag:v hvc1 my_timelapse.mp4

Information

Bref, j’ai scripté

Si vous cherchez plus compliqué pour faire plus simple, j’en ai fait un script disponible sur mon GitHub.

Sur une impression d’un peu moins de 6 heures, j’obtiens 1881 photos (78 MO). Avec mon script, mon PC à pris 82 secondes pour générer le fichier (lancé sous WSL).

encoded 1881 frames in 81.68s (23.03 fps), 1513.74 kb/s, Avg QP:18.23

Voici le lien du timelapse en question : CCR6SE_eyeball4_2.mp4
Voici le lien de l’impression effectué : Print-In-Place Iris Box (remix)

Epilogue

Enfin mon imprimante 3D est connectée !
Je suis plutôt content du résultat avec la prise, au début, je pensais devoir gérer cela avec une automatisation sur HA.

Je n’ai pas fait beaucoup d’impressions avant de mettre cela en place (j’utilise encore la bobine de PLA fourni avec l’imprimante), mais je suppose que cela va changer maintenant que j’ai une solution commode à l’utilisation.

Généré avec Hugo
Thème Stack conçu par Jimmy