Recent Posts


Sim racing and game controllers - part 3 - Arduino leonardo project

The issue

I've posted these articles on the Arduino racing pad that I've built: part1, part2 and the video and problems. I've complained a bit on the fact that what I have done has only 8bits of information for the steering wheel. That should be enough for steering, but when driving straight in LFS, you could see that the steering wheel "jumps" between positions. 8bits of information is 256 possible positions of the wheel and when you get 270 degrees of rotation on a potentiometer, that is visible - you cannot turn the wheel by a half of a degree.

My third kid started sleeping better, so now I have bits of time here and there to play around with toys. After a beer or two I've said to my self "8bits steering improvement - how hard can it be?".

The ingredients

Back then, one year ago, you needed to copy the custom HID.cpp and USBAPI.h files into the Arduino IDE libraries to get the Joystick definition. Now you don't have to. Arduino 1.6.8 IDE allows for libraries to be added and guy named Nico prepared marvelous library called Arduino HID Project 2.4.3. This library contains Gamepad definition with 32 buttons, 2 dpads, 4 16bit axis and 2 8bit axis.

So I've used:
  • Arduino Leonardo with the tupperware racing pad I've build in the previous posts, 
  • Arduino IDE 1.6.8,
  • Arduino HID Project 2.4.3,
  • moderate amount of alcohol.

The solution

The new Arduino HID project makes it very tidy and simple to set up the controler I needed. The code for the Arduino Sketch is given below. When someone will try to copy and play with that, be sure to check which axis has how many bits. X, Y, RX, RY are 16bits, Z and RZ are 8bits.

The Arduino HID needs to be downloaded and copied into the libraries directory of your Arduino IDE installation. I'm sure there are other places you can put it in, but I guess I'm too lazy :)

The results

Now I've got all axis on 16 bits. Arduino Leonardo A/D has 10 bits resolution, so that is an overkill. The USB device is 64 times more precise than what Arduino can return, but it does not matter. I got what I needed on a very simple set of libraries. Now when I turn the wheel knob everything is super smooth. 

Now the only thing keeping me from winning every LFS game is my set of mediocre virtual driving skills.

Next improvement - some other mechanical potentiometers for the throttle and brakes.

The Code

#include "HID-Project.h"

const int pinLed = LED_BUILTIN;
const int pinButton = 2;

void setup() {
  pinMode(pinLed, OUTPUT);
  pinMode(pinButton, INPUT_PULLUP);

void loop() {
  float steeringmin=0;
  float steeringmax=1023;
  float brakemin=0;
  float brakemax=1023;
  float accelmax=1023;
  float accelmin=0;
  float min=-32767;
  float max=32767;
  float diff=max-min;

  float steer = (float)analogRead(0)/(steeringmax-steeringmin)*diff + min;
  float accel = ((float)analogRead(2)/(accelmax-accelmin))*diff + min;
  float brake = ((float)analogRead(1)/(brakemax-brakemin))*diff + min;
  // on second thought, I just could have multiplied one thing by 64 to get the result
  int gearup = digitalRead(2);
  int geardown = digitalRead(3);
  if ((accel <= 3) and (accel >= -3)) {
  if ((brake <= 3) and (brake >= -3)) {

 if (gearup == 0)
 } else {

 if (geardown == 0)
 } else {

 // zAxis is 8bit, I wanted to use 16bits on all