まこと の ブログ

MaKoTo no burogu — Journal de bord…

Aller au contenu | Aller au menu | Aller à la recherche

Mot-clé - Rétrogaming

Fil des billets - Fil des commentaires

dimanche, 22 mars 2026

Décapotes -03-, circuit de positionnement d'image pour écran TV

Suite de la conception précédente :

  • Avant de tenter de résoudre le problème du trou dans H−Sync, j'ai voulu trouver une solution à la stabilité de la synchro sortante afin d'obtenir une image la plus nette possible, et ce même si le circuit à base de PLL propose une qualité d'image tout à fait correcte.

Mon côté perfectionniste doublé de curiosité m'emmena faire un tour du côté du monde merveilleux de l'Arduino et de l'ESP32. Malheureusement les quelques essais que j'ai pu réaliser n'ont pas donnés les résultats escomptés, et étaient parfois pire qu'avec mon précédent circuit.

  • Quelques temps ont passés avant que je sois poussé à m'intéresser au Raspberry Pi Pico, et plus particulièrement la carte de WaveShare RP2040-ZERO.

J'étais passé jusqu'alors complètement à côté de cette puce. Certes j'avais eu vent de son existence et de la « mode » entourant sa sortie, beaucoup de monde s'y mettait, sauf moi. Comme souvent j'ai plusieurs trains de retard sur les technos, que je sais laisser passer tranquillement avant d'en avoir réellement besoin. Idem pour tout ce qui est LLM + prompt d'intelligence simulée, pas besoin. Vous lisez un type qui lit encore sa musique classée dans des dossiers, en local sur son appareil. Pas de méta−données, rien. Pas besoin.

  • Bref. J'ai donc découvert le RP2040 et entrevu une potentielle solution pour mon problème, en comprenant ce qu'il en était des States Machines, ces machines intégrées à la puce à qui on s'adresse en assembleur et qui roulent au rythme des cycles d'horloges, indépendamment du code adressé au processeur.

Vraiment très intéressant, quand on sait la vitesse à laquelle c'est capable de monter sans sourciller.
C'est bien simple, j'ai pu coder des exemples de génération de signaux de manière classique, à travers le processeur et demander la même chose aux States Machines et le résultat à l'oscilloscope était sans équivoque tellement meilleurs avec ces dernières.
Pour plus d'info, il y a cette vidéo qui explique très bien ce qu'il en est des Machines à état et cette page aussi..
Je comprend maintenant l'engouement pour ce Raspberry Pi Pico !

Un troisième circuit d'essais :

  • J'ai donc envisagé ce schéma, avec une nouvelle fois la structure basée sur le circuit séparateur de synchro LM1881 en entrée, les portes logiques 74LS132 en sortie, mais utilisant le RPi Zero pour le traitement du signal.


  • Particularité ici très importante, le RP2040 fonctionnant en logique 0−3,3V, il faut impérativement adapter les signaux qu'on lui applique, ce que je fais ici à l'aide d'un circuit basé sur le transistor MOSFET BS170 montés ainsi en adaptateur de niveau logique.

Je dispose maintenant d'un analyseur logique, ce qui est bien pratique pour montrer facilement les signaux. J'en profite donc pour donner un relevé des signaux d'entrée/sortie du LM1881, agrémentés de diverses mesures intéressantes…



  • Après plusieurs itérations, j'ai pu écrire ce programme µ−python pour le RP2040-Zero (dispo aussi en annexe à ce billet), pour déphaser les signaux.

Il utilise quatre State Machines pour déphaser les signaux. Les potentiomètres et le bouton sont gérés par le CPU. Lorsqu'on appuie sur le bouton, on passe en mode lecture de la valeur des pots, ce qui permet donc de décaler l'image en les réglants, puis de mémoriser ces réglages en rappuyant sur le bouton.

  • Voyons ce que donnent les signaux :


− En blanc, le C−Sync d'entrée,
− En marron, le V−Sync de sortie du LM1881, qui entre dans le RP2040-Zero en GP5,
− En rouge, le C−Sync de sortie du LM1881, qui entre dans le RP2040-Zero en GP14,
− En orange, le V−Sync déphasé en sortie GP6 du RP2040-Zero, qui entre dans le 74LS132,
− En jaune, le C−Sync déphasé en sortie GP15 du RP2040-Zero, qui entre dans le 74LS132,
− En vert, la sortie du 74LS132, avec V−Sync + C−Sync réassemblés.

Lire la suite...

samedi, 22 novembre 2025

Joystick Arcade pour Nintendo GameCube

La borne est en travaux !
En plus du PC « mame » je souhaite lui installer deux autres systèmes de jeux, dont l'un est la console GameCube.
Motivation ? Jouer à Ikaruga et SoulCalibur sur la borne avec les sticks arcade.
Sauf que ! Comment faire pour connecter ces derniers à la console ?

Avant de réinventer la roue, j'ai traîné sur le web à la recherche d'une proposition de circuit électronique.
J'ai eu un peu de mal à trouver ce que je cherchai, visiblement ça n'intéresse pas trop les foules… L'occasion de constater au passage que la manette GameCube n'était pas aussi électroniquement simple que ses aînées, et qu'il faudrait un circuit programmable pour faire le travail.

J'ai fini par trouver cette page, qui décrit comment construire un contrôleur maison, avec un Arduino, et surtout l’existence de la bibliothèque logicielle adéquate : https://github.com/NicoHood/Nintendo (que je joins en annexe à ce billet)

  • Le code C++ est vraiment très simple à adapter grâce aux exemples donnés, et j'ai alors pu assigner les numéros de broches d'un Arduino Pro Mini 5V aux boutons d'une manette GameCube et établir le schéma de câblage suivant :


Une fois un câble de manette de remplacement acheté, restait alors le plus long à faire, câbler les broches sur le joystick.

  • Ici le brochage est réalisé à l'aide de connecteurs « maisons », qui permettront d'interchanger le joystick entre plusieurs systèmes de jeu (USB ou GameCube pour le moment).


  • Le brochage du câble de la manette est le suivant :
Couleur  −   Usage 

Jaune    −   5V
Blanc    −   GND
Vert     −   GND
Noir     −   GND
Bleu     −   3,3V
Rouge    −   DATA
  • Voici le Scketch à inscrire sur l'Arduino, en ayant pris soins de charger la librairie de NicoHood :

https://github.com/makotoworkshop/Joystick_Arcade_GameCube

#include <Nintendo.h>

// Variables
#define Bouton_A  A1
#define Bouton_B  9
#define Bouton_X  A2
#define Bouton_Y  3
#define Bouton_START  A3
#define Bouton_L  7
#define Bouton_R  8
#define Bouton_Z  2
#define Direction_UP  6
#define Direction_DOWN  5
#define Direction_LEFT  A0
#define Direction_RIGHT  4

// Broche de communication vers la console GameCube
CGamecubeConsole gc_console(10);

// Structure de données de la manette
Gamecube_Data_t gc_data = defaultGamecubeData;


void setup() {
//  Serial.begin(115200);
  // Configuration des boutons en entrée avec résistance pull-up
  pinMode(Bouton_A, INPUT_PULLUP);
  pinMode(Bouton_B, INPUT_PULLUP);
  pinMode(Bouton_X, INPUT_PULLUP);
  pinMode(Bouton_Y, INPUT_PULLUP);
  pinMode(Bouton_START, INPUT_PULLUP);
  pinMode(Bouton_L, INPUT_PULLUP);
  pinMode(Bouton_R, INPUT_PULLUP);
  pinMode(Bouton_Z, INPUT_PULLUP);
  pinMode(Direction_UP, INPUT_PULLUP);
  pinMode(Direction_DOWN, INPUT_PULLUP);
  pinMode(Direction_LEFT, INPUT_PULLUP);
  pinMode(Direction_RIGHT, INPUT_PULLUP);
  delay(100);
}

void loop() {
  // Lecture des boutons
  gc_data.report.a      = !digitalRead(Bouton_A);
  gc_data.report.b      = !digitalRead(Bouton_B);
  gc_data.report.x      = !digitalRead(Bouton_X);
  gc_data.report.y      = !digitalRead(Bouton_Y);
  gc_data.report.start  = !digitalRead(Bouton_START);
  gc_data.report.z      = !digitalRead(Bouton_Z);
  gc_data.report.l      = !digitalRead(Bouton_L);
  gc_data.report.r      = !digitalRead(Bouton_R);

  gc_data.report.dup    = !digitalRead(Direction_UP);
  gc_data.report.ddown  = !digitalRead(Direction_DOWN);
  gc_data.report.dleft  = !digitalRead(Direction_LEFT);
  gc_data.report.dright = !digitalRead(Direction_RIGHT);

  // Stick analogique centré
  gc_data.report.xAxis = 128;
  gc_data.report.yAxis = 128;

  // Stick C centré
  gc_data.report.cxAxis = 128;
  gc_data.report.cyAxis = 128;

  // Gâchettes analogiques à 0
  gc_data.report.left = 0;
  gc_data.report.right = 0;

  // Envoi du rapport à la console de jeux
  gc_console.write(gc_data);

//  Serial.print("bouton Y = ");
//  Serial.println(gc_data.report.y);
  
}

samedi, 15 novembre 2025

RecalStick -2-

Suite de la création précédent :

Perçage de la ventilation :

Étant donné que le Raspberry pi 4 va chauffer à l'intérieur du boîtier, j'ai pratiqué deux trous de Ø30 mm sur les bords droit et gauche de celui-ci, afin de pouvoir disposer deux ventilateurs.

  • J'ai dû désaxer la perceuse à colonne car il n'y avait pas suffisamment de place pour cela.



Fixation du Raspberry pi 4 :

Comme évoqué lors de l'épisode précédent, il est malheureusement nécessaire de modifier le boîtier pour permettre au µ-Ordinateur de rentrer en place.

  • L'opération consiste à déplacer l'ouverture sur la droite, donc à élargir la découpe à droite.


  • Ensuite il faut coller une « rustine » dans le trou laissé à gauche, que j'ai préparé pour faciliter l'opération.

  • Une fois la rustine sculptée au ciseau, on peut présenter le Rpi :


  • J'ai collé deux cales d'épaisseurs pour faire reposer le boîtier/dissipateur thermique du Rpi sans gêner les ventilateurs qui s'exprimeront sur le dessous.


Comme le boîtier du Rpi est en butée dans la gorge de la façade, un bloc vissé à l'opposé suffit à le bloquer un place, pas besoin de chercher plus compliqué.

Câblage :

  • Sur la lamelle métallique nous avons trois connecteurs. La rallonge VGA, qu'il suffit d'aller brancher sur le VGA666 du Raspberry. La prise Jack d'alimentation, et la prise Jack stéréo pour la sortie sonore.


Sur la prise Jack d'alimentation, j'ai soudé quatre paires de fils − rouges et noirs −, trois équipés de connecteurs JST mâles qui recevront les JST femelles des ventilateurs et un pour alimenter le Raspberry en les soudants directement sur les pastilles adéquates du bus GPIO.
Sur la prise Jack stéréo, sont soudés trois fils − vert, blanc et noir − qui sont eux aussi directement soudés au dos du Rpi. Je réalise malheureusement que je n'en ai pas pris de photos.

Lire la suite...

lundi, 3 novembre 2025

Décapotes -02-, circuit de positionnement d'image pour écran TV

Suite de la conception précédente :

Le premier circuit ayant donc montré ses limites et défauts, nous allons ici tenter de les corriger.

Un deuxième circuit d'essais :

  • À force d'expérimentations, j'ai fini par aboutir à ce schéma :


Ce circuit fonctionne relativement bien, mais avant de tirer les conclusions (oui je ne suis pas un politique ou un journaleux qui tire les conséquences, faut arrêter avec ça !), regardons comment il fonctionne, car encore une fois, ce sera salutaire pour la suite à donner.

  • Nous avons donc à nouveau l'étage de séparation de synchro basé sur le circuit intégré LM1881, nécessaire pour récupérer le signal V−Sync.

Cet étage est cette fois connecté à des PLL (boucle à verrouillage de phase) CD4046, le type de montage à système bouclé dont la théorie me donnait des sueurs froides à l'école… Mais bon c'est plus facile à expérimenter… un peu.

  • La PLL est ici employée afin de générer un signal carré d'une fréquence égale au signal d'entrée. Une fois la fréquence « accrochée » par le VCO (oscillateur contrôlé en tension), led témoin allumée par l'entremise du potentiomètre, ce système bouclé va nous permettre de déphaser le signal carré en continuant de jouer du potentiomètre. La limite étant le décrochage du VCO au delà d'une certaine plage de fonctionnement où l'on perd alors la fréquence.

Les composants R1, R2 et C1 sont donc calculés et vérifiés expérimentalement pour offrir la plage de fonctionnement la plus large possible sans décrocher de la fréquence d'entrée.
Pour H−Sync et ses 15,625 kHz, R1 = 100 kΩ, R2 = 100 kΩ, C1 = 1 nF.
Pour V−Sync et ses 59 Hz, R1 = 8,2 kΩ, R2 = 18 kΩ, C1 = 1 µF.

  • Voici une démo vidéo de la phase d'accrochage de la PLL, avec le signal zoomé sur V−Sync, on regarde la sortie 3 du CD4046.

On prend soin d'observer attentivement la valeur de fréquence affichée en bleu sur l'oscilloscope, ainsi que la réaction de la led.

  • La sortie de chaque PLL est ensuite envoyé à un monostable, pour, comme nous l'avons étudié précédemment, générer une impulsion de largeur fixée grâce au potentiomètre associé.

Voyons cela avec des oscillogrammes :

  • Ici nous voyons le déphasage obtenu pour H−Sync. Le signal C−Sync (en jaune), la sortie 3 de la PLL (en bleu), et la sortie Q7 du monostable (en vert) qui déclenche son impulsion sur le front montant du signal de sortie du CD4046.


  • Et de la même manière, nous voyons le déphasage obtenu pour V−Sync. Le signal V−Sync (en jaune), la sortie 3 de la PLL (en bleu), et la sortie Q9 du monostable (en vert).


Lire la suite...

- page 1 de 39