5.0 KiB
Executable File
author | pub_date | title | tags | uuid | ||
---|---|---|---|---|---|---|
Akbar Rahman | Tue, 04 Aug 2020 15:20:13 +0100 | Repurposing Racing Wheel Pedals |
|
0f09200e-fd50-451b-aae1-1117a8a704db |
Repurposing Racing Wheel Pedals
I have a Logitech G27 I don't use much. I wondered if I could use it for anything else. I could.
The Pinout of the Connector
The first thing I had to do was figure out what each pin did on the DE-9 connector, and which ones I should care about. This was done easily after I took off the top plastic casing thing by poking the three 100k Ohm potentiometers and the connector in the right places at the right times:
pin | function |
---|---|
1,4 | ground |
6 | clutch pedal |
7 | brake pedal |
8 | accelerator pedal |
9 | voltage in |
Reading the Values of the Pots
I'm using an Arduino to read the pots and then do something with the values. I very dirtily wired pin 4 on the pedals to GND on a Arduino Uno, pin 9 to 5V, and pins 6,7,8 to A0, A1, and A2. I used a basic sketch to check that everything is good:
Show/hide test_sketch.ino
void setup() { Serial.begin(9600); }
void loop() { Serial.println(analogRead(A2)); delay(20); }
I noticed that the minimum and maximum values read by the Uno were quite far off 0 and 1024, like they should be, and voltage was being lost on the way to and from the potentiometers. Since the pedals have to be calibrated every time you plug them in, I assume this is normal and spat out this code:
Show/hide sketch_aug02a.ino
// sensor pins int sa = A0; int sb = A1; int sc = A2;
// minimum values detected by the sensors int mina = 1025; int minb = 1025; int minc = 1025;
// maximum values detected by the sensors int maxa = 512; int maxb = 512; int maxc = 512;
// raw values of the sensors int rva, rvb, rvc;
// calculated values of the sensors (between 0 and 1, this is the value sent to computer) float cva, cvb, cvc;
void setup() { Serial.begin(9600); }
void loop() { rva = analogRead(sa); rvb = analogRead(sb); rvc = analogRead(sc);
if (rva < mina) mina = rva; if (rvb < minb) minb = rvb; if (rvc < minc) minc = rvc; if (rva > maxa) maxa = rva; if (rvb > maxb) maxb = rvb; if (rvc > maxc) maxc = rvc; cva = (float)(rva-mina)/(float)(maxa-mina); cvb = (float)(rvb-minb)/(float)(maxb-minb); cvc = (float)(rvc-minc)/(float)(maxc-minc); Serial.print('['); Serial.print(cva); Serial.print(','); Serial.print(cvb); Serial.print(','); Serial.print(cvc); Serial.print(']'); Serial.println(); delay(20);
}
Actually Making the Numbers Do Something
This is where you can make the pedals do fun things. I reworked another piece of code I wrote to do a similar thing to quickly create a script that reads the values sent by the Arduino, and then simulate pressing a key combination. The only thing I've done with this is set push-to-talk to ctrl-shift-alt-1. I don't know what else I could use this for, maybe temporarily muting particular things, like music.
Show/hide pedalboard.py
#!/usr/bin/env python3
import sys import json import time from enum import Enum
import keyboard import serial
class KeyState(Enum): UP = 0 DOWN = 1
STATES = [KeyState.UP] * 3 THRESHOLD = 0.8 MACROS = ['ctrl+shift+alt+1', 'ctrl+shift+alt+2', 'ctrl+shift+alt+3']
def get_args(): """ Get command line arguments """
import argparse parser = argparse.ArgumentParser() parser.add_argument('device') return parser.parse_args()
def main(args): """ Entry point for script """ while True: try: kb = serial.Serial(port=args.device, baudrate=9600) while True: handle(json.loads(kb.readline())) except serial.serialutil.SerialException as e: print(e) print("Failed to connect to device... trying again") time.sleep(1) except Exception as e: print(e) return 0
def handle(data): global STATES
states = [KeyState.DOWN if value > THRESHOLD else KeyState.UP for value in data] r = [handle_state_change(i, states[i]) if states[i] != STATES[i] else None for i in range(len(STATES))] STATES = states return r
def handle_state_change(key, newstate): print(f"{key} {newstate}") return keyboard.press(MACROS[key]) if newstate == KeyState.DOWN else keyboard.release(MACROS[key])
if name == 'main': try: sys.exit(main(get_args())) except KeyboardInterrupt: sys.exit(0)