Et si je vous disais qu’il est possible de faire communiquer deux microcontrôleurs ATtiny via fibre optique, me croirez vous ? Eh bien, c’est ce que je vais vous montrer aujourd’hui !
Bien sûr, je parle bien d’une véritable communication de type série, utilisant ici le protocole UART. Ainsi, il sera possible de transmettre des messages d’un µC à l’autre, pour faire à peu près « tout ce qu’on veut » ! Ça vous dit ? Alors en avant toute 😉
Remarque : il s’agit ici d’un projet éducatif, à portée pédagogique. Il est donc volontairement simplifié, et réalisé avec une solution peu coûteuse (leds simples, phototransistors, fibres optiques plastiques, et connecteurs imprimés en 3D).
À quoi sert cet E/R optique expérimental ? (vidéo)
L’objectif du présent montage est de montrer qu’il est possible d’envoyer un message d’un microcontrôleur à un autre, via fibre optique, afin d’envisager un jour de les faire pleinement communiquer ensemble.
Et ce, sans avoir à dépenser des fortunes avec des fibres optiques coûteuses, ni connecteurs coûteux. Car nous allons utiliser de la fibre optique plastique (pas chère, comparé aux autres !), et des connecteurs optiques imprimés en 3D !
Pour vous faire une démo ce cela, j’ai choisi de réaliser un PCB permettant :
- d’émettre des messages via fibre optique : 2 boutons-poussoirs permettent d’envoyer 2 messages distincts
- de recevoir des messages via fibre optique : 2 leds s’allument ou s’éteignent, selon si un message les concernant a été reçu ou pas
Et pour vous montrer qu’il n’y a pas de « triche », j’ai même utilisé 2 de ces PCB, identiques donc, avec la sortie optique de l’un branchée sur l’entrée optique de l’autre, et vice-versa. Ainsi, les boutons-poussoirs d’une carte commanderont les leds de l’autre carte, et réciproquement.
Tout ça ne vous paraît pas très clair ? Alors voici une courte démo visuelle, vous détaillant tout ça (moins de 2 minutes) :
Comme vous pouvez le constater :
- l’essai 1 (sans fibre optique) fait que l’appui sur les boutons-poussoirs n’allume pas la moindre led, où que ce soit
- l’essai 2 (avec fibre optique du haut) montre la communication « carte de droite » vers « carte de gauche »
- l’essai 3 (avec fibre optique du bas) montre la communication « carte de gauche vers carte de droite »
- l’essai 4 (retrait fibre optique du bas) montre la rupture de communication « gauche vers droite » uniquement
- l’essai 5 (remise fibre optique du bas) montre le rétablissement de la communication gauche/droite
Et comme nous allons le voir dans ce projet, ce n’est pas un simple allumage « oui/non » dans les fibres optiques qui permettent d’allumer l’allumage des leds, mais bien des messages codés sur 8 bits !
Alors si ça vous dit d’en savoir plus, découvrez sans plus attendre chaque partie de ce montage expérimental 🙂
Nota 1 : ce projet est « expérimental » en ce sens où 2 résistances ajustables, figurant sur le PCB, permettent de trouver manuellement le « meilleur point de fonctionnement » de la carte, c’est à dire le point où les communications UART-optique seront les plus rapides possibles. Vous verrez ainsi qu’avoir une résistance trop faible ou trop forte au niveau des transistors limite la vitesse de transmission, et qu’il y a une « valeur ohmique optimale » où la transmission est la plus rapide qui soit. À vous de trouver ces valeurs de résistances variables, en expérimentant vous-même !
Nota 2 : pour info, le débit UART a été réglé sur 1200 bauds ici, pour cette démo vidéo. Nous verrons d’ailleurs ensemble les limites d’un tel projet, vers la fin de cet article.
Présentation de cette carte émettrice-réceptrice UART optique
Histoire d’entrer un peu plus dans les détails, voici la carte PCB de cet émetteur/récepteur optique expérimental vue de plus près. Au passage, si je vous en montre une seule ici, alors qu’il y en avait 2 dans la démo, c’est tout simplement car ce sont 2 cartes identiques que j’ai utilisé (l’une « à l’endroit », et l’autre « tournée à 180° »).

On retrouve ici :
- un microcontrôleur ATtiny (modèle 414), qui gère l’ensemble (boutons-poussoirs, leds, et transmissions UART)
- un connecteur de programmation ATtiny (à utiliser la première fois seulement, pour uploader le programme arduino dans l’ATtiny414)
- une prise d’alimentation USB-C, fournissant du +5V à ce montage
- 2 boutons-poussoirs (notés « BP #1 » et « BP #2 »), permettant de déclencher l’émission de message UART (vers la « fibre optique sortante »)
- 2 leds (notées « LED#1 » et « LED#2 »), s’allumant ou s’éteignant en fonction des messages UART reçus (depuis la « fibre optique entrante »)
- 2 résistances variables (notées « RV1 » et « RV2 »), dont seule celle du bas, RV2, est vraiment utile ici (car c’est elle qui fixe la valeur ohmique raccordée au collecteur du phototransistor de réception lumineuse)
- un connecteur de réception (cylindre blanc du bas), recevant la fibre optique « entrante », fournissant des données à cette carte
- et un connecteur d’émission (cylindre blanc du haut), accueillant la fibre optique « sortante », délivrant des données vers l’extérieur
Important : ce PCB doit être alimenté en 5V soit par la prise USB-C, soit par le connecteur de programmation ATtiny. Mais jamais par ces 2 biais en même temps ! Faites donc bien attention à ce point, si jamais vous reproduisez ce montage.
À présent, avant de passer à la partie électronique à proprement parler, zoomons encore un peu, et voyons en transparence et en 3D les coupleurs optiques fait-maisons (les « fameux » 2 cylindres blancs fixés sur la droite du PCB, là où se branchent les fibres optiques plastiques).
Coupleurs optiques imprimés en 3D « fait-maison » (POF 1 mm)
Les fibres optiques et leurs connecteurs associés coûtent particulièrement cher, à mon goût. C’est pourquoi j’ai expérimenté ici de la fibre optique plastique (aussi nommée POF, issu de l’anglais Plastic Optical Fiber, ou encore Polymer Optical Fiber), avec des connecteurs faits-maison, imprimés en PLA sur une imprimante 3D.
Visuellement parlant, ces connecteurs optiques sont facilement identifiables sur le PCB présenté ci-dessus, car comme évoqué précédemment, il s’agit ni plus ni moins que des 2 « gros » cylindres blancs visibles sur le côté droit du PCB.
Physiquement, ces pièces admettent :
- la fibre optique, par le dessus
- et la LED émettrice (Ø3 mm) ou le PHOTOTRANSISTOR récepteur (Ø5 mm), par le dessous (les connecteurs 3D étant vissés sur le PCB)
Mais pour que ce soit plus parlant, voici les plans d’un des coupleurs optiques imprimés en 3D (les deux sont identiques, dans l’absolu, exception faible du trou côté PCB, où il est de 3mm si le coupleur repose sur la led de 3mm, ou de 5mm si le coupleur repose sur le phototransistor de 5mm) :

Cela étant vu, passons à la partie électronique à présent, qui est bien plus intéressante 😉
Remarque : j’ai nommé « coupleur optique » ces connecteurs optiques, car cela correspond assez bien à leur fonction, à savoir mettre mécaniquement en face l’un de l’autre les composants électroniques d’une part, et l’âme de la fibre optique d’autre part (faisant ici 1 mm, si on fait abstraction de la « gaine noire de protection » Ø2,2 mm).
Schéma électronique
En détail, voici le schéma électronique de cet émetteur récepteur optique expérimental, permettant d’envoyer/recevoir des messages UART entre 2 microcontrôleurs ATtiny, avec 2 boutons-poussoirs de pilotage et 2 leds témoins (remarque : si l’image ci-dessous n’est pas suffisamment lisible, n’hésitez pas à consulter la version PDF de ce schéma, accessible tout en bas de cet article, dans la partie « Liens et téléchargements ») :

Comme à l’accoutumée, je vous ai divisé ce schéma en plusieurs blocs, histoire d’être le compréhensible possible. Ainsi, on retrouve essentiellement :
- un bloc « Connecteur USB », qui permet d’alimenter ce projet en +5V (avec fusible réarmable de protection, et condensateur de filtrage)
- un bloc « Connecteur PROG », qui fournit un accès de programmation UPDI pour le microcontrôleur ATtiny414 présent dans ce montage (et aussi d’alimenter l’ensemble en +5V, si rien n’est branché sur le connecteur d’alim USB)
- un bloc « Partie émission », qui permet de piloter la LED émettrice dans la fibre optique sortante, au travers d’un transistor NPN, muni d’une résistance variable permettant d’ajuster son courant de base (remarque : la porte inverseuse U2D est là pour permettre d’avoir des « fronts bien droits » à chaque changement d’état de la sortie du µC, et d’inverser le signal UART, qui doit être au niveau haut au repos)
- un bloc « Partie réception », dans lequel on retrouve un phototransistor piloté par la lumière qu’il reçoit via la fibre optique entrante. Ici :
- la résistance ajustable RV2 joue un rôle crucial, pour atteindre la vitesse max de transmission
- les deux portes logiques inverseuses (U2F et U2E) permettent simplement d’appliquer un hystérésis (« bascule de Schmitt ») sur les signaux issus du phototransistor, afin de convertir les signaux analogiques « sales » entrants en signaux numériques « propres », et bien stables
- un bloc « Leds », où figurent 2 leds pilotables par le microcontrôleur ATtiny, suivant les messages reçus en UART, via la fibre optique entrante
- un bloc « Boutons-poussoirs », où on retrouve 2 boutons poussoirs de mise à la masse, eux aussi raccordés à l’ATtiny (qui aura ses pull-up d’entrée activées à ce niveau), pour demander l’émission de messages UART, au travers de la fibre optique sortante
- un bloc « Condensateurs de découplage », où se retrouvent des classiques condensateurs de 100nF, permettant de découpler le µC ATtiny414, le circuit intégré 74HC14 (six portes inverseuses à trigger de Schmitt), et la led émettant dans la fibre optique sortante (pour que ça lui fasse une petite réserve d’énergie locale)
- un bloc « Porte inutilisées », qui évite de laisser à l’état de haute impédance les entrées des portes inverseuses non utilisées, qui pourraient bien se mettre à osciller si non raccordées, et par conséquent, induire une consommation excessive de courant, ainsi qu’un échauffement de la puce. C’est pourquoi les entrées de ces portes « libres » sont mises à un niveau fixe et stable (ici la masse), afin d’éviter ce problème potentiel.
Du reste, on retrouve deux autres blocs rudimentaires, à savoir : le microcontrôleur ATtiny 414, et l’alimentation de la puce 74HC14 en elle-même (qui fournira ensuite cette énergie à ses 6 portes inverseuses).
Cela étant vu, passons maintenant au détail des composants utilisés ici, avec leurs références « exactes » 🙂
Important : pour alimenter ce projet en +5V, il faut soit brancher une alim sur la prise USB, soit brancher un programmateur UPDI sur le bornier de prog, mais jamais les deux en même temps ! Faites donc bien attention à ne pas brancher ces 2 alim en même temps, sans quoi vous pourriez provoquer des dégâts !
Liste des composants
Pour ceux que ça intéresse, voici la liste des composants utilisés pour cet émetteur/récepteur UART via fibres optiques, entre deux ATtiny 414 :
Soudage PCB
Voici le circuit imprimé (PCB) de ce projet émetteur-récepteur UART/optique pour ATtiny, vu de dessus et dessous :

À noter que tous les composants CMS sont implanté sur le dessus du PCB, l’arrière étant réservé au plan de masse. Et côté soudage, comme d’habitude, j’ai soudé les plus petits composants en premier, et les plus grands/encombrants ensuite (donc les CMS d’abord, et les composants traversants ensuite, pour faire simple !).
Au niveau du soudage des CMS, j’ai utilisé une table chauffante réglable manuellement en température, et de la pâte à braser basse température (Sn64,7 – Bi35 – Ag0,3 – 179°C). En image, ça donne ceci (avec retouches au fer à souder pour la dernière) :



Pour info, au niveau du profil de brasage, j’ai suivi le plan suivant :
- préchauffage : passage de la température ambiante jusqu’à 120 °C, sur 1 minute environ
- maintien préchauffage : maintien de ces 120 °C, pendant 1 minute environ
- montée en chauffe : augmentation de la température de chauffe de 120 °C à 180/190 °C, sur 1 minute environ
- refusion : maintien de ces 180/190 °C, pendant 30 secondes environ
- refroidissement : arrêt de la chauffe, pour un refroidissement lent et naturel
Vient ensuite le soudage des composants traversants. J’ai réalisé cela avec un simple fer à souder filaire (Kaiweets KETS02), et de la soudure plomb/étain qu’il me reste dans mes tiroirs. Voici ce que ça donne une fois terminé :

Enfin, j’ai vissé les 2 coupleurs optiques (adaptateurs pour fibre optique plastique, imprimés en 3D), comme vous pouvez le voir ici, dessus (cylindres blancs) et dessous (fixation par vis noires) :


Voilà, tout est fin prêt sur le plan matériel ! Il ne reste plus qu’à tester tout ça, en commençant par l’alimentation de ce projet à vide, puis la programmation du microcontrôleur ATtiny 414 😉
Comment programmer le µC ATtiny414 ? (Arduino IDE + megatinycore)
Pour programmer un ATtiny, c’est assez simple, en fait ! Car il suffit simplement de disposer d’un convertisseur USB/UPDI (tel que celui réalisé sur ce site), d’un ordi, et le tour est joué !
Au niveau matériel, il faudra raccorder le +5V, la ligne UPDI, et le GND, entre ce convertisseur USB-UPDI et la carte de ce projet. Et rien d’autre ! Donc aucune alim branchée simultanément sur la prise USB de ce projet, je veux dire ; uniquement cette carte projet et le convertisseur USB UPDI (pour éviter tout conflit de tension).
En pratique, le montage doit ressembler à quelque chose comme ça :

Et immédiatement, à l’aide d’une caméra thermique (type Kaiweets KTI-W01, par exemple), il faudra examiner cette carte PCB en détail, pendant un certain temps, afin de s’assurer de l’absence de tout échauffement anormal. C’est très important, donc ne passez pas outre cette vérification de sécurité, si vous réalisez des montages électroniques !
Ensuite, côté logiciel, il faudra lancer Arduino IDE, et :
- vérifier que « megatinycore » est bien installé (si ce n’est pas le cas, n’hésitez pas à faire un saut sur ce tuto qui explique comment installer megatinycore au niveau d’Arduino IDE)
- et paramétrer convenablement les choses au niveau du menu « Options », comme visible ci-dessous (avant d’uploader les programmes de cet article)

Les principales choses à configurer sont :
- Chip : « ATtiny414«
- Clock : « 1 MHz INTERNAL » (impératif pour le programme #2 de cet article, afin de pouvoir descendre suffisamment bas en vitesse de transmission UART, pour faire des essais / expérimentations)
- Port : le port USB de votre ordi, où est branché l’adaptateur USB/UPDI permettant de programmer l’ATtiny
- Programmateur : « Serial UPDI – SLOW : 57600 bauds » (nota : rassurez-vous, malgré son nom, le mode « SLOW » est particulièrement rapide ici, pour la programmation d’ATtiny ! Et qui plus est, ce mode permet d’éviter les erreurs de transmission, qui peuvent arriver lorsqu’on augmente la vitesse)
Bon … ! À présent, nous sommes fin prêts à voir les 2 programmes de ce projet (un programme de test, pour vérifier que tout va bien, et le programme final ensuite).
Programme #1 : test de « blink optique » (loopback)
Première chose à faire ici : tester l’émission/réception optique, pour voir si tout fonctionne ! Pour ce faire, nous allons :
- mettre un bout de fibre optique reliant la sortie optique de cette carte à son entrée optique, créant ainsi un bouclage local (aussi appelé « loopback », en anglais)
- faire lentement clignoter la LED placée sous le coupleur optique « ÉMETTEUR », à l’aide d’un classique programme « blink »
- et allumer les 2 leds jaunes/oranges du PCB si un faisceau lumineux est reçu au niveau du coupleur « RÉCEPTEUR » (là où le capteur phototransistor est placé, donc)
En clair, il faut d’abord court-circuiter l’entrée/sortie optique de la carte électronique, à l’aide d’une fibre optique. Ainsi, tous les signaux lumineux sortant de la carte seront immédiatement renvoyés en entrée.
Pour ma part, j’ai réalisé cela avec un simple morceau de fibre optique, comme visible ci-dessous :


Ensuite, il faudra uploader le code arduino suivant dans l’ATtiny414, pour faire clignoter la LED émettrice (sous la fibre sortante) toutes les secondes, et allumer ou éteindre les deux LEDs jaune/orange suivant si un signal lumineux est reçu ou non au niveau du phototransistor récepteur.
Voici le code de ce programme de test, faisant un blink optique avec témoins de réception :
// ===================================================================================================
// ______ _ _///_ _ _ _
// / _ \ (_) | ___| | | | (_)
// | [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
// | ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
// | | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
// \__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
// | |
// \_|
// ===================================================================================================
//
// Nom Projet : Émetteur/Récepteur Optique Expérimental (ATtiny, UART)
//
// Desc Projet : Programme permettant de tester la partie optique, via un simple "blink" sur la
// led émettrice vers la fibre optique, et allumage des LEDS embarquées (LED1/LED2)
// chaque fois qu'une lumière est reçue de l'autre côté de la fibre, côté récepteur
//
// Fichier : prgTestBlinkOptique.ino
// Créé le : 31.08.2026
// Auteur : Jérôme TOMSKI
// Site : https://passionelectronique.fr/
// GitHub : https://github.com/PassionElectronique/Emetteur-Recepteur-Optique-Experimental
// Licence : https://creativecommons.org/licenses/by-nc-nd/4.0/deed.fr (BY-NC-ND 4.0 CC)
//
// ==============================================================================================================
//
// Prérequis : Avoir installé "megatinycore" dans Arduino IDE
//
// Remarque : Le UART étant actif à l'état bas, et au repos à l’état haut, la logique est donc inversée
// au niveau de la LED d'émission, ainsi qu'au niveau du phototransistor de réception
//
// ==============================================================================================================
// -----------------------------------------------------------------------
// Affectation des broches (microcontrôleur ATtiny414, en boitier SOIC-14)
// -----------------------------------------------------------------------
constexpr uint8_t BROCHE_LED_1 = PIN_PA4;
constexpr uint8_t BROCHE_LED_2 = PIN_PA6;
constexpr uint8_t BROCHE_EMISSION_OPTIQUE = PIN_PB2;
constexpr uint8_t BROCHE_RECEPTION_OPTIQUE = PIN_PB3;
// ----------
// Constantes
// ----------
constexpr uint32_t INTERVALLE_DE_BLINK_EN_MS = 1000; // Le blink fera donc des alternances "1 seconde allumé" puis "1 seconde éteint", répété à l'infini
// ========================
// Initialisation programme
// ========================
void setup() {
// ---------------------------------------------------------------------------------------------
// Configuration des sorties ATtiny (fixation de l'état pour commencer, puis activation ensuite)
// ---------------------------------------------------------------------------------------------
digitalWrite(BROCHE_LED_1, LOW); // LED1/LED2 s'éteignent en les mettant à l'état bas
digitalWrite(BROCHE_LED_2, LOW);
digitalWrite(BROCHE_EMISSION_OPTIQUE, HIGH); // ... tandis que la LED émettrice optique suit une logique inversée (il faut donc mettre cette sortie à l'état haut, pour éteindre cette led)
pinMode(BROCHE_LED_1, OUTPUT);
pinMode(BROCHE_LED_2, OUTPUT);
pinMode(BROCHE_EMISSION_OPTIQUE, OUTPUT);
// --------------------------------
// Configuration des entrées ATtiny
// --------------------------------
pinMode(BROCHE_RECEPTION_OPTIQUE, INPUT);
// Petit délai, avant de passer à la boucle loop
delay(200);
}
// =================
// Boucle principale
// =================
void loop() {
// Variables locales
static bool etatBlink = HIGH; // Mémorisation ("static") de l'état de blink, qu'on va alterner ON/OFF (low/high) à intervalle régulier (mise à "HIGH", pour commencer)
static uint32_t timingDernierChangementEtatBlink = 0; // Mémorisation ("static") du compteur-temps arduino lors du dernier changement d'état de blink (mise à "0" pour commencer)
const uint32_t maintenant = millis(); // Récupération de la valeur du compteur-temps arduino actuel, à chaque passage dans cette boucle loop
// -------------------------
// Partie "émission optique"
// -------------------------
if (maintenant - timingDernierChangementEtatBlink >= INTERVALLE_DE_BLINK_EN_MS) {
// S'il s'est passé un temps au moins égal à "INTERVALLE_DE_BLINK_EN_MS" depuis la dernière initialisation de "timingDernierChangementEtatBlink", alors :
// 1) on change l'état de notre variable "etatBlink" (ce qui devrait arriver dès le premier passage, dû au fait qu'on a mis 'delay=200' dans la fonction setup)
// 2) on enregistre le compteur-temps arduino au moment de cet événement
// 3) on pilote la led émettrice optique en conséquence
etatBlink = !etatBlink;
timingDernierChangementEtatBlink = maintenant;
digitalWrite(BROCHE_EMISSION_OPTIQUE, etatBlink==HIGH ? LOW : HIGH); // Logique inversée : la LED émettrice sera allumée si on envoie un état bas, et éteinte si on envoie un état haut
} // (logique câblée ainsi, pour l'implémentation du UART plus tard)
// --------------------------
// Partie "réception optique"
// --------------------------
// On check si un signal lumineux est actuellement reçu (en inversant également la logique ici au passage, car c'est routé ainsi sur le PCB)
const bool signalOptiqueActuellementRecu = (digitalRead(BROCHE_RECEPTION_OPTIQUE)==LOW);
// Et on pilote les leds embarquées (LED1 et LED2) en conséquence
digitalWrite(BROCHE_LED_1, signalOptiqueActuellementRecu==HIGH ? HIGH : LOW);
digitalWrite(BROCHE_LED_2, signalOptiqueActuellementRecu==HIGH ? HIGH : LOW);
}Comme vous avez pu le constater, le programme est assez simple, car au final, il ne fait que :
- faire clignoter (blink) la LED « émission optique », en la faisant changer d’état toutes les secondes
- et allumer ou éteindre les LEDS #1 et #2 (jaune/orange, sur le PCB) selon si un signal lumineux est reçu ou non, via le PHOTOTRANSISTOR « réception optique »
La seule petite difficulté pouvant quelque peu brouiller la compréhension de ce programme tient du fait que la logique au niveau du câblage électronique est inversée au niveau du µC, selon l’état du phototransistor (type de câblage « obligatoire » pour assurer la communication UART que nous verrons juste après, dans le programme #2).
C’est à dire que les signaux reçus par l’ATtiny seront :
- à l’état HAUT au niveau du µC si aucune lumière n’est reçue au niveau du phototransistor
- à l’état BAS au niveau du µC si une lumière est reçue au niveau du phototransistor
Mise à part cela, le fonctionnement de ce programme arduino est vraiment basique. On peut d’ailleurs voir le résultat en image, sur cette vidéo :
Ici, on voit bien :
- la LED émettrice rouge qui s’allume au niveau du coupleur optique du haut (émission), car la lumière arrive à passer au travers de la pièce imprimée en 3D
- et les LEDs jaune/orange clignoter au rythme du blink de la led rouge, passant au travers :
- de la fibre optique de court-circuitage/bouclage
- du coupleur optique du bas (réception)
- et du phototransistor captant la lumière reçue
Donc émission et réception fonctionnent bien ! On peut donc passer au programme permettant de faire communiquer deux ATtiny de manière croisée.
Remarque : à ce stade, tout a été testé, sauf les boutons-poussoirs ! En fait, ce 1er programme visait surtout à tester la partie optique en intégralité, émission et réception, et ce de manière répétée et automatisée.
Programme #2 : émission/réception UART via fibres optiques
Maintenant que nous savons que notre carte « émetteur/récepteur optique » fonctionne bien, il est temps de passer au « vrai » programme de ce projet. Celui-ci permettra 2 choses « simultanées » :
- l’envoi de messages UART (TX) à destination de la fibre optique sortante, via la LED émettrice rouge, à chaque fois qu’un bouton-poussoir sera appuyé (plus précisément, on enverra le code 0x01 si le BP1 est appuyé, et 0x02 si le BP2 est appuyé)
- la réception de messages UART (RX) provenant de la fibre optique entrante, via le PHOTOTRANSISTOR récepteur, et l’allumage ou l’extension des leds jaune/orange en fonction (selon si un message 0x01 ou 0x02 a été reçu, ici)
Pour ce faire, nous aurons non pas besoin d’une carte PCB, mais de deux ici. Nous relierons ainsi la sortie optique sur l’entrée optique de l’autre, et vice-versa. C’est d’ailleurs ce que je vous avais montré en intro vidéo de cet article, et que je vous remets ici pour mémoire :
Du reste, pour arriver à faire cette communication bidirectionnelle entre deux microcontrôleurs ATtiny via UART et fibres optiques, nous aurons besoin du programme suivant :
// ===================================================================================================
// ______ _ _///_ _ _ _
// / _ \ (_) | ___| | | | (_)
// | [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
// | ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
// | | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
// \__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
// | |
// \_|
// ===================================================================================================
//
// Nom Projet : Émetteur/Récepteur Optique Expérimental (ATtiny, UART)
//
// Desc Projet : Programme permettant de faire communiquer 2 cartes ATtiny en UART,
// via de la fibre optique (ou plus précisément deux, l'un pour faire
// circuler les données dans un sens, et l'autre dans l'autre sens)
//
// Fichier : prgEmetteurRecepteurOptiqueExperimental.ino
// Créé le : 27.08.2026
// Auteur : Jérôme TOMSKI
// Site : https://passionelectronique.fr/
// GitHub : https://github.com/PassionElectronique/Emetteur-Recepteur-Optique-Experimental
// Licence : https://creativecommons.org/licenses/by-nc-nd/4.0/deed.fr (BY-NC-ND 4.0 CC)
//
// ==============================================================================================================
//
// Prérequis : - Avoir installé "megatinycore" dans Arduino IDE
// - Impérativement sélectionner "1 MHz INTERNAL" dans le menu Outils > Clock
//
// Remarques : - les leds LED1 et LED2 s'allument à l'état haut
// - les boutons poussoirs BP1 et BP2 sont actifs à l'état bas
// (il faudra activer les pull-up ATtiny ici)
// - la liaison UART sera de type : 8 bits, sans parité, et 1 bit de stop
// (avec une vitesse basse de 62 bauds, de préférence, pour commencer !)
//
// ==============================================================================================================
// -----------------------------------------------------------------------
// Affectation des broches (microcontrôleur ATtiny414, en boitier SOIC-14)
// -----------------------------------------------------------------------
constexpr uint8_t BROCHE_LED_1 = PIN_PA4;
constexpr uint8_t BROCHE_LED_2 = PIN_PA6;
constexpr uint8_t BROCHE_BOUTON_POUSSOIR_1 = PIN_PA5;
constexpr uint8_t BROCHE_BOUTON_POUSSOIR_2 = PIN_PA7;
// + PB2 : TX UART (émission optique)
// + PB3 : RX UART (réception optique)
// ----------
// Constantes
// ----------
constexpr uint32_t VITESSE_TRANSMISSION_UART_EN_BAUDS = 1200; // Minimum 62 bauds / Maximum 125000 ... mais maximum relativement limité en pratique (en ajustant RV2, j'ai atteint 3900 bauds sur une carte,
// et 5000 bauds sur une autre). Ici, avec un tel montage artisanal, rien qu'une fibre optique insérée différemment peut influer sur le débit !
constexpr uint8_t OCTET_DE_SYNCHRONISATION = 0x5A; // Bits de synchronisation = 0101 1010 (choisi "au hasard", comme motif de départ de communication UART)
constexpr uint8_t OCTET_SIGNIFIANT_BP1_APPUYE = 0x01; // Valeur signifiant "un appui sur le bouton poussoir #1 a été fait"
constexpr uint8_t OCTET_SIGNIFIANT_BP2_APPUYE = 0x02; // Valeur signifiant "un appui sur le bouton poussoir #2 a été fait"
constexpr uint16_t DELAI_REARMEMENT_BP_EN_MS = 30; // 30 ms de délai "anti-rebond logiciel", pour chaque bouton poussoir
// ---------------------------------------------------------------------------------------------
// Structure définissant "un bouton poussoir", avec les propriétés qu'on décide de lui adjoindre
// ---------------------------------------------------------------------------------------------
struct BoutonPoussoir {
uint8_t broche_attiny_utilisee; // Permet de dire quelle broche ATtiny sera affectée au bouton-poussoir en question
bool precedent_etat_lu; // Permet de mémoriser le précédent état lu du bouton poussoir (en sachant que ce programme va scanner l'état des BPs à chaque passage en boucle loop)
uint32_t timing_dernier_changement_d_etat; // Permet de mémoriser le timing arduino (compteur temps qui a démarré à 0 à la mise sous tension ou reset de l'arduino) au moment du dernier changement d'état du BP
bool bouton_precedemment_relache; // Permet de dire si le bouton était précédemment relaché ou non (avec anti-rebond post-relachement)
};
// ---------------------------------------------------------------------------------------------
// Déclaration de nos 2 boutons poussoirs, à l'aide de la structure 'struct' précédemment créée)
// ---------------------------------------------------------------------------------------------
BoutonPoussoir bp1{BROCHE_BOUTON_POUSSOIR_1, HIGH, 0, true}; // HIGH, O, false permet donc de définir initialement : precedent_etat_lu = HIGH, timing_dernier_changement_d_etat = 0,
BoutonPoussoir bp2{BROCHE_BOUTON_POUSSOIR_2, HIGH, 0, true}; // et bouton_precedemment_relache = true
// ========================
// Initialisation programme
// ========================
void setup() {
// Configuration des broches ATtiny où seront branchées les LEDs
pinMode(BROCHE_LED_1, OUTPUT);
pinMode(BROCHE_LED_2, OUTPUT); // Broches configurées en "sortie"
digitalWrite(BROCHE_LED_1, LOW); // et mises à l'état bas, pour commencer (leds éteintes)
digitalWrite(BROCHE_LED_2, LOW);
// Configuration des broches ATtiny où seront branchés les BOUTONS POUSSOIRS
pinMode(BROCHE_BOUTON_POUSSOIR_1, INPUT_PULLUP);
pinMode(BROCHE_BOUTON_POUSSOIR_2, INPUT_PULLUP); // Broches configurées en "entrée", et pull-ups ATtiny activées
// Configuration de la liaison UART
Serial.swap(0); // Nota : le "0" permet de sélectionner les broches UART par défaut (si j'avais mis 1, il aurait fallu utiliser les broches alternatives TX/RX de l'ATtiny, mais ce n'est pas le cas ici)
Serial.begin(VITESSE_TRANSMISSION_UART_EN_BAUDS, SERIAL_8N1); // Initialisation de la liaison UART, à la vitesse choisie plus haut (en mode "8N1", donc : 8 bits / sans parité / 1 bit de stop)
}
// =================
// Boucle principale
// =================
void loop() {
// ----------------------
// Partie "émission UART"
// ----------------------
// On check l'état du 1er bouton-poussoir, et s'il est appuyé, alors on envoie un message via l'UART signifiant cela
if (boutonAppuye(bp1)) envoieOctet(OCTET_SIGNIFIANT_BP1_APPUYE);
// On check l'état du 2nd bouton-poussoir (et s'il est appuyé, on envoie un message via l'UART signifiant cela)
if (boutonAppuye(bp2)) envoieOctet(OCTET_SIGNIFIANT_BP2_APPUYE);
// -----------------------
// Partie "réception UART"
// -----------------------
// On check si des données ont été reçues via l'UART (et sont donc en attente de lecture)
while (Serial.available() > 0) {
// Si c'est le cas, alors on lit un octet uniquement, on le traite, puis on passe aux éventuels suivants
uint8_t octetRecu = Serial.read();
traiteOctetRecu(octetRecu);
}
}
// ======================
// Fonction "envoieOctet"
// ======================
void envoieOctet(uint8_t octet_a_envoyer) {
// Afin que le récepteur soit "sûr" que l'octet qu'il reçoit est bon, on va "encadrer" cet "octet à envoyer" entre un octet de synchronisation (motif 8 bits toujours identique, signifiant le
// début d'une transmission), et le complément de cet octet (tous les bits inversés, donc, afin de pouvoir faire une comparaison simple ensuite, vérifiant l'intégrité ou non de la donnée transmise).
uint8_t complement_de_l_octet_a_envoyer = (~octet_a_envoyer);
// Du coup, la trame (suite de 3 octets ici) qui sera envoyée via l'UART se décomposera ainsi :
// 1) un octet de synchronisation
// 2) l'octet à envoyer
// 3) et le complément de cet octet à envoyer
Serial.write(OCTET_DE_SYNCHRONISATION);
Serial.write(octet_a_envoyer);
Serial.write(complement_de_l_octet_a_envoyer);
}
// =======================
// Fonction "boutonAppuye"
// =======================
bool boutonAppuye(BoutonPoussoir &bp) {
// Lit l'état actuel du bouton poussoir visé
const bool etat_actuel_bp = digitalRead(bp.broche_attiny_utilisee);
// Récupération du compteur temps arduino, pour pouvoir ensuite comparer cela au timing mémorisé dans la "struct" de ce bouton-poussoir
const uint32_t maintenant = millis();
// Si l'état a changé depuis la dernière lecture du BP, alors on mémorise ce nouvel état, et la valeur du compteur-temps arduino à cet instant
if (etat_actuel_bp != bp.precedent_etat_lu) {
bp.precedent_etat_lu = etat_actuel_bp;
bp.timing_dernier_changement_d_etat = maintenant;
}
// Si ce bouton vient juste d'être appuyé, alors on retourne "true" pour que la transmission UART démarre
if (etat_actuel_bp == LOW && bp.bouton_precedemment_relache) {
bp.bouton_precedemment_relache = false;
return true;
}
// Si ce bouton a été relaché, on regarde depuis combien de temps, et on réinitialise son état si le délai de réarmement a été dépassé
if (etat_actuel_bp == HIGH && !bp.bouton_precedemment_relache) {
if (maintenant - bp.timing_dernier_changement_d_etat >= DELAI_REARMEMENT_BP_EN_MS) {
bp.bouton_precedemment_relache = true;
}
}
// Dans tous les autres cas, on retourne false
return false;
}
// ==========================
// Fonction "traiteOctetRecu"
// ==========================
void traiteOctetRecu(uint8_t octet_recu) {
// Liste énumérant les différents états que peut prendre RX, dans ce programme
enum ListeDesEtatsPourRX : uint8_t { ATTEND_OCTET_DE_SYNCHRONISATION, ATTEND_OCTET_DE_DONNEE, ATTEND_COMPLEMENT_OCTET_DE_DONNEE };
// Variable enregistrant l'état courant de RX ("static" permet de mémoriser cette variable après sortie de cette fonction, pour le "tour d'après")
static ListeDesEtatsPourRX etatDeRX = ATTEND_OCTET_DE_SYNCHRONISATION;
// Variable permettant de mémoriser la donnée qui sera reçue (pour la comparer ensuite à son complément, qu'on devrait recevoir en suivant)
static uint8_t donnee_transmise;
// Actions à faire, selon les différents états possibles de RX
switch (etatDeRX) {
// ---------------------------------------
// Cas : "ATTEND_OCTET_DE_SYNCHRONISATION"
// ---------------------------------------
case ATTEND_OCTET_DE_SYNCHRONISATION:
if (octet_recu == OCTET_DE_SYNCHRONISATION) {
// Si on a bien reçu un octet de synchronisation (un "motif" permettant de repérer le début d'une trame UART, ici), alors on passe à la suite (attente de "l'octet de donnée")
etatDeRX = ATTEND_OCTET_DE_DONNEE;
}
break;
// ------------------------------
// Cas : "ATTEND_OCTET_DE_DONNEE"
// ------------------------------
case ATTEND_OCTET_DE_DONNEE:
// Si on a bien reçu un octet signifiant un appui sur BP1 ou BP2, alors on mémorise cet état, et on passe à la suite (attente du "complément")
if (octet_recu == OCTET_SIGNIFIANT_BP1_APPUYE || octet_recu == OCTET_SIGNIFIANT_BP2_APPUYE) {
donnee_transmise = octet_recu;
etatDeRX = ATTEND_COMPLEMENT_OCTET_DE_DONNEE;
} else {
// Sinon, on revient "à la case départ", en attendant une nouvelle trame (commençant par "l'octet de synchronisation")
etatDeRX = ATTEND_OCTET_DE_SYNCHRONISATION;
}
break;
// ------------------------------
// Cas : "ATTEND_OCTET_DE_DONNEE"
// ------------------------------
case ATTEND_COMPLEMENT_OCTET_DE_DONNEE:
// Calcul rapide du complément, à partir de la précédente donnée transmise mémorisée
uint8_t complement_donnee_transmise = ~donnee_transmise;
// Si l'octet reçu correspond à ce complément, alors on agit sur les LEDs en fonction de quel BP a été appuyé
if (octet_recu == complement_donnee_transmise) {
if (donnee_transmise == OCTET_SIGNIFIANT_BP1_APPUYE) { // Nota : "octet_recu" contient le complément de "donnee_transmise" ; il faut donc réutiliser
digitalWrite(BROCHE_LED_1, !digitalRead(BROCHE_LED_1)); // "donnee_transmise" non complémenté ici, pour faire les tests de correspondance
} else if (donnee_transmise == OCTET_SIGNIFIANT_BP2_APPUYE) {
digitalWrite(BROCHE_LED_2, !digitalRead(BROCHE_LED_2));
}
}
// Et dans tous les cas, que l'octet ait bien été un complément ou qu'il y ait eu une erreur, on retourne "à la case départ" (à savoir : attente d'un nouvel "octet de synchronisation")
etatDeRX = ATTEND_OCTET_DE_SYNCHRONISATION;
break;
}
}Surtout, ne prenez pas peur à la vue de ce programme arduino ! Car il est vraiment simple, si vous l’abordez morceau par morceau. D’ailleurs, la fonction « loop » résume bien tout le programme :
- on regarde l’état du bouton poussoir BP1, et s’il est appuyé, alors on envoie le message correspondant via UART, et par conséquent, via fibre optique sortante (« émetteur »)
- on regarde l’état du bouton poussoir BP2, et idem que BP1
- on regarde si des octets ont été reçus via l’UART, à partir du phototransistor, et donc, via la fibre optique entrante (« récepteur »), et on les traite (en fait, finalement, on allume ou éteint la led LED1 ou LED2 en fonction des messages reçus)
Par contre, en dehors de cette fonction « loop », il y a une chose qu’il faut que je vous explique au niveau de la fonction « setup » : ici, vous trouverez une constante nommée « VITESSE_TRANSMISSION_UART_EN_BAUDS ». En fait, elle permet de définir la vitesse de transmission UART, en bauds (équivalent à des « bits par seconde », ici). Pour commencer, je vous conseille d’opter pour 62 bauds, qui est la vitesse minimale à laquelle le UART peut tourner, avec une fréquence CPU ATtiny de 1 MHz. Ensuite, vous pourrez monter en vitesse, jusqu’à voir à partir de quand ça bloque au niveau des transmissions.
Important : sélectionnez bien « 1 MHz internal » pour la vitesse CPU de l’ATtiny 414, au moment du téléversement de ce programme (upload), sans quoi il sera impossible de ralentir suffisamment la vitesse de transmission UART, du moins autant qu’il le faudrait ici pour expérimenter la carte (car suivant les positions des résistances variables RV1 et surtout RV2, la communication UART pourrait ne pas fonctionner, tant que les réglages ne sont pas dégrossis).
Ah oui… autre chose importante dont j’ai oublié de vous parler ici : pour limiter les erreurs de transmission, j’ai fait le choix d’envoyer 3 octets et non 1 seul, à chaque fois qu’un bouton poussoir est appuyé, au niveau du code arduino. Plus exactement, ce programme enverra :
- un 1er octet contenant une valeur fixe (j’ai arbitrairement mis 0x5A dans le code, pour qu’il y ait pas mal de 0 et de 1 dans la trame UART de départ)
- un 2ème octet contenant la valeur relative au bouton-poussoir appuyé (0x01 pour BP1, et 0x02 pour BP2, valeurs choisies arbitrairement aussi, et pouvant être modifiées comme bon vous semble)
- un 3ème octet, qui sera le « complément à 1 » (l’inversion de tous les bits, si vous préférez) des octets correspondant à BP1 et BP2 (par exemple, si BP1 envoyait la valeur 0000 0001, alors le complément de BP1 serait 1111 1110). À noter que cet octet n’est pas indispensable en soit, mais qu’il renforce la sécurité de la transaction. En effet, côté récepteur, on pourra ainsi comparer « l’octet miroir » reçu (3ème) à l’octet de donné précédemment reçu (2ème), et immédiatement s’apercevoir si un bit a été altéré en cours de route (et donc, rejeter ce message altéré/non conforme)
Et j’insiste bien sur le fait que peu importe les valeurs du 1er octet (que j’ai nommé « octet de synchronisation » dans le code) et de celles des boutons-poussoirs (BP1 et BP2), du moment que émetteur et récepteur travaillent avec les mêmes valeurs !

Limites de ce projet (led/phototransistor + adaptateurs pour fibre optique imprimés en 3D)
Comme vous pouvez l’imaginer, la limite de ce projet expérimental est surtout liée à sa partie optique (car je ne suis pas parti sur des connecteurs pour fibre optique coûteux, en fait).
Problèmes de diamètres
Dans ce projet :
- la LED émettrice fait Ø3 mm extérieur (et 10° d’ouverture au niveau de sa lumière émise, ce qui fait que « tout ne pars pas en ligne droite » non plus !)
- la fibre optique plastique fait Ø1 mm intérieur (le reste autour étant un isolant protecteur)
- et le phototransistor fait Ø5 mm extérieur
Donc on passe de 3mm –> 1mm –> 5mm. Comme vous pouvez vous en douter, ce n’est pas optimal 😉
Problèmes d’alignement
Du fait de l’imprécision de mes impressions 3D, les fibres optiques ne sont pas forcément piles dans l’axe des composants électroniques (led et phototransistor, j’entends).
Cela est principalement dû au fait que ma « vieille » imprimante 3D était montée avec une buse « grossière » de 0,6mm pour gagner du temps, du vieux filament insuffisamment sec, et tout ça amène à un travail non soigné (faute de moyens, désolé !).
Problèmes de longueurs d’ondes
Dans ce projet :
- la LED émet à 624 nm (rouge)
- et le PHOTOTRANSISTOR a une sensibilité maximale à 570 nm (efficacité à 1), et environ 10 % de moins (efficacité à 0,9) à 624 nm
Cela signifie qu’il y a une perte d’efficacité ici, rien qu’au fait que les longueurs d’ondes ne s’accordent pas comme il faut.
Fibre simplement coupée au cutter, à la main
Autre point problématique : la coupe de la fibre. Perso, j’ai simplement fait ça avec une lame de cutter, à la main. Mais cela à 2 inconvénients :
- la coupe n’est pas forcément propre, du fait que la fibre ne se coupe pas forcément d’un seul coup (il faut parfois la tourner pour arriver à la couper, sans risque de casser la lame du cutter)
- et la coupe n’est assurément pas droite (perpendiculaire à son âme, je veux dire), ce qui fait que l’émission ou la réception de signaux lumineux peuvent être inefficients !
Problèmes du serrage par friction des fibres optiques
Autre point : j’ai conçu le coupleur optique afin que la fibre optique s’insère de manière serrée, sans système de verrouillage. Cela m’a posé 2 soucis :
- je n’étais pas sûr que la fibre descendait bien à fond (car même s’il y a une butée au fond de ma pièce imprimée en 3D, la friction peut à elle seule faire croire que la fibre est bien arrivée au fond, alors que non !)
- des dépôts (dus au frottements de la fibre sur le PLA, lors de l’insertion) peuvent se déposer sur la fibre, offusquant ainsi tout ou partie de son âme conductrice de lumière (ce que j’ai découvert à plusieurs reprises lors de mes essais, où j’ai retrouvé des bavures/morceaux de PLA blanc « collés » au bout de la fibre optique)
Problèmes de diffusion de lumière au travers du PLA
Vous l’avez certainement remarqué sur la vidéo de « blink optique », on voit clairement la LED émettrice rouge « illuminer » l’intérieur de pièce imprimée en 3D, et ce, malgré 6 épaisseurs de cloison ! Donc la lumière se diffuse vers l’extérieur du coupleur, lors d’une émission lumineuse. Et on peut aisément comprendre qu’on a le même soucis côté réception, où se trouve le phototransistor qui est ainsi parasité par cette lumière externe (qui peut être handicapant, en « haute fréquence » de transmission).
Par ailleurs, le PLA de couleur BLANC n’était peut-être pas un bon choix ici, pour ce type d’application (c’était toutefois la seule couleur que j’avais sous la main, au moment de l’impression, faute de moyens là encore !). Toutefois, il faut bien avouer que ça a été un atout indéniable pour la visualisation des signaux émis dans la fibre optique, pour la démo du « blink optique » 🙂
Le bilan
Ce type de connexion optique artisanal imprimé en 3D n’est clairement pas l’idéal !
Cela étant dit, on peut sûrement améliorer les choses ici, avec un meilleur choix de composants (led émettrice / phototransistor de réception), et une impression 3D plus soignée. Et sans parler du fait que ce montage pédagogique est particulièrement économique, comparé aux solutions « industrielles » !
Qui plus est, après avoir finement réglé la résistance ajustable RV2, j’ai quand même pu atteindre les 3900 bauds sur une carte, et 5000 bauds sur une autre, ce qui n’est pas si mal non plus, pour un tel montage fait-maison 😉
Pour info, pour atteindre les 3900 bauds sur la première carte, j’ai réglé la résistance variable RV2 multitours sur environ 19,2 KΩ ; ce qui fait donc 21,4 KΩ de résistance au collecteur du phototransistor, si je prends en compte la résistance fixe de 2,2 KΩ mise en série avec.
Du reste, pour compléter les tests, il faudrait également :
- faire des essais longue distance (que je n’ai pas pu faire, faute de temps cette fois). En effet, il serait intéressant de voir la vitesse de transmission qu’on pourrait atteindre suivant la longueur de fibre plastique utilisée
- et brancher un oscillo sur le collecteur du phototransistor pour bien montrer l’incidence de la résistance variable RV2 (en prenant 3 exemples : une valeur ohmique insuffisante, optimale, et trop importante)

Liens et téléchargements
Pour tous ceux que ça intéresse, vous trouverez ici :
- le schéma électronique de cet émetteur/récepteur UART optique ATtiny, en version PDF
- la conception 3D des coupleurs pour fibre optique, faite sous FreeCAD
- le programme ATtiny de test optique, sur GitHub
- le programme ATtiny d’émission/réception optique ATtiny/UART, sur GitHub
- et le lien vers le PCB de ce projet (pour ceux qui souhaiteraient commander le circuit imprimé de ce projet expérimental, moyennant « quelques euros », via le fabricant PCBWay ; pour plus d’infos, voir les explications ci-dessous)
(*) COMMENT FAIRE FABRIQUER LE PCB DE CE PROJET ?
→ Cliquez sur le lien juste ci-dessus (pour ouvrir le projet partagé sur PCBWay)
→ Cliquez sur « Add to cart » (pour l’ajouter à votre panier)
→ Attendre quelques minutes (sinon 24/48h maximum) pour que les fichiers de ce projet soient vérifiés (surveiller l’état d’avancement des éléments dans le panier ; ils resteront grisés tant que ça n’a pas été validé, et colorés une fois fait)
→ Finalisez la commande de circuit imprimé (en ajoutant un stencil, au besoin !)
Communication UART ATtiny via POF : conclusion !
Voilà pour aujourd’hui ! J’espère que ce montage optique expérimental vous aura plu, ou vous aura permis d’apprendre des choses. Aussi, peut-être vous aura t’il permis d’entrevoir tout le potentiel d’une telle solution (transmission UART/optique entre microcontrôleurs). Surtout que, dans l’absolu :
- on n’est pas limité à l’envoi d’un seul octet utile par message (et remplacer l’octet « miroir » par une « somme de contrôle », appelée « checksum » en anglais)
- et on pourrait très bien imaginer une carte « maître » et des « périphériques » esclaves ensuite, et piloter tout un ensemble de cartes (soit mises en série, soit mises en parallèle) avec deux fibres optiques seulement 🙂
Sur ce, je vous laisse !
À bientôt,
Jérôme.
À découvrir aussi : un adaptateur I2C ATtiny pour capteur à ultrasons HC-SR04
(*) Mis à jour le 06/11/2026

Félicitations, sacré travail de réalisation et de rédaction ; petite remarque, au paragraphe 10.5, l’emploi du mot « offusquant » est impropre me semble t-il.
Salut Maurice !
Merci infiniment ! Et concernant le verbe « offusquer », au sens propre, il signifie « empêcher de voir en éblouissant ou en obscurcissant ». Ici, comme la fibre optique peut être partiellement ou totalement offusquée (masquée/cachée) par des résidus de PLA, je pense que le terme est approprié (cf. https://www.dictionnaire-academie.fr/article/A9O0290). Après, je peux le changer en « masquer » ou « cacher », si y’a besoin 🙂
Excellente journée à toi,
Jérôme.