Recent Posts

Pokazywanie postów oznaczonych etykietą arduino. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą arduino. Pokaż wszystkie posty

2016-04-15

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);
  Gamepad.begin();
}

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)) {
    accel=0;
  }
  if ((brake <= 3) and (brake >= -3)) {
    brake=0;
  }



 
 if (gearup == 0)
 {
   Gamepad.press(1);
 } else {
   Gamepad.release(1);
 }

 if (geardown == 0)
 {
   Gamepad.press(2);
 } else {
   Gamepad.release(2);
 }
 Gamepad.xAxis((int)steer);
 Gamepad.yAxis((int)accel);
 Gamepad.rxAxis((int)brake);
 Gamepad.write();

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

}

2015-06-16

My first Arduino racing pad - video and conclusions

Hi!

For future reference, check out the video with the Arduino racing pad, that I've built here: http://jakkul.blogspot.com/2015/06/sim-racing-and-game-controllers-part-2_3.html

My first Arduino racing pad in full glory!


There are some problems with the design that need working on:
  • The ergonomics are not the best. It's hard to use one hand for acceleration, brakes and gears.
  • I think, that 8bits of data fed by Arduino to the PC for steering are not enough.
  • You cannot drink beer while driving. Two hands need to be always on the pad. This is not the case when driving with a mouse or a wheel.
  • The gaming-pad-like joysticks are crap. About half of the axis travel is analogue, the rest is in full on state. 
I have some ideas for the next design. But I guess that will have to wait until autumn, since my 3rd kid is due to be born within next 2-3 weeks :)

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();
}

2015-05-26

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

So I've always dreamed about getting a steering wheel for my PC and playing LFS. There are three downfalls of this idea:
  • Its large - so hiding it from my better half will be hard.
  • Its noisy - force feedback on logitech g25/g27 and force GT wheels use some sort of gear that emits a noise while turning the wheel. So playing after my kids are asleep is a no-no. And I would wake up my wife.
  • I've got a wife, who would like me not have a steering wheel for my games. There is a term WAF in audio world - the Wife Acceptance Factor.
I even borrowed a Logitech G25 from a friend and didn't like it for one more reason: it lags. You can see, that the wheel in the game does not turn as fast as you do. It lags more than a mouse.

I like playing LFS with my mouse, but there are two issues:
  • You cannot gradually add power or brake, so handling more powerful cars than the GTI is difficult.
  • Hardly any other racing game provides mouse steering, and I hate driving with keyboard.
I've seen the HIMOTO simulator for getting to know how to drive RC cars. (link from rchobbystore.co.uk) But it's not available here in Poland.

I want a device that is small, can be placed on my desk, would have analog inputs for steering, gas and braking, would have some buttons. And I can't find any. Console pads with analog sticks don't cut it. The steering precision is faaaar from what you can get with a mouse or a cheap wheel. I can live without force feedback.

So I've googled for one hour and just ordered an Arduino Leonardo clone, two analogue sticks for accelerating and breaking, some switches and an analogue 10k linear potentiometer for steering.

Of course I could get an axis for hand brake and clutch and a hat switch and a .... but let's keep it simple, down to the absolute minimum that is needed to play LFS. If this runs, I'll develop later on. SCRUM MVP FTW! This is my first project of the kind anyway.

I will keep posting about the journey.