Avec le FabLab UtoPi, nous travaillons sur un projet de souris adaptée pour personnes handicapées. En fait, partant d’un projet « simple » on s’aperçoit que l’adaptation est bien plus complexe qu’il n’y parait. Pour un gamer nous voulons adapter une manette de jeu PS4. La première étape consiste à comprendre comment cela fonctionne, et donc à procéder à un démontage pour identifier les composants, le montage, la façon dont les boutons sont reliés etc. Je me suis dit que la démarche pouvait intéresser certains lecteurs. Voici donc la découverte du contenu d’une manette vendue sur Amazon (lien affilié).
Au sommaire :
- 1 Une manette PS4 sur PC – Démontage, utilisation
- 2 Remontage
- 3 Un test en python
- 4 Installation de touches tactile
- 5 Sources
Une manette PS4 sur PC – Démontage, utilisation
C’est cette manette Laazii que j’ai retenue pour les essais car compatible PS4 et PC, elle dispose d’une batterie LiPo et peut fonctionner sans fil. Sur PC elle fonctionne avec un câble micro USB => USB A fourni dans la boîte.
A la réception, le premier test a été de connecter la manette au PC pour m’assurer que tout fonctionnait correctement.
Le test d’une manette de jeu sous Windows
Dans Windows vous avez un testeur de Contrôleur de Jeu. Pour le lancer, tapez joy.cpl dans la fenêtre exécuter. Vous pouvez aussi taper « Contrôleur de jeu » dans la zone Recherche.
La fenêtre Contrôleurs de jeu s’ouvre. Si votre manette est connectée via son câble USB et fonctionne, elle doit apparaître et la LED entre les deux joysticks s’allume. Sur cette manette elle « respire » en jaune (vert ? je suis daltonien).
Cliquez sur le bouton Propriétés et la fenêtre Tester vous montre les actions que vous effectuez sur la manette. Il y a 14 boutons, la position des axes et le contrôle point de vue.
J’ai noté sur ce schéma quels boutons ou axes sont activés. Quand on appuie sur le joystick on actionne les boutons 11 et 12. Le 13 est le bouton HOME, le PAD actionne le bouton 14. On peut voir que tous les boutons (les 14) sont utilisés. Les deux palettes L2 et R2, en bas à droite et à gauche actionnent les boutons 7 et 8 mais aussi les axes de rotation X et Y de façon analogique.
Notice de la manette PS4
Voici la notice en anglais de la manette. L’autre langue disponible étant le chinois, je vous en dispense… Vous pouvez cliquer sur les pages pour les agrandir.
Les tests d’une manette de jeu en ligne
Il existe un site pour tester votre manette en ligne : https://gamepad-tester.com/
Lorsque la manette est connectée et détectée (si elle ne l’est pas appuyez sur un bouton de la manette pour forcer la détection) vous avez un affichage de tous les boutons et joysticks et lorsque vous les actionnez, la vue sur la page web est mise en ligne. Attention sur Chrome et Edge vous avez un rappel des boutons en haut sous le nom de la manette et vous pouvez accéder au test de vibration (flèches rouges). c’est impossible sur Firefox (pour le moment).
Ici sur Firefox on voit que les boutons ne sont pas actifs et que les moteurs de vibration ne sont pas détectés.
Ces deux outils serviront quand on aura modifié/adapté la manette pour vérifier que tout est fonctionnel. Je vous invite maintenant à démonter ce bazar pour voir ce qu’elle a dans le ventre.
Démontage de la manette PS4
Présentation de la manette
La manette est livrée avec un câble USB qui permet de fonctionner en filaire, en particulier sur PC.
Deux poignées antidérapantes facilitent la prise en main. Au centre de la tablette on voit un PAD tactile, sous lequel une barre blanche dissimule la LED qui indique la mise en route de la manette et par sa couleur indique quel numéro de joueur a été attribué à la manette.
Les boutons 1 et 2 à l’avant de la manette. La palette 2 de chaque côté fonctionne de façon numérique, comme un bouton, mais aussi de façon analogique.
Vue côté des poignées. La prise de casque est située entre les joysticks (flèche blanche).
En bout de la poignée antidérapante une vis fixe la poignée sur la manette.
Vue de dessous. Deux trous renferment les vis de montage de la manette. Le trou indiqué par une flèche blanche donne accès au bouton poussoir de RESET de la manette. Vous pourrez utiliser un cylindre de petite taille (trombone déplié par exemple).
Démontage des poignées
Les deux poignées antidérapantes sont démontées.
Démontage du boîtier
Sous la manette on a maintenant accès aux 4 vis qui permettent de démonter la manette.
Deux des vis de montage de la manette.
Ouverture du boîtier
Une fois ouverte (avec précaution) on peut séparer la partie inférieure et la parte haute de la manette. La partie haute comporte l’ensemble des composants actifs : carte mère et batterie 3.7v/600mAH, boutons et joysticks, moteurs de vibration.
La batterie LiPo est chargée par la carte. Elle semble comporter un BMS (Battery Management System = Système de gestion de la batterie) monté sur le dessus de la batterie.
Les palettes marquées 2 à l’avant de la manette comportent un ressort de rappel (flèche blanche) qu’il conviendra de replacer correctement au remontage pour conserver le fonctionnement d’origine.
Sur cette photo on voit les deux moteurs de vibration (avec des masselottes différentes). En haut à droite le câble plat (câble en nappe) connecte le PAD tactile. En haut à gauche de la batterie le bouton poussoir RESET. En bas au centre le connecteur Jack sur lequel on branchera le casque audio.
Les deux moteurs sont simplement coincés avec une mousse rigide. Celui de gauche a une masselotte composée de 2 plaques, celui de droite a 4 plaques. La dissymétrie des plaques provoque une vibration. C’est le même principe que les vibreurs de téléphone ou de tablette… en plus gros !
Les boutons à l’avant R1 et L1 sont formés de deux demi cercles en carbone. Quand on appuie sur le bouton la capsule en silicone s’écrase et la pastille de carbone conducteur vient établir le contact entre les deux demi-cercles. Tous les boutons de la manette sont faits de cette manière.
Les palette R2 et L2 sont différentes, le capteur a une forme de peigne et et la réponse est proportionnelle à l’appui sur la palette. A priori le circuit imprimé est vernis (vernis vert) et il se peut que la détection du plot en carbone soit capacitive… A vérifier
Carte mère
Sur ce gros plan de la carte mère avant démontage de la batterie, vous retrouvez les éléments présentés précédemment.
La batterie est collée avec une sorte de mousse double face. Décollez la sans utiliser d’outil métallique et sans exercer de force au niveau de la batterie. Les LiPo sont sensibles et dangereuses…
Une fois la batterie démontée, vous trouvez les 2 vis (flèches blanches) qui fixent la carte mère à la partie supérieure de la manette et en même temps garantissent un contact efficace au connecteur qui relie la carte mère aux boutons poussoirs de la manette. La flèche jaune correspond au bouton poussoir de RESET. D’après le schéma (voir plus loin dans l’article) U3 qui n’est pas sur la carte serait le gyroscope/accéléromètre. Effectivement cette manette n’envoie pas d’informations quand on la tourne physiquement.
J’ai un peu de mal à identifier le circuit intégré U8. Ça semble être un MP01010.
Démontage de la carte mère
Une fois la carte mère enlevée on voit le câble plat du PAD tactile (flèche jaune), le connecteur qui relie la carte aux boutons poussoirs des deux croix (flèche bleue) et l’arrivée des fils venant des boutons poussoirs (flèche blanche).
De ce côté de la carte mère, on trouve les deux joysticks soudés directement sur la carte. En bas de la carte le bouton poussoir blanc (au dessus de la micro USB) est le bouton qui est déclenché quand on appuie sur le PAD tactile. De chaque côté on trouve les poussoirs SHARE et OPTIONS (coupelles dorées). Au centre de la carte le connecteur assure la liaison avec le circuit souple de liaison aux boutons poussoirs. Au dessus de ce connecteur on trouve la LED RGB et encore plus haut le bouton HOME marqué PS1.
Gros plan sur la nappe du PAD tactile. On voit aussi la coupelle du bouton SHARE, monté sur la carte.
En gros plan ici le bouton poussoir situé sous le PAD tactile, le connecteur avec ses pastille en carbone et en haut de l’image, la LED RGB.
U5 semble être le CI qui gère les boutons.
Les boutons poussoirs
On enlève la plaque supportant les contacts des boutons poussoirs.
On découvre alors la partie supérieure de la manette. Le PAD tactile (en haut) est encore en place et relié à la carte mère par une nappe. De chaque côté une croix en silicone supporte les contacts pour les boutons.
Ici le PAD tactile est enlevé. Au centre entre les trous des joysticks, le poussoir HOME et juste au dessus la barre translucide qui est éclairée par la LED RGB.
Les boutons poussoirs
La plaque des boutons poussoirs comporte un circuit imprimé transparent et souple. Ce circuit intègre le connecteur qui va envoyer les signaux à la carte mère.
Ces deux photos montrent le connecteur des boutons poussoirs. Juste au dessus les deux barres arrondies servent de ressort quand on appuie sur le PAD tactile pour appuyer sur son bouton.
Ici une vue d’ensemble du circuit imprimé souple. De chaque côté les 4 contacts des deux croix. Si on suit les pistes, on voit qu’il y a une piste commune à tous les boutons poussoirs et que l’autre côté est relié directement au connecteur, donc au circuit de gestion du clavier.
De ce côté on voit les demi-cercles de chaque bouton poussoir. La piste extérieure est connectée à chaque bouton. Le petit rectangle en carbone doit être une résistance utilisée avec la palette 2 qui fournit un signal analogique.
De l’autre côté on a le même montage avec la piste extérieure qui rejoint chacun des boutons poussoirs. Même remarque concernant le rectangle en carbone en bas à droite.
Le schéma
Merci Yves pour l’envoi de ce schéma de la manette PS4. Le modèle présenté ici n’est bien sûr pas exactement le même mais on peut repérer les éléments et comprendre comment le tout est organisé.
Ce que la manette envoie sur le port USB
En cherchant un peu on trouve des infos sur les données transmises par une manette PS4 à la console ou au PC. Le site https://www.psdevwiki.com par exemple fournit de nombreuses informations sur les données échangées.
Pour la manette PS4, on trouve les data qui devraient permettre d’analyser les échanges, c’est sans doute ce qu’un site comme https://gamepad-tester.com/ utilise pour analyser les actions effectuées sur la manette. Les données arrivent 250 fois par seconde (toutes les 4ms).
Remontage
Après remontage soigneux, la manette a retrouvé un fonctionnement normal (ouf). On va pouvoir commencer à envisager des modifications à partir de ce modèle.
J’ai mis ci-dessous quelques liens utilisés lors de ma découverte de cette manette. Je ne suis pas gamer et je découvre un peu cet environnement…
Un test en python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import pygame # Initialiser Pygame pygame.init() # Définir la taille de la fenêtre Pygame fenetre = pygame.display.set_mode((200, 200)) # Définir la manette PS4 en tant que dispositif d'entrée manette = pygame.joystick.Joystick(0) manette.init() # Boucle de jeu pour récupérer les données de la manette PS4 while True: for event in pygame.event.get(): if event.type == pygame.JOYAXISMOTION: # Récupérer les données de l'axe axe_x, axe_y = manette.get_axis(0), manette.get_axis(1) print("Axe X: {}, Axe Y: {}".format(axe_x, axe_y)) if event.type == pygame.JOYBUTTONDOWN: # Récupérer le bouton enfoncé bouton = event.button print("Bouton appuyé: {}".format(bouton)) |
Un programme de base qui ne prend pas en compte tous les capteurs mais permet au moins de dialoguer entre la manette et un prog Python (Python 3.11.3 et pygame 2.3.0). On obtient ce genre de sortie à la console :
ou celui ci qui fonctionne bien avec la manette et permet aussi d’activer la vibration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
import pygame pygame.init() # This is a simple class that will help us print to the screen. # It has nothing to do with the joysticks, just outputting the # information. class TextPrint: def __init__(self): self.reset() self.font = pygame.font.Font(None, 25) def tprint(self, screen, text): text_bitmap = self.font.render(text, True, (0, 0, 0)) screen.blit(text_bitmap, (self.x, self.y)) self.y += self.line_height def reset(self): self.x = 10 self.y = 10 self.line_height = 15 def indent(self): self.x += 10 def unindent(self): self.x -= 10 def main(): # Set the width and height of the screen (width, height), and name the window. screen = pygame.display.set_mode((500, 700)) pygame.display.set_caption("Joystick example") # Used to manage how fast the screen updates. clock = pygame.time.Clock() # Get ready to print. text_print = TextPrint() # This dict can be left as-is, since pygame will generate a # pygame.JOYDEVICEADDED event for every joystick connected # at the start of the program. joysticks = {} done = False while not done: # Event processing step. # Possible joystick events: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN, # JOYBUTTONUP, JOYHATMOTION, JOYDEVICEADDED, JOYDEVICEREMOVED for event in pygame.event.get(): if event.type == pygame.QUIT: done = True # Flag that we are done so we exit this loop. if event.type == pygame.JOYBUTTONDOWN: print("Joystick button pressed.") if event.button == 0: joystick = joysticks[event.instance_id] if joystick.rumble(0, 0.7, 500): print(f"Rumble effect played on joystick {event.instance_id}") if event.type == pygame.JOYBUTTONUP: print("Joystick button released.") # Handle hotplugging if event.type == pygame.JOYDEVICEADDED: # This event will be generated when the program starts for every # joystick, filling up the list without needing to create them manually. joy = pygame.joystick.Joystick(event.device_index) joysticks[joy.get_instance_id()] = joy print(f"Joystick {joy.get_instance_id()} connencted") if event.type == pygame.JOYDEVICEREMOVED: del joysticks[event.instance_id] print(f"Joystick {event.instance_id} disconnected") # Drawing step # First, clear the screen to white. Don't put other drawing commands # above this, or they will be erased with this command. screen.fill((255, 255, 255)) text_print.reset() # Get count of joysticks. joystick_count = pygame.joystick.get_count() text_print.tprint(screen, f"Number of joysticks: {joystick_count}") text_print.indent() # For each joystick: for joystick in joysticks.values(): jid = joystick.get_instance_id() text_print.tprint(screen, f"Joystick {jid}") text_print.indent() # Get the name from the OS for the controller/joystick. name = joystick.get_name() text_print.tprint(screen, f"Joystick name: {name}") guid = joystick.get_guid() text_print.tprint(screen, f"GUID: {guid}") power_level = joystick.get_power_level() text_print.tprint(screen, f"Joystick's power level: {power_level}") # Usually axis run in pairs, up/down for one, and left/right for # the other. Triggers count as axes. axes = joystick.get_numaxes() text_print.tprint(screen, f"Number of axes: {axes}") text_print.indent() for i in range(axes): axis = joystick.get_axis(i) text_print.tprint(screen, f"Axis {i} value: {axis:>6.3f}") text_print.unindent() buttons = joystick.get_numbuttons() text_print.tprint(screen, f"Number of buttons: {buttons}") text_print.indent() for i in range(buttons): button = joystick.get_button(i) text_print.tprint(screen, f"Button {i:>2} value: {button}") text_print.unindent() hats = joystick.get_numhats() text_print.tprint(screen, f"Number of hats: {hats}") text_print.indent() # Hat position. All or nothing for direction, not a float like # get_axis(). Position is a tuple of int values (x, y). for i in range(hats): hat = joystick.get_hat(i) text_print.tprint(screen, f"Hat {i} value: {str(hat)}") text_print.unindent() text_print.unindent() # Go ahead and update the screen with what we've drawn. pygame.display.flip() # Limit to 30 frames per second. clock.tick(30) if __name__ == "__main__": main() # If you forget this line, the program will 'hang' # on exit if running from IDLE. pygame.quit() |
On active la vibration en appuyant sur le bouton en bas de la croix de droite.
Installation de touches tactile
c’est Yves qui s’est chargé de l’opération avec un PIC16F1709 et des touches tactiles de récupération.
La manette comporte des points de connexion clairement identifiés (ici R1, R2, L1, L2) qui ont permis de raccorder les 4 sorties du OIC à la manette. L’alimentation du PIC est prélevée sur la manette également (VSS et VDD). Les 4 fils sortent de chaque côté de la prise USB sur le devant de la manette. Reste à Simon de placer les touches tactiles au mieux pour son utilisation. Ce n’est qu’un prototype, on fera évoluer en fonction des attentes de Simon.
Sources
Manette modulable – Projet Polytech
https://projets-ima.plil.fr/mediawiki/images/1/1d/P35_Manette_Modulable.pdf
Testeur de manette
https://gamepad-tester.com/
Programme JS de gestion de manette
https://dev.to/codingwithadam/how-to-use-js-gamepad-api-and-build-a-gamepad-tester-5em6
Tester une manette PS4
https://whatsabyte.com/how-can-i-test-ps4-controller/
Utiliser PyGame
https://blog.mclemon.org/python-using-a-dualshock-4-with-pygame
https://www.pygame.org/docs/ref/joystick.html
Ping : Une manette PS4 sur PC – Démontage, utilisation
Bonjour,
Il existe un programme open-source pour gérer les manettes de consoles.
Il s’agit de AntiMicroX :
https://github.com/AntiMicroX/antimicrox
Il est diponible pour Windows et Gnu-Linux.
Ludiquement vôtre.
À quand un tutoriel similaire pour une manette dualsense-like (PS5) ?
Ou un sur transformer sa manette micro-usb en manette USB type c ?
À suivre…