06
YOSHIMITSU — la solution complète : tous les codes, un seul rouleau
Une fable de cheatcodes où il n'y a que des gagnants. Un sketch détendu, six postures, un harnais permanent : la parade CRSF→PWM (KINCHO), la lévitation gyroscopique Zephyrus (MANJI_DRAGONFLY), le flasheur de poche (FLEA · MEDITATION), l'établi sans épée (NSS), le miroir qui ne regarde jamais en arrière (BACK_TURNED) — plus YOSHI, l'aurore toujours allumée, et JIGUANG (極光), l'administrateur méditant qui raconte la légende. Câble-le une fois, flashe-le une fois ; ensuite la bibliothèque se met à jour et le trône commande.
Une carte, six postures
YOSHIMITSU est le Shinobi Hermétique aux six postures — chaque posture une victoire différente, toutes portant la même âme. Un sketch détendu compile pour les deux cartes ; les postures basculent par commande USB, bouton GPIO0 (ESP32-S3) ou appuis sur RESET (RP2040-Tiny) :
| Posture | Signification |
|---|---|
KINCHO
|
Convertisseur CRSF→PWM — la parade (le CRC écarte le faux). Pas de noms de canal, pas de gyro. |
MANJI_DRAGONFLY
|
Convertisseur + liaison gyro Zephyrus (MPU6050 optionnel) — la lévitation. |
FLEA
|
Gabarit de cycle d'alimentation — la levée qui fait tomber le RX dans son bootloader. |
MEDITATION
|
Flasheur de poche — la tête-éponge, économe en énergie, prête à être flashée. |
NSS
|
Établi sans-épée — servo direct en USB, pas de RF. |
BACK_TURNED
|
Le repos trompeur — un miroir UART vivant. Ne regarde jamais en arrière. |
Un sketch, deux cibles : sketches/yoshimitsu/yoshimitsu.ino compile pour le Waveshare RP2040-Tiny (le plus léger, sans bouton embarqué) et tout ESP32-S3 à USB natif, avec les cores standard arduino-pico / arduino-esp32. Dans l'IDE Arduino, le même sketch se trouve sous File → Examples → Yoshimitsu → Yoshimitsu_Default.
YOSHIMITSU — le firmware combiné
YOSHIMITSU est le firmware recommandé. Il démarre en KINCHO (le convertisseur) et se déplace entre les postures. La console USB est l'interrupteur canonique sur les deux cartes — KINCHO → MANJI → FLEA → MEDITATION → NSS → BACK → POSE <n>. Sur l'ESP32-S3 le bouton BOOT (GPIO0) est une seconde surface :
| Contexte | Geste | Action |
|---|---|---|
| toute posture | double tap | cycle KINCHO → MANJI → NSS → BACK → KINCHO → |
| toute posture | appui long 2 s | entrer en MEDITATION |
| MEDITATION / FLEA | tap simple | redémarrer le récepteur (lancer le nouveau firmware) |
| MEDITATION / FLEA | double tap | FLEA — faire tomber le récepteur dans son bootloader |
Le câblage est un harnais permanent — les mêmes fils servent toutes les postures, donc tu ne recâbles jamais entre voler et flasher. En MEDITATION le chemin USB→UART est un pont purement transparent (aucun parsing de lignes), donc le trafic SLIP binaire d'esptool traverse intact. Source complète : sketches/yoshimitsu/yoshimitsu.ino (le sketch détendu), src/Yoshimitsu.h (le cœur) et src/Yoshimitsu_Loadout.h (le loadout de départ).
La bibliothèque — mettre à jour sans retoucher ton sketch
YOSHIMITSU est une bibliothèque avec un sketch fin par-dessus — tout le Shinobi vit dans la bibliothèque, le sketch ne garde que ta configuration. Installe le dossier une fois comme bibliothèque Arduino ; File → Examples → Yoshimitsu → Yoshimitsu_Default te tend un sketch prêt et détendu, avec broches, portes et les quelques flags qui appartiennent au code. Le cœur vit dans src/Yoshimitsu.h, chaque défaut dans src/Yoshimitsu_Loadout.h (le loadout de départ, valeurs *_DEFAULT). Pour mettre à jour : git pull la bibliothèque — ou dépose une nouvelle release — et ton sketch reste intact. Une mise à jour de firmware n'est jamais un recâblage et jamais une reconfiguration.
src/Yoshimitsu.h— tout le cœur : postures, CRSF, MUSHIN, JIGUANG, le pont du flasheur.src/Yoshimitsu_Loadout.h— le loadout de départ : chaque défaut (broches, timings, niveaux de porte) en valeurs*_DEFAULT.library.properties— le manifeste de la bibliothèque Arduino (version, architectures).examples/Yoshimitsu_Default/— le sketch détendu ; remplace n'importe quoi en le définissant avant l'include.
KINCHO — Convertisseur CRSF→PWM
KINCHO — la posture convertisseur — lit le CRSF à 420 000 bauds sur l'UART, pilote les servos avec une fenêtre de 988–2012 µs mappée depuis la plage de canaux 172–1811, et les centre sur un failsafe de 500 ms. La parade est le contrôle CRC : un frame corrompu est écarté avant d'atteindre jamais un servo. Le convertisseur est agnostique au canal — les servos sont SERVO_PIN_1..8 et la table CHANNEL_TO_SERVO décide quel canal CRSF alimente chacun ; le sens du canal appartient au mixer/kernel, jamais à la carte.
- ESP32-S3 : RX TX → GPIO44, RX RX → GPIO43, GND commune, rail 5 V partagé.
- RP2040-Tiny : RX TX → GPIO1 (UART0), GND commune.
Servos :
SERVO_PIN_1..3(trois de plus sur le S3) — remplaçables dans le bloc PIN MAP.
Pour un ornithoptère stabilisé par gyro, utilise MANJI_DRAGONFLY — le même convertisseur plus la liaison Zephyrus : un MPU6050 optionnel sur GYRO_SDA/GYRO_SCL alimente une correction de taux de lacet dans le servo de crête. Sans gyro câblé, MANJI_DRAGONFLY dégrade avec grâce vers KINCHO. Une carte convertisseuse CRSF→PWM commerciale n'a aucun chemin gyro — les récepteurs de classe EP2 ne portent pas d'IMU, donc Zephyrus vit dans YOSHIMITSU, pas dans le récepteur.
Si ton récepteur parle déjà PWM (une carte 5 ch ou 7 ch), tu n'as pas du tout besoin des postures convertisseuses — MEDITATION ci-dessous est alors ta seule raison de posséder le S3.
KINCHOI — Flasher de poche pour récepteurs de classe EP2
Le problème : les récepteurs de classe EP2 (HappyModel EP2, EP1, EPW6, …) exposent le CRSF sur des pads crénelés et portent un minuscule pad BOOT. Utiliser un adaptateur FTDI, c'est tenir une sonde contre deux pads de 1 mm pendant qu'on cycle l'alimentation du récepteur — maladroit, et tu ressoudes ou reclipses à chaque mise à jour du firmware.
La solution : laisse l'ESP32-S3 être le flasheur. Un GPIO maintient le pad BOOT du récepteur à bas ; un petit P-MOSFET commute le rail 3,3 V du récepteur sous contrôle logiciel ; le port USB devient le port série. Appuie sur un bouton du S3 et il exécute la danse exacte de cycle d'alimentation qui fait tomber un ESP8285 dans son bootloader ROM — puis esptool écrit droit à travers le pont. Pas de FTDI, pas de sondes, pas de ressoudages : soude les pads du récepteur une fois sur un court pigtail et réutilise-le pour toujours.
Liste des pièces :
| Pièce | Référence typique | Coût |
|---|---|---|
| Micro carte ESP32-S3 (USB natif) | Waveshare ESP32-S3-Tiny / -Micro / -Nano | ~6 USD |
| MOSFET canal P niveau logique | AO3401 (SOT-23) sur petite breakout | ~1 USD |
| Résistance 10 kΩ (pull-up de grille) | — | <0,10 USD |
| Fils Dupont / pigtail + gaine thermo | — | ~1 USD |
| Récepteur ELRS, pads pigtailés une fois | EP2 / EP1 / EPW6 (SX1280 + ESP8285) | dès ~12 USD |
Le pont fonctionne avec tout récepteur ELRS ESP8285/SX1280 qui expose TX, RX, 3V3, GND et un pad BOOT — l'écrasante majorité des *cartes concrètes* dans le tableau du matériel . Il flashe aussi le S3 lui-même, bien sûr : bouton BOOT + USB, c'est tout ce qu'il y faut.
Câblage du support de flash
Câble le gabarit avec le S3 hors tension. Le MOSFET commute le rail 3,3 V du récepteur : source → S3 3V3, drain → EP2 3V3, grille → S3 GPIO10 avec pull-up de 10 kΩ vers 3V3 (grille haute = MOSFET coupé). GPIO9 pilote le pad BOOT.
| Pad EP2 / RX | Broche ESP32-S3 | Fonction |
|---|---|---|
| BOOT (RX GPIO0) | GPIO9 | Ligne de maintien boot (bas = entrer dans le bootloader) |
| 3V3 | Drain du MOSFET | Rail commuté (source → S3 3V3, grille → GPIO10) |
| TX (CRSF out) | GPIO18 (U1RX) | RX → TX (croisé) |
| RX (CRSF in) | GPIO17 (U1TX) | TX → RX (croisé) |
| GND | GND | Masse commune (obligatoire) |
S3 3V3 ──► S ── P-MOSFET (AO3401) ── D ──► EP2 3V3
S3 GPIO10 ──► gate (10kΩ pull-up to 3V3; LOW = ON)
S3 GPIO9 ──► EP2 BOOT pad (asserted LOW during power-up)
S3 GPIO18 ◄── EP2 TX (U1 RX)
S3 GPIO17 ──► EP2 RX (U1 TX)
S3 GND ──► EP2 GND
Mode flash
MEDITATION démarre en passage transparent (USB ↔ UART à 115 200 bauds). Pour entrer en mode flash, double-tape le bouton BOOT du S3 (ou tape FLEA sur le série USB). Le sketch :
- tire GPIO9 au bas (pad BOOT actif),
- coupe le MOSFET pendant 120 ms (récepteur hors tension),
- le rallume et attend 900 ms (le récepteur démarre dans son bootloader),
- relâche GPIO9 — le RX siège dans le bootloader ROM, attendant esptool,
- reprend le passage USB↔UART pour qu'esptool puisse lui parler.
Comme le pont ne peut pas piloter les lignes classiques d'auto-reset DTR/RTS, flashe toujours avec --before no_reset — la danse de cycle d'alimentation ci-dessus est le reset. Après le flash, un simple tap BOOT re-cycle l'alimentation du récepteur pour qu'il démarre le nouveau firmware ; un double-tap ne ferait que ré-entrer en mode flash.
Flasher PteronautOS via le S3
Compile le firmware (ou récupère une release), puis lance esptool contre le port série USB du S3. Sur macOS le port apparaît comme /dev/cu.usbmodem* :
# 1. Compile PteronautOS (depuis la racine du dépôt)
pio run -e PteronautOS_ESP8285_2400_RX
# 2. Fais tomber le RX en mode flash (tape FLEA, ou double-tape BOOT), puis :
python3 -m esptool --chip esp8285 \
--port /dev/cu.usbmodemXXXX --baud 115200 \
--before no_reset write_flash \
--flash_mode dout --flash_size 1MB --flash_freq 40m \
0x0 .pio/build/PteronautOS_ESP8285_2400_RX/firmware.bin
# 3. Redémarre le RX une fois de plus (simple tap BOOT) pour lancer le nouveau firmware.
Les réglages de flash (dout, 1 Mo, 40 MHz) correspondent à la cible ELRS ESP8285 d'origine — n'utilise jamais qio ni une taille supérieure. Après le flash, le même port USB affiche le journal de démarrage du récepteur : ouvre-le à 115 200 bauds et guette la bannière PteronautOS puis, dès qu'un émetteur s'appaire, les messages de liaison CRSF. Le pont sert aussi de console de terrain pour la télémétrie en direct.
Vérification et premier vol
- FLEA doit cycler l'alimentation du RX et le laisser attendre — le 3,3 V chute pendant ~120 ms.
esptool rapporte
Chip is ESP8285et finit parHash of data verified.- Le journal de démarrage montre la bannière PteronautOS et, radio allumée, un message de liaison.
- Remue les manches : les servos suivent sans à-coups ; coupe la radio : les ailes se recentrent à 1500 µs en une seconde.
- Si le RX n'entre jamais dans le bootloader, vérifie la polarité du pad BOOT (actif bas) et la commutation du MOSFET avec le test au voltmètre ci-dessus.
Une fois flashé, le même récepteur vole — aucun FTDI ne reste derrière.
Le build de poche RP2040-Tiny
Préfère le Waveshare RP2040-Tiny (~5 USD) — ou son jumeau, le RP2040-Zero, qui partage exactement le même brochage. Les six postures tournent sur le RP2040 sans aucun bouton lisible : les taps BOOT/RESET de l'adaptateur ne pilotent que BOOTSEL/RUN, donc YOSHIMITSU-RP2040 se pilote par le port série USB, plus un compteur de taps RESET sans bouton.
FLEA— faire tomber le récepteur dans son bootloader ROM (danse de cycle d'alimentation du MOSFET), puis ponter USB ↔ UART pour esptool.KINCHO/MANJI/NSS/BACK/MEDITATION— changer de posture.POSE <n>— sauter vers une posture par numéro.STATUS— imprimer la carte de broches active et le rapport d'autotest.HELP— lister toutes les commandes.- Des taps RESET rapides (dans ~2 s, comptés en EEPROM persistée contre la RTC AON) avancent la posture : 1 = MANJI → 2 = NSS → 3 = BACK → 4 = MEDITATION → 5 = KINCHO.
Pour flasher le RP2040-Tiny lui-même, tiens BOOT pendant le cycle d'alimentation (il se monte en disque de stockage de masse), dépose le .uf2 dessus, puis appuie une fois sur RESET — la carte redémarre en KINCHO avec le nouveau firmware. Configure une fois, flashe une fois, n'y touche plus jamais.
Brochage RP2040-Tiny
| Fonction | Broche RP2040-Tiny | Note |
|---|---|---|
| CRSF RX ← TX du récepteur | GPIO1 (UART0 RX) | 420 000 bauds |
| CRSF TX (inutilisé, câblé par complétude) | GPIO0 (UART0 TX) | Croisé : TX → RX |
| Pont RX ← TX du récepteur | GPIO9 (UART1 RX) | 115 200 bauds |
| Pont TX → RX du récepteur | GPIO8 (UART1 TX) | Croisé : TX → RX |
Servo 1 ( |
GPIO2 | PWM — canal via |
Servo 2 ( |
GPIO3 | PWM |
Servo 3 ( |
GPIO4 | PWM |
| Gyro SDA (MPU6050, optionnel) | GPIO10 | MANJI_DRAGONFLY |
| Gyro SCL (MPU6050, optionnel) | GPIO11 | MANJI_DRAGONFLY |
| RX BOOT (GPIO0 du récepteur, actif bas) | GPIO5 | Bas = entrer dans le bootloader |
| RX PWR (grille du P-MOSFET, bas = alimenté) | GPIO6 | Rail commuté 3,3 V |
| LED d'état | GPIO16 | WS2812B |
La carte de broches complète est un bloc éditable en haut de sketches/yoshimitsu/yoshimitsu.ino — plages et collisions de broches sont validées par un POST de démarrage, et les numéros UART invalides refusent de compiler plutôt que de se mal conduire en l'air.
YOSHI — l'aurore des postures toujours active
YOSHI (« l'aurore ») est le cheatcode toujours allumé. YOSHI_RGB transforme l'unique WS2812B embarqué en anneau d'humeur vivant : chaque posture respire sa propre couleur et son propre rythme, pour que tu lises l'esprit du ronin à travers la pièce sans un seul octet série. La couleur et le motif de clignotement racontent l'histoire — aucune commande supplémentaire ; la posture est le cheatcode, la lumière son écho.
| Posture | Aurore (couleur → rythme) |
|---|---|
KINCHO
|
respiration verte lente + un éclair net de double parade (la frappe CRC) |
MANJI_DRAGONFLY
|
une roue chromatique tournant comme les rotors du gyro (la lévitation) |
FLEA
|
stroboscope ambre frénétique et montant (la levée) |
MEDITATION
|
violet presque sombre + un battement lent — prête à être flashée |
NSS
|
éclair net de triple tap en bleu (lame au fourreau, tempo qui monte) |
BACK_TURNED
|
quasi noir + un reflet cramoisi imprévisible (le miroir — ne regarde jamais en arrière) |
Le RGB vit sur le RP2040-Tiny (RGB_LED_PIN=16) derrière YOSHI_RGB ; l'ESP32-S3 garde sa sobre LED d'état. Chaque couleur est de la pure mathématique entière — pas de float, pas de malloc, pas de delay() — et pumpRgb() est bridé à ~50 fps pour que le pont flasheur octet-exact ne soit jamais dérangé. La règle hermétique tient : la pose change, la lumière suit.
JIGUANG — le conteur · commentateur · administrateur
Trois noms, une âme — le triangle de cheatcodes de la solution complète : YOSHIMITSU est tout le firmware du Shinobi Hermétique ; YOSHI est le cheatcode RGB (l'aurore de posture toujours allumée) ; et JIGUANG (極光, « l'aurore ») est l'administrateur méditant — le moteur immobile assis en tailleur sur le trône MEDITATION. La voix de Yoshimitsu est fonctionnelle et brève ; celle de JIGUANG est le mythe. 極光 est le prompt de la console, pas une décoration : pour agir en administrateur, tu tapes 極光 puis la commande — sinon le trône reste hors d'atteinte. Le prompt est un #define (JIGUANG_PROMPT), donc ton sketch peut le renommer ; tout le conteur se cache derrière la porte de compilation JIGUANG (1 = omniprésent, 0 = pas un seul octet de 極光 compilé).
Easter egg : tape 極光 LEGEND et toute la légende se déroule en un seul parchemin ASCII — les postures, les cheatcodes, le trône et le prompt qui ne meurt jamais. JIGUANG / jiguang / 極光 ne meurt jamais — ni dans le code, ni dans les commentaires, ni dans ce tutoriel.
Réveille la voix avec 極光 JIGUANG et elle grimpe quatre niveaux : 0 agneau (silencieuse, même si les commandes explicites répondent encore), 1 conte (boot et chaque changement de posture narrés), 2 parchemin (+ la lecture des canaux CRSF) et 3 omni (+ les octets de debug ELRS du récepteur passés verbatim). 極光 MUTE la fait taire ; 極光 CRSF imprime le parchemin des 16 canaux et 極光 SCORE déroule le classement arcade HIGHSCORE — bonnes trames CRSF, événements failsafe, octets du pont et uptime. JIGUANG ne prend jamais la posture : CRSF, servos et le pont continuent d'obéir à la pose pendant que la légende est racontée.
En MEDITATION la tête-éponge est le trône de JIGUANG — et le trône est gardé : chaque commande d'administrateur commence par le prompt de console 極光. Depuis le paradis USB-série il répond 極光 STATUS, 極光 CRSF, 極光 SCORE, 極光 POSE, 極光 DOC (le catalogue de cheatcodes) et 極光 SETUP (l'assistant de méditation, qui guide les réglages clés au lieu d'un mur de defines). Les changements de posture restent ouverts — KINCHO, MANJI, FLEA, MEDITATION, NSS, BACK, POSE n. La pose économise l'énergie comme l'ancienne pause de méditation, et le ronin reste prêt à être flashé. À l'instant où l'octet SLIP d'esptool appelle, le trône cède au pont transparent du flasheur et y reste jusqu'à ce que MEDITATION revienne. Avec YOSHI_RGB au niveau 3 le conteur porte aussi l'aurore : jiguang(ms) peint une lente roue à spectre complet qui tisse chaque couleur de posture en un seul souffle.
MUSHIN 無心 — le cheatcode de la mémoire musculaire
MUSHIN (無心, « sans pensée ») est la fonction héroïne — le non-attachement, l'épée qui frappe avant la pensée. Dans les arts de l'épée, 無心 est l'esprit qui se lâche de lui-même : aucun intervalle ne demeure entre ce qui est vu et ce qui est fait. PteronautOS est l'esprit : il planifie l'onde de l'aile et envoie des intentions de servo à travers le pont. YOSHIMITSU ne s'accroche pas au plan : il répond au muscle avec le PID local du gyroscope Zephyrus, les servos déjà en mouvement avant que la pensée suivante ne puisse s'agripper. Deux cœurs, une frappe — aucune autre carte ELRS-PWM ne peut porter cela.
Arme-le depuis le trône : 極光 MUSHIN rapporte, 極光 MUSHIN ON/OFF arme ou désarme, et le choix persiste en flash — il démarre prêt. Dans le sketch, MUSHIN démarre armé par défaut ; le flag admin est l'interrupteur au runtime, donc tu ne recompiles jamais pour le changer.
Le protocole v0 du sans-pensée traverse les deux mêmes fils que le flasheur : [0x9B][len][type][payload][xor] — 0x01 intentions (esprit→muscle, n×uint16 µs), 0x02 keepalive d'annonce, 0x03 télémétrie du gyroscope. Les intentions fraîches (moins de 500 ms) pilotent les servos ; le PID gyro local tient la crête. Si le fil se tait, YOSHIMITSU revient à son propre muscle CRSF — dégradation gracieuse, jamais un manche mort.
En vol, la division est le gagnant-gagnant : le récepteur fait la réflexion avant la frappe (CRSF, Zephyrus, l'âme du mixer), et YOSHIMITSU fait ce qui se joue au muscle (PWM PIO sans glitch). Hélicoptère ou battement d'ailes — du point de vue de l'épée c'est pareil : une trajectoire canonique, et l'épée ne demande jamais quel vaisseau elle porte. La pose continue de voler ; seul le regard change.