まこと の ブログ

MaKoTo no burogu — Journal de bord…

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

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

mercredi, 10 septembre 2025

IQS−PGM - Labels pour cartouche de jeu DIY

Suite de l'aventure précédente :
Parlons étiquettes !

Quelques personnes ont réalisés des scans et partagés des créations originales d'étiquettes sur les forums que j'ai visité pour construire tout ça.
Il y a des étiquettes à coller sur les EEPROMS et des étiquettes de tranche de cartouche pour identifier les jeux.

  • J'ai rassemblé toutes celles qui me plaisaient bien pour en faire une planche A4 (en annexe à ce billet), imprimée sur un papier spécial étiquette.

L'encre est censée résister aux rayures sur ce papier, mais j'ai pu constater sur les petites étiquettes que ce n'était pas si évident. J'ai donc apposé un film transparent autocollant sur les étiquettes de tranche afin de les protéger. Quant aux petites, il était trop tard pour cela.

  • J'en ai aussi imprimé sur papier standard pour évaluation, en les disposants ainsi sans collage, car je ne parviens pas à me décider ^^;



Je vous laisse avec une galerie de photo des cartouches, qui montre un peu comment elles sont construites.

  • ESPGaluda :



  • Dodonpachi Dai-ou-jou :



  • Ketsui :



- page 2 de 176 -