L’impression 3D, la « tête » d’impression et Openscad: l’OpenSource à la rescousse

Le tendeur en S dont j’avais évoqué l’idée dans le post précédent est maintenant réalisé. Il fonctionne à merveille 🙂

Les pièces du tendeur

 

Tendeur en place

 

J’ai eu ensuite quelques déboires avec les axes X et Y. J’ai finalement réglé mes problèmes en remplaçant tous les paliers par des roulements à billes. En effet, les paliers glissent très bien mais dès que les courroies sont sous tension, les déplacements sont plus durs et ça fini a un moment ou à un autre par coincer provoquant ainsi des mouvements saccadés…

J’ai donc usiné des nouveaux supports pour y insérer des roulements à billes de rollers à la place des paliers.

 

Roulements

Pour les chariots, j’ai remplacé le double palier par une douille à billes prisonnière à l’intérieur du chariot.

Douille à billes

Après ces quelques modifications, tout fonctionne parfaitement ! Pour les déplacements en Y, j’ai fait des premiers tests, j’arrive à une vitesse de 12 000 mm / min. Je ne pense pas pouvoir imprimer à cette vitesse, mais la machine supporte sans problème  une vitesse de déplacement élevée.

 

Reste à réaliser le support de la tête d’impression… Ce n’est pas une mince affaire, la pièce est relativement complexe, et j’ai du mal à la visualiser et surtout à en estimer les mesures exactes. J’arrive à mes limites 😉

Heureusement, l’ordinateur est là pour nous aider à simuler différents modèles de support. L’idéal pour moi étant de réaliser un modèle 3D qui me servira ensuite à projeter à plat les pièces pour pouvoir ensuite les fraiser.

 

Le premier « truc » qui vous vient à l’idée: SolidWorks ! Oui et bien c’est « très » cher et je ne l’ai pas. Sketchup alors ? Non, il ne tourne pas sous linux ( même avec Wine je n’y arrive pas ). Alors comme toujours on va regarder du côté des solutions opensource. J’en connais 4 que j’utilise régulièrement:

  • LibreCAD: Excellent outil mais qui se limite à la 2D, nous l’utiliserons pour compléter les projections 2D des pièces.
  • HeeksCAD: Pour ce qui est de la conception 3D, il le permet mais j’ai du mal avec son ergonomie…
  • FreeCAD: Très bien, dessin 3D paramétrique, pas trop dur à prendre en main. Mais il a un gros soucis pour le moment. Autant il permet de créer des pièces facilement autant il est très difficile de les assembler dans un modèle 3D complet. A surveiller dans les futures versions, il évolue assez vite.
  • OpenSCAD: Un outil atypique ! Il permet de dessiner des pièces complexes en 3D paramétrique, mais ici, point d’interface graphique, le dessin se fait à l’aide d’un langage de programmation.

 

Espace de travail

 

Mon choix s’est donc porté sur Openscad. Il présente aussi l’avantage de générer des fichiers STL qui seront utiles lors de l’utilisation de l’imprimante 3D. D’où l’intérêt de commencer à le maîtriser dès maintenant.

 

Openscad dispose d’un éditeur intégré mais celui-ci est peu évolué. Si vous voulez plus de convivialité, vous pouvez utiliser un éditeur externe. Pour celà, il faut « cacher » l’éditeur intégré et cocher l’option « Automatic reload and compile »

Option

 

Options

 

Si vous utilisez emacs comme moi, vous pouvez lui dire de traiter les fichier « scad » comme des fichiers C. Ça permet d’avoir une bonne indentation et une coloration syntaxique correcte.

Pour cela, il faut mettre les lignes suivantes dans le fichier « .emacs »

(add-to-list 'auto-mode-alist '("\\.scad$" . c-mode))

 

L’environnement est prêt, on peut commencer à travailler. Pour commencer par des choses simples, modélisons  une douille à bille.

// Linear Ball Bearing
include 

$fn=50;
$lbb_inner_diameter=8;
$lbb_outer_diameter=15;
$lbb_length=24;

module linear_bearing_15_24()
{
  color(Aluminum) difference()
    {
      cylinder($lbb_length,$lbb_outer_diameter/2,$lbb_outer_diameter/2,center=true);
      cylinder($lbb_length+1,$lbb_inner_diameter/2,$lbb_inner_diameter/2,center=true);
    }
}

//For test
linear_bearing_15_24();
Linear ball bearing

C’est très simple, juste la différence entre 2 cylindres ! Là ou c’est génial: on ajuste les variables et hop on change les côtes.

 

Pour continuer, un peu plus compliqué: la tête chauffante. On va la modéliser rapidement pour qu’elle nous serve ensuite de repère pour la construction du support.

 

// HotEnd jhead MK IV
$fn=50;

$hotend_resistor_diameter=5;
$hotend_filament_diameter=3;
$hotend_outer_diameter=16;
$hotend_peek_length=50;

// Peek element
module peek() {
color(black) difference()
  {
    difference()
      {
	// Peek cylinder
	cylinder($hotend_peek_length,$hotend_outer_diameter/2,$hotend_outer_diameter/2);
	// Hole for filament
	translate([0,0,5]) cylinder($hotend_peek_length,$hotend_filament_diameter/2,$hotend_filament_diameter/2);
      }

    // Mount groove
    translate([0,0,$hotend_peek_length-10])
	{
	  difference()
	    {
	      cylinder(5,9,9);
	      cylinder(5,6,6);
	    }
	}
  }

}

module copper_end()
{
  translate([-5,-6.5,3])
    {
      difference()
	{
	  cube(size = [16,13,8]);
	  translate([12,15,4])
	    {
	      rotate([90,0,0])
		{
		  cylinder(20,$hotend_resistor_diameter/2,$hotend_resistor_diameter/2);
		}
	    }
	}
    }
  difference()
	{
	  cylinder(3,1,4.5);
	  cylinder(3,0.35,3);
	}
  translate([0,0,3])
    {
      difference()
	{
	  cylinder(20,4,4);
	  translate([0,0,1]) cylinder(21,3,3);
	}
    }
}

module hotend()
{
  translate([0,0,13])
    {
      peek();
    }
  copper_end();
}

// For test
hotend();

 

Hotend

 

Pas mal non 😉

 

Et pour terminer le support. Grâce à openscad, on peut changer les côtes, déplacer les perçages… pour simuler tout ce qui nous passe par la tête !

Même si ça peut paraître compliqué au premier abord, c’est très agréable à utiliser. Je ne prétends pas maîtriser complètement l’outil, mais je me débrouille.

 

Autre point très intéressant, on peut utiliser des conditions et autres boucles. Ici j’utilise quelques variables qui si elles sont initialisées à 1 modifient le rendu pour me permettre d’obtenir rapidement les projections à plat.

 

// Hotend Mount

include ;
include ;

$top_length=50;
$top_width=50;
$side_height=50;
$hole_cable_diameter=15;

$fromA=0;
$fromB=0;
$fromtop=0;

module mount_top()
{
  difference()
    {
	cube(size = [$top_length,$top_width,15]);
	translate([15,15,-2]) cylinder(20,$hotend_outer_diameter/2,$hotend_outer_diameter/2);
    }
}

module mount_side_A()
{
  rotate([0,90,0])
    {
      difference()
	{
	  cube(size = [$side_height,$top_length+5,5]);
	  translate([25,40,0])
	    {
	      cylinder(15,$lbb_outer_diameter/2,$lbb_outer_diameter/2, center=true);  

	    }
	}
      if ($fromA==0)
	{
	  translate([25,40,5]) linear_bearing_15_24();
	}
    }
}

module mount_side_B()
{
  rotate([90,90,0])
    {
      difference()
	{
	  cube(size = [$side_height,$top_length,5]);
	  translate([40,35,0]) cylinder(15,$lbb_outer_diameter/2,$lbb_outer_diameter/2, center=true);
	  translate([30,15,1]) cylinder(10,$hole_cable_diameter/2,$hole_cable_diameter/2, center=true);        

	}
       if ($fromB==0)
	 {
      translate([40,35,0]) linear_bearing_15_24();
	 }
    }
}

module mount_complete()
{
  if ( $fromA==0 && $fromB==0 )
    {
      mount_top();
    }

  if ($fromtop==0 && $fromB==0)
    {
      translate([-5,-5,15]) mount_side_A();
    }
  if ($fromtop==0 && $fromA==0)
    {
      translate([0,0,15]) mount_side_B();
    }
  if ($fromtop==0 && $fromA==0 && $fromB==0)
    {
      color(black) translate([15,15,-48]) #hotend();
    }
}

module mount_full()
{

  if ($fromtop==0 && $fromA==0 && $fromB==0)
    {
      // rod A
      rotate([0,90,0]) translate([10,35,-50]) cylinder(300,4,4);
      // rod B
      rotate([90,90,0]) translate([25,35,-150]) cylinder(300,4,4);
    }
  //Holes for hotend groove
  difference()
    {
      mount_complete();
      translate([23,-10,7.5]) rotate([-90,0,0]) cylinder(40,2.5,2.5);
      translate([7,-10,7.5]) rotate([-90,0,0]) cylinder(40,2.5,2.5);
    }
}

if ( $fromtop==1 )
  {
    projection(cut=false) mount_full();
  }

if ( $fromA==1 )
  {
    projection(cut=false) rotate([0,90,0]) mount_full();
  }

if ( $fromB==1 )
  {
    projection(cut=false) rotate([90,0,0]) mount_full();

  }
if ( $fromtop==0 && $fromA==0 && $fromB==0 )
  {
    mount_full();
  }

 

Hotend mount

 

Si l’on utilise les variables indiquées en haut du fichier, on obtient les projections à plat des 3 faces qui m’intéressent.

Si: $fromA=1;

fromA

Si $fromB=1;

 

FromB

 

Si $fromTop=1;

 

FromTOP

 

Le tout peut être exporté en DXF pour être ensuite utilisé dans LibreCAD puis HeeksCNC pour le fraisage des pièces. Seul petit bémol, les cercles et arcs de cercles sont des successions de segment ce qui n’est pas optimal. On peut facilement les reprendre dans Librecad.

Les différents plans sont regroupés dans un Zip si vous voulez jouer avec openscad.

Si un expert openscad passe par là, il peut nous donner des astuces dans les commentaires, je suis preneur 😉

La suite sur la fraiseuse…

Tamponne moi un barbu

Un petit tutoriel vidéo mettant en scène pas mal de logiciels libres pour créer des tampons à l’aide d’une fraiseuse numérique.

 

Avant le tutoriel en vidéo, voici la liste des outils utilisés:

  • Inkscape: Logiciel de dessin vectoriel utilisé ici pour vectoriser un fichier PNG.
  • LibreCad: Logiciel de CAD qui sert juste pour éditer le fichier DXF sortant d’inkscape.
  • F-engrave: L’outil indispensable pour la gravure numérique.
  • EMC: Le logiciel de pilotage de la fraiseuse.

Ne pas oublier le logo de @lagrottedubarbu
Le tutoriel en vidéo:

 

Speed your life, Linux & SSD

Je viens de monter un SSD à la place de mon ancien disque classique sur mon macbook vieux de 3 ans. Voici un bref retour d’expérience.

Afin d’avoir quelques chiffres, avant d’installer le SSD, j’ai installé bonnie++ qui est un logiciel de benchmark de disque.

Pour le lancer, voici une commande permettant de prendre en compte facilement la quantité de RAM disponible sur votre PC  ( je ne sais plus trop d’où elle vient, merci à son auteur en tout cas 😉

sudo bonnie++ -n 0 -u 0 -r `free -m | grep 'Mem:' | awk '{print $2}'` -s $(echo "scale=0;`free -m | grep 'Mem:' | awk '{print $2}'`*2" | bc -l) -f -b -d /home

Cette commande nous donne un résultat brut assez peu lisible.

Using uid:0, gid:0.
Writing intelligently...done
Rewriting...done
Reading intelligently...done
start 'em...done...done...done...
Version 1.03e       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
EquinoxeFR    7366M           40652   5 18250   2           61482   4  70.7   0
EquinoxeFR,7366M,,,40652,5,18250,2,,,61482,4,70.7,0,,,,,,,,,,,,,

Heureusement, bonnie++ est fourni avec des scripts permettant de mettre en forme les données.

echo "EquinoxeFR,7366M,,,40652,5,18250,2,,,61482,4,70.7,0,,,,,,,,,,,,," |  bon_csv2html > bonnie_results.html

Ce qui nous donne un tableau HTML de ce type.

Maintenant que nous avons les chiffres de notre disque classique, nous pouvons installer le SSD. Afin de faciliter la migration des données, j’ai monté le SSD dans le portable et placé l’ancien DD dans un boitier USB. La copie des partitions existantes a été faite à l’aide de Clonezilla lancé depuis le LiveCD « parted magic« .

Voilà, les données sont copiés, nous redémarrons la machine en à peine 10 sec !!! ( de grub à l’invite de login GDM )

Visiblement le gain de performance est bien là et le silence est absolu, pas une pièce en mouvement, quel plaisir.

Afin d’améliorer encore l’utilisation du SSD, voici quelques optimisations:

Tout d’abord, changeons le « I/O Scheduler » qui est contre productif en mode « cfq » avec un disque SSD. Dans /boot/grub/menu.lst, il faut placer elevator=deadline dans les paramètres du kernel.

# (0) Arch Linux
title  Arch Linux
root   (hd0,0)
kernel /boot/vmlinuz-linux root=/dev/sda1 elevator=deadline ro quiet vga=773
initrd /boot/initramfs-linux.img

Ce qui après un redémarrage nous donne

[pierre@EquinoxeFR ~]$ cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
[pierre@EquinoxeFR ~]$

Ensuite, réglons quelques paramètres pour le montage de nos partitions:

[pierre@EquinoxeFR ~]$ cat /etc/fstab
#
# /etc/fstab: static file system information
#
#
devpts /dev/pts devpts defaults 0 0
shm /dev/shm tmpfs nodev,nosuid 0 0
/dev/sda1 / ext4 noatime,discard,data=writeback,errors=remount-ro 0 1
/dev/sda2 swap swap defaults 0 0
/dev/sda3 /home ext4 noatime,discard,data=writeback,errors=remount-ro 0 1
  • noatime: désactive la mise à jour de l’heure d’accès aux fichiers. Ca n’a que peu d’intérêt et ça use le SSD inutilement.
  • discard: active le TRIM pour préserver au maximum la durée de vie du SSD
  •  data=writeback: journalise uniquement les métadatas avec EXT4. Attention il faut faire un tune2fs -o journal_data_writeback /dev/sda1 depuis un CD bootable sur la partition root sous peine de ne pas pouvoir redémarrer…

 

Voilà, après ces quelques optimisations, nous avons un système très réactif ( le jour et la nuit 🙂 même si je suis un peu étonné que les chiffres ne soit pas plus parlants. J’ai un SSD SATA III alors que mon portable ne supporte que le SATA II mais qui peut le plus, peut le moins… Ceci dit, j’ai quand même l’impression d’avoir des résultats en dessous de ce que l’on peut trouver sur le net. Peut-être que ça vient du contrôleur du macbook… sur OSX, beaucoup ont des problèmes de « link speed » sur le bus SATA avec de nombreux SSD.

 

Update 5/02:

Les résultats avec le scheduleur sur noop

nouveaux résultats avec AHCI Mode = SATA

J’ai mis à jour ArchWiki pour l’activition du mode SATA sur un macbook 5.1

rp_filter et maux de tête

Je viens de passer un certain temps à régler un problème avec une machine fraîchement migrée de CENTOS 5.7 à CENTOS 6.2

J’ai une machine dans un réseau A qui tente de contacter mon serveur qui dispose d’une interface (1) dans le réseau A et une interface (2) dans le réseau B.

Plusieurs cas de figure:

  • La machine ping l’adresse de l’interface (1) du serveur. C’est sur le même réseau, tout va bien.
  • La machine ping l’adresse de l’interface (2) du serveur. Ce n’est pas le même réseau, le routeur joue son rôle, le paquet ICMP arrive bien sur l’interface (2) comme l’atteste tcmdump, mais il n’y a jamais de ECHO REPLY… WTF ?!?

 

Ce cas de figure marchait parfaitement avec CENTOS 5.x. C’était sans compter l’arrivée du noyau 2.6.31 qui a modifié le fonctionnement du « Reverse path filtering »

Extrait Release notes Redhat 6x:

A change in the 2.6.31 Linux kernel made the net.ipv4.conf.default.rp_filter = 1 more strict in the I/O that is accepted. Consequently, in Red Hat Enterprise Linux 6, if there are multiple interfaces on the same subnet and I/O is sent to the one that is not the default route, the I/O will be dropped. Note that this applies to iSCSI iface binding when multiple interfaces are on the same subnet. To work around this, set the net.ipv4.conf.default.rp_filter parameter in /etc/sysctl.conf to 0 or 2, and reboot the machine.

Quand la machine contacte le serveur sur l’interface (2), le serveur voit un paquet provenant du réseau A, il ne va pas comme avec CENTOS 5 (en vert) répondre par la même interface en routant le paquet mais va tenter de répondre avec l’interface (1) (en rouge sur le schéma) qui est sur le réseau A. Or, c’est la qu’intervient le rp_filter qui va détruire la paquet !

Pour se sortir de cette situation il suffit d’éditer /etc/sysctl.conf  et de changer net.ipv4.conf.default.rp_filter = 1 pour net.ipv4.conf.default.rp_filter = 2 ou éventuellement net.ipv4.conf.default.rp_filter = 0