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.


Publications similaires

  • SkyDSL : manque de souplesse ?

    Parfois j’ai l’impression de parler à un mur ! Prenons SkyDSL : j’ai demandé à basculer sur l’offre 10 MBps alors que la promotion à 19,90 € était en cours. Réponse ce matin : pas possible avant le 1er Aout, et je paierai plein tarif à ce moment là, soit 49,90 € mensuels !! Or, le changement m’avait été confirmé, SANS FRAIS, SANS CHANGEMENT DE TARIF par un conseiller clientèle partenaires que j’avais eu au téléphone… Imaginez le mécontentement ce…

  • Les taxis Wimax

    eh oui, mais pas en France désolé, le Wimax mobile restant toujours interdit ! Cela se passe à Taïwan : les taxis sont équipés de terminaux Wimax permettant de surfer sur internet ou de regarder des Web-TV, c’est ce qu’évoque l’article du Monde Informatique.

  • Wimax : Bolloré & Orange ?

    Le groupe Bolloré Télécom, titulaire de20 licences wimax régionales, serait en pourparlers avec Orange et d’autres opérateurs pour mutualiser les sites et ainsi pouvoir proposer le service wimax dans plusieurs régions. Les opérateurs fourniraient les sites, Bolloré les licences régionales. L’avenir nous dira si une telle offre peut survivre, et si la couverture des zones blanches est effectivement un marché rentable. Rappelons que Bolloré a récemment fermé un relai wimax dans le nord faute de rentabilité (à moins que les…

  • AutoBlueSky : Publication RSS vers Bluesky

    Ce projet permet de publier automatiquement les nouveaux articles d’un flux RSS vers le réseau social Bluesky. Le script est conçu pour Python 3. Il récupère les articles, extrait intelligemment l’image de couverture et le résumé (via les balises OpenGraph), et publie le tout sous forme de « Card » riche. Prérequis Étape 1 : récupérer le mot de passe d’application Pour utiliser ce script, vous ne devez jamais utiliser votre mot de passe de connexion habituel. Vous devez générer un mot…

  • VoIP sur Blackberry enfin mûre !

    Une fois n’est pas coutume, nous ne parlerons pas d’iPhone : il semblerait cette fois que la VoIP prenne enfin son essort sur les Blackberry avec l’application TringMe. Les appels peuvent se passer en WiFi, mais également avec des numéros en callback (rappel). Les utilisateurs TringMe pourront en outre communiquer librement et gratuitement entre eux. Ajoutez à cela des possibilités de conférence, des envois de SMS, etc. Source : TringMe

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.