Télécommande Wemos D1 + TPP223
Retour rapide sur la télécommande MQTT de ce précédent billet, avec ici une version pour le très célèbre Wemos D1 et son ESP8266 tout simple, mais avec des interrupteurs tactiles, à base de TPP 223 :
Le proto est on ne peut plus basique, avec au dos du couvercle les TPP223 :
Chose amusante, le boîtier du proto a été entièrement codé par Gemini au format OpenSCAD. En voici une déclinaison plus récente :
// ==========================================
// configuration de l'exportation (choisir le mode)
// ==========================================
// 1 = base du boîtier seule
// 2 = couvercle seul
// 3 = les deux pièces côte à côte (vue d'ensemble)
mode_affichage = 3;
// paramétrage global
$fn = 32;
epaisseur_mur = 2.0;
jeu = 0.4; // espace pour l'ajustement des pièces
// --- configuration du texte à graver ---
texte_position_1 = "1"; // texte pour le premier emplacement (i = 1)
texte_position_2 = "2"; // texte pour l'emplacement central (i = 0)
texte_position_3 = "3"; // texte pour le troisième emplacement (i = -1)
// --- paramètres de la visserie m2 & inserts ---
insert_diametre = 3.2; // diamètre du trou pour insérer l'insert m2 à chaud
insert_profondeur = 4.5; // profondeur du trou d'insert (pour insert de 4mm)
vis_pas_diametre = 2.4; // trou de passage de la vis m2 dans le couvercle
vis_tote_diametre = 4.2; // diamètre de la tête de vis m2 (pour fraisage)
vis_tote_hauteur = 1.2; // profondeur du fraisage de la tête de vis
pilier_diametre = 7.0; // diamètre du pilier rond dans les angles
// dimensions d1 mini
d1_l = 34.5 + jeu;
d1_w = 26.0 + jeu;
d1_h = 5.0;
// --- paramètres ajustables du berceau de calage wemos ---
berceau_epaisseur = 1.6; // largeur du mur du contour
berceau_hauteur = 6.5; // hauteur totale du contour (depuis le fond)
barre_rehausse_hauteur = 2.5; // hauteur des barres pour surélever le pcb
barre_rehausse_epaisseur = 3.0; // largeur des barres de support transversales
// dimensions ttp223 modifiées (15 x 12 mm)
ttp_l = 15.0 + jeu;
ttp_w = 12.0 + jeu;
ttp_h = 2.5;
// dimensions internes de la boîte (légèrement augmentées pour intégrer les piliers sans gêner)
box_l = d1_l + 12;
box_w = max(d1_w, (ttp_w * 3) + 20);
box_h = 20;
// dimensions externes calculées
ext_l = box_l + 2 * epaisseur_mur;
ext_w = box_w + 2 * epaisseur_mur;
module base_boitier() {
difference() {
// 1. structure pleine : la boîte creuse + les piliers ronds ré-ajoutés dedans
union() {
// corps de la boîte creuse de base
difference() {
cube([ext_l, ext_w, box_h]);
translate([epaisseur_mur, epaisseur_mur, epaisseur_mur])
cube([box_l, box_w, box_h + 1]);
}
// ajout physique des 4 piliers cylindriques dans les coins vides
// pilier 1 : bas-gauche
translate([epaisseur_mur + pilier_diametre/2, epaisseur_mur + pilier_diametre/2, epaisseur_mur])
cylinder(d = pilier_diametre, h = box_h - epaisseur_mur);
// pilier 2 : haut-gauche
translate([epaisseur_mur + pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, epaisseur_mur])
cylinder(d = pilier_diametre, h = box_h - epaisseur_mur);
// pilier 3 : bas-droit
translate([ext_l - epaisseur_mur - pilier_diametre/2, epaisseur_mur + pilier_diametre/2, epaisseur_mur])
cylinder(d = pilier_diametre, h = box_h - epaisseur_mur);
// pilier 4 : haut-droit
translate([ext_l - epaisseur_mur - pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, epaisseur_mur])
cylinder(d = pilier_diametre, h = box_h - epaisseur_mur);
}
// 2. soustractions globales : ouverture usb et trous d'inserts
// ouverture pour le port micro-usb du wemos d1
translate([-1, ext_w/2 - 7, epaisseur_mur + barre_rehausse_hauteur])
cube([epaisseur_mur + 2, 14, 6.5]);
// perçages cylindriques pour insérer les inserts à chaud au centre des piliers ronds
// angle bas-gauche
translate([epaisseur_mur + pilier_diametre/2, epaisseur_mur + pilier_diametre/2, box_h - insert_profondeur])
cylinder(d = insert_diametre, h = insert_profondeur + 1);
// angle haut-gauche
translate([epaisseur_mur + pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, box_h - insert_profondeur])
cylinder(d = insert_diametre, h = insert_profondeur + 1);
// angle bas-droit
translate([ext_l - epaisseur_mur - pilier_diametre/2, epaisseur_mur + pilier_diametre/2, box_h - insert_profondeur])
cylinder(d = insert_diametre, h = insert_profondeur + 1);
// angle haut-droit
translate([ext_l - epaisseur_mur - pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, box_h - insert_profondeur])
cylinder(d = insert_diametre, h = insert_profondeur + 1);
}
// --- entourage de maintien et calage du wemos d1 mini ---
offset_x = epaisseur_mur + (box_l - d1_l)/2;
offset_y = epaisseur_mur + (box_w - d1_w)/2;
// 1. parois latérales de calage (gauche et droite)
translate([offset_x, offset_y - berceau_epaisseur, epaisseur_mur])
cube([d1_l, berceau_epaisseur, berceau_hauteur]);
translate([offset_x, offset_y + d1_w, epaisseur_mur])
cube([d1_l, berceau_epaisseur, berceau_hauteur]);
// 2. butée arrière (ferme l'entourage pour bloquer la carte)
translate([offset_x + d1_l, offset_y - berceau_epaisseur, epaisseur_mur])
cube([berceau_epaisseur, d1_w + 2 * berceau_epaisseur, berceau_hauteur]);
// 3. barres transversales de surélévation (relient le côté gauche et droit)
// barre avant (placée juste derrière l'entrée usb)
translate([offset_x + 2, offset_y, epaisseur_mur])
cube([barre_rehausse_epaisseur, d1_w, barre_rehausse_hauteur]);
// barre du milieu
translate([offset_x + (d1_l / 2) - (barre_rehausse_epaisseur / 2), offset_y, epaisseur_mur])
cube([barre_rehausse_epaisseur, d1_w, barre_rehausse_hauteur]);
}
module couvercle_tactile() {
// la face externe lisse repose sur le plateau (z=0), les éléments montent vers le haut
difference() {
union() {
// 1. plaque principale du couvercle
cube([ext_l, ext_w, epaisseur_mur]);
// 2. lèvre d'emboîtement (ajustée avec le jeu interne)
difference() {
translate([epaisseur_mur + jeu/2, epaisseur_mur + jeu/2, epaisseur_mur])
cube([box_l - jeu, box_w - jeu, epaisseur_mur]);
translate([epaisseur_mur * 2 + jeu/2, epaisseur_mur * 2 + jeu/2, epaisseur_mur - 0.5])
cube([box_l - jeu - epaisseur_mur * 2, box_w - jeu - epaisseur_mur * 2, epaisseur_mur + 1]);
// découpes cylindriques aux 4 coins de la lèvre pour laisser passer proprement les piliers ronds de la base
translate([epaisseur_mur + pilier_diametre/2, epaisseur_mur + pilier_diametre/2, epaisseur_mur - 0.1])
cylinder(d = pilier_diametre + jeu, h = epaisseur_mur + 0.5);
translate([epaisseur_mur + pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, epaisseur_mur - 0.1])
cylinder(d = pilier_diametre + jeu, h = epaisseur_mur + 0.5);
translate([ext_l - epaisseur_mur - pilier_diametre/2, epaisseur_mur + pilier_diametre/2, epaisseur_mur - 0.1])
cylinder(d = pilier_diametre + jeu, h = epaisseur_mur + 0.5);
translate([ext_l - epaisseur_mur - pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2, epaisseur_mur - 0.1])
cylinder(d = pilier_diametre + jeu, h = epaisseur_mur + 0.5);
}
// 3. supports d'encastrement sur angles opposés pour les 3 modules ttp223
hauteur_ergot = ttp_h + 1.0;
epaisseur_ergot = 1.5;
longueur_retour = 3.0;
centre_x = ext_l / 2;
for (i = [-1, 0, 1]) {
centre_y = ext_w / 2 + i * (ttp_w + 5);
translate([centre_x, centre_y, epaisseur_mur]) {
// --- angle haut gauche ---
translate([-ttp_l/2, ttp_w/2 - longueur_retour, 0])
cube([epaisseur_ergot, longueur_retour, hauteur_ergot]);
translate([-ttp_l/2, ttp_w/2 - epaisseur_ergot, 0])
cube([longueur_retour, epaisseur_ergot, hauteur_ergot]);
// --- angle bas droit ---
translate([ttp_l/2 - epaisseur_ergot, -ttp_w/2, 0])
cube([epaisseur_ergot, longueur_retour, hauteur_ergot]);
translate([ttp_l/2 - longueur_retour, -ttp_w/2, 0])
cube([longueur_retour, epaisseur_ergot, hauteur_ergot]);
}
}
}
// 4. trous débouchants fraisés pour la fixation par vis m2 (alignés avec les piliers)
coords_trous = [
[epaisseur_mur + pilier_diametre/2, epaisseur_mur + pilier_diametre/2],
[epaisseur_mur + pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2],
[ext_l - epaisseur_mur - pilier_diametre/2, epaisseur_mur + pilier_diametre/2],
[ext_l - epaisseur_mur - pilier_diametre/2, ext_w - epaisseur_mur - pilier_diametre/2]
];
for (pt = coords_trous) {
// trou central de passage de la vis
translate([pt[0], pt[1], -0.5])
cylinder(d = vis_pas_diametre, h = epaisseur_mur * 2 + 1);
// fraisage pour noyer la tête de vis à la surface (z = 0)
translate([pt[0], pt[1], -0.1])
cylinder(d = vis_tote_diametre, h = vis_tote_hauteur + 0.1);
}
// 5. gravure du texte configuré sous chaque emplacement
centre_x = ext_l / 2;
profondeur_gravure = 1.0;
for (i = [-1, 0, 1]) {
centre_y = ext_w / 2 + i * (ttp_w + 5);
chiffre = (i == 1) ? text_position_1 :
(i == 0) ? texte_position_2 :
texte_position_3;
translate([centre_x, centre_y, -0.1]) {
linear_extrude(height = profondeur_gravure + 0.1) {
mirror([1, 0, 0]) {
text(
text = chiffre,
size = max(6, ttp_w - 4),
font = "liberation sans:style=bold",
halign = "center",
valign = "center"
);
}
}
}
}
}
}
// ==========================================
// logique d'affichage selon l'option choisie
// ==========================================
if (mode_affichage == 1) {
base_boitier();
}
else if (mode_affichage == 2) {
couvercle_tactile();
}
else if (mode_affichage == 3) {
base_boitier();
// pose le couvercle à plat à côté sur l'axe y
translate([0, ext_w + 10, 0])
couvercle_tactile();
}
Cela vous donnera un boîtier refermable par vis, moyennant l’ajout d’inserts, et un couvercle muni des empacements pour les 3 TPP :
Vous aurez observé des tas de configurations possibles dans le code : les boutons 1,2, 3 peuvent porter d’autres noms, l’épaisseur se change, la hauteur du support du Wemos D1, la génération d’une ou 2 pièces en STL, etc. C’est assez modulable, et aussi totalement améliorable.
Pensez à bien tout fermer AVANT de mettre sous tension, les TPP223 se configurent alors avec leur environnement immédiat et réagiront sans soucis à votre approche.


