émuler un clavier avec n’importe quel Arduino

Suite à un jeu un peu gourmand en touche ( Elite Dangerous, pour ne pas le nommer ), j’ai voulu monter une console pour effectuer certaines actions. j’ai d’abords fait un hack clavier avec une vielle carte de clavier ( Je ne vais pas rentrer dans les détails )
chose qui fonctionne très bien, mais certaines actions demande une série d’action qui reste plus simple à faire au clavier qu’avec un hotas.

L’idée de l’Arduino pour faire ces actions est en soit une bonne idée, sauf que seul certains Arduino ( Leonardo entre autre) acceptent d’être considéré comme un clavier du côté du PC.

Pour contourner le problème, j’ai donc trouvé une astuce toute simple :

créer un script python pour lire le port com du pc ( où est branché l’Arduino ) et de le transcrire en commande clavier ( ou série de commande ) qui peu servir à n’importe quel jeu pour effectuer des commandes ( Starcraft… )

Exemple de Code Arduino

void setup() {

// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(2, INPUT);
}

void loop() {
// envoie un ‘a’ sur le port com si le bouton est activé
if ( digitalRead(2) == 1) Serial.print(‘a’);
/// un peu de delay pour éviter que ça n’en envoie trop rapidement.
delay(250);

}

préparation python

pip install pyautogui
pip install pyserial

code python

import pyautogui
import serial
import time

serial_port = serial.Serial(port=’COM3′, baudrate=9600)

i=0

def land():
pyautogui.press([‘1’, ‘e’, ‘e’,’s’,’space’])

def jump():
pyautogui.press([‘j’])

def frontassist():
pyautogui.press([‘+’])

options = {‘a’ : land,
4 : jump,
2 : frontassist,
}

while i < 1000:
lecture = serial_port.read()
transcript = lecture.decode(‘utf-8’)
options[transcript]()
time.sleep(0.35)
i=i+1

la liste des touches disponibles pour python

https://pyautogui.readthedocs.io/en/latest/keyboard.html#the-typewrite-function

Le montage des boutons reste classique à tout projet Arduino ^^

Edit  :  j’ai mis à jour les programmes et ça marche très bien, malheureusement, ça ne fonctionne pas sur certains jeux ( semble t’il à cause de directX )

la version  arduino pour x boutons en y lignes ( l’exemple ici avec 2*4 boutons ( inspiration d’openclassroom )

float r1=1000.0; // valeur pour R1

float r2=1000.0; // valeur pour R2

float p=15.0; // pourcentage d’erreur

float ue=5000.0; // tension d’entrée en mV

const int nbBoutons=4; // nombre de boutons
const int nblignes=2; // nombres de lignes

int valeurs[nbBoutons]; // tableau de stockage des valeurs basses
int val[nblignes];
int bouton;

void setup() {

Serial.begin(9600);//communication série

//Serial.println(« ************* »);

for (int t=0;t<nbBoutons;t++){

float pr2=r2*p/100; //valeur du pourcentage

float usmin=(r1/(r1+t*(r2+pr2)))*ue; // valeur sortie min

valeurs[t]=map (int(usmin),0,5000,0,1023); //ajout d’une valeur

}

}

void loop() {

// lecture des CAN
for (int t=0;t<nblignes;t++) {
val[t]=analogRead(t); // lecture du CAN t
// Serial.print (t);
// Serial.print (« :  » );
// Serial.print (val[t]);
//Serial.println ( » « );
}

for (int line=0;line<nblignes;line++)
{
if (val[line]){ // si différent de 0

for (int t=0;t<nbBoutons;t++)
{ // parcours des valeurs

if (val[line]>=valeurs[t])
{ //test si supérieur à valeur concernée

// affichage
bouton = t+(line*nbBoutons) ;
// Serial.print (« Bouton « );

//Serial.println (val[t]);
Serial.print (bouton);
// Serial.print ( » « );

// Serial.println ( » down »);

break; //sortie de boucle

}

}

}
}
delay (250);
}

et le code pyhon

 

import pyautogui
import serial
import time

serial_port = serial.Serial(port=’COM3′, baudrate=9600)

i=0

def radar():
pyautogui.press([‘j’])

def land():
pyautogui.press([‘1’, ‘e’, ‘e’,’s’,’space’])

def jump():
pyautogui.typewrite([‘z’])

def frontassist():
pyautogui.press([‘^’])

def system():
pyautogui.press([‘4’])

def nebula():
pyautogui.press([‘l’])

def ghost():
pyautogui.press([‘x’])

def cme():
pyautogui.press([‘p’])

options = {
‘0’ : jump,
‘1’ : frontassist,
‘2’ : radar,
‘3’ : land,
‘4’ : system,
‘5’ : nebula,
‘6’ : ghost,
‘7’ : cme,
}

while i < 1000:
lecture = serial_port.read()
transcript = lecture.decode(‘utf-8’)
options[transcript]()
time.sleep(0.25)
i=i+1

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.