Recent Posts

2015-06-03

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

I've written here about the need to build a customized pad-like controller for my racing games: http://jakkul.blogspot.com/2015/05/sim-racing-and-game-controllers-part-1.html Now I've managed to find 3 hours yesterday to put the thing together. But lets start from the beginning.


The Plan

The goal is to have the right hand operate the steering wheel potentiometer, the left hand's index and middle finger to operate accelerator and brakes, left thumb to operate gears up and down. After a long debate I came up with this:


The Plan

The ingredients

The thing that looked the most like the case for the device was a tupperware-like food container. It's also easily available, easy to drill and put things on and has a low low price of zero.

I also bought:
  • Arduino Leonardo (clone I guess),
  • two thumb joysticks,
  • four buttons (two used),
  • one linear 10k potentiometer,
  • some cables.

The stuff

Building

Building was a fun and easy part. I've screwed everything to the container, made a hole for cabling and connected together.


 Connecting it all was easy:
  • 5V and ground everywhere,
  • digital pins 2 and 3 to the gear switches,
  • X axis of the thumb joysticks (both) to analog lines 1 and 2,
  • potentiometer to analog line 0.
I haven't connected the rest of the stuff available in the joysticks - that was not needed.




Starting up

I've used the following excellent howto on how to get Arduino Leonardo to behave like a Joystick: http://www.instructables.com/id/Add-USB-Game-Controller-to-Arduino-LeonardoMicro/?ALLSTEPS. This is also very helpful: http://www.imaginaryindustries.com/blog/?p=80&cpage=1. There are two files that you need to get into your Arduino IDE environment (HID.cpp and USBAPI.h) that define the Joystick, that is not defined in Arduino IDE standard distribution.

I've used Arduino IDE 1.6.4 and Windows 7 64bit. I'm a linux addict, but since this is to be used in racing games, I wanted to test it straight away.

The step 2 of the howto mentioned above provides a test sketch (Arduino program) that allows for the arduino board to send signals as a joystick to your PC. The code that I've made basing on that and other examples in the net is presented below. You can switch displaying all values on COM port for double checking if it works. You can also tune your potentiometers and joysticks using max-min ranges. Keep in mind, that Arduino reads potentiometers and joysticks, returning and integer ranging from 0 to 1023, and the Joystick class requires the values to be between -127 and 127 for each axis.

Summary

It just works! I can now play my racing games with a full analogue controller without the hassle of a steering wheel. It's a different kind of fun, but still fun :)

The code

int useserial = 1;

float steeringmin = 0;
float steeringmax = 1023;
float brakemin = 501; //0;
float brakemax = 1023;
float accelmax = 1023;
float accelmin = 520; //0;
// 0 steer 1 brake 2 accel
float min = -127;
float max = 127;
float diff = max - min;

void setup() {
  Joystick.begin();
  if (useserial == 1 )
  {
    Serial.begin(9600);
  }
}

void loop() {

  float steer = (max - min) / (steeringmax - steeringmin) * ((float)analogRead(0) - steeringmin) + min;
  float accel = (max - min) / (accelmax - accelmin) * ((float)analogRead(2) - accelmin) + min;
  float brake = (max - min) / (brakemax - brakemin) * ((float)analogRead(1) - brakemin) + min;
  int gearup = digitalRead(2);
  int geardown = digitalRead(3);

  if (steer > max) {
    steer = max;
  }
  if (steer < min) {
    steer = min;
  }
  if (accel > max) {
    accel = max;
  }
  if (accel < min) {
    accel = min;
  }
  if (brake < min) {
    brake = min;
  }
  if (brake > max) {
    brake = max;
  }

  if (useserial == 1 )
  {

    Serial.print ((int)steer);
    Serial.print (' ');
    Serial.print (analogRead(0));
    Serial.print (' ');
    Serial.print (accel);
    Serial.print (' ');
    Serial.print (analogRead(2));
    Serial.print (' ');
    Serial.print (brake); Serial.print (' ');
    Serial.print (analogRead(1));
    Serial.print (' ');
    Serial.print (gearup);
    Serial.print (' ');
    Serial.println (geardown);
  }
  if (gearup == 0)
  {
    Joystick.pressButton(0);
  } else {
    Joystick.releaseButton(0);
  }

  if (geardown == 0)
  {
    Joystick.pressButton(1);
  } else {
    Joystick.releaseButton(1);
  }
  Joystick.setXAxis((int)steer);
  Joystick.setYAxis((int)accel);
  Joystick.setZAxis((int)brake);
  Joystick.sendState();
}

0 komentarze:

Prześlij komentarz