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 — KINCHOMANJIFLEAMEDITATIONNSSBACKPOSE <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.

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.

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 :

  1. tire GPIO9 au bas (pad BOOT actif),
  2. coupe le MOSFET pendant 120 ms (récepteur hors tension),
  3. le rallume et attend 900 ms (le récepteur démarre dans son bootloader),
  4. relâche GPIO9 — le RX siège dans le bootloader ROM, attendant esptool,
  5. 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

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.

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 (SERVO_PIN_1)

GPIO2

PWM — canal via CHANNEL_TO_SERVO

Servo 2 (SERVO_PIN_2)

GPIO3 PWM

Servo 3 (SERVO_PIN_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.