Main > Driving & Racing Cabinets

Maximum Tune 3 (WMMT 3DX) - Cab Conversion Help

<< < (5/5)

Vee21:

--- Quote from: PL1 on November 16, 2021, 03:07:43 am ---Looks like a solid start on the "truth table" approach.   :cheers:

You may want to find the answers to these questions before you proceed too much further.

1. What type of input does Teknoparrot/MAME and the game(s) you plan to use need from the shifter?
- One button for each gear 1-6, but none for Neutral?
- One button for each gear 1-6 and a button for Neutral?
- A sequential shifter input?

2. Do the emulators/games you plan to use care if the shifter sends gamepad button presses or keystrokes?
- Some games only allow inputs from a single device.

3. Do the emulators/games you plan to use care if gamepad outputs are dinput or xinput?


Scott

--- End quote ---

Thanks!

1) The games I want to play are all in Tekoparrot - WMMT, Initial D, Sega Racing Classics and Battle Gear. Some of these games require a Up/Down style shifter so I'm going to have to try figure something out for that, would you guys have any ideas?

2) Teknoparrot seems to be ok with gamepad inputs and/or keyboard inputs.

3) I've currently got Teknoparrot configured to use direct input which seems to be working fine.

I have the first complete working draft code which incorporates the Steering Wheel, Brake/Accel, View/Mode buttons and the 6 Speed Shifter!  :cheers:
I tested it out on WMMT on Teknoparrot, its basic and not efficient but seems to do the job everything seems to be working as it should.

Still can't believe its all working!  :laugh: thanks again for the help.

Here is the complete code for anyone interested. If anyone is reading this and has some ideas to make the code more efficient please share!


--- Code: ---#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS,
8, 0,                  // Button Count, Hat Switch Count
false, false, false,    // X, Y, Z Axis
false, false, false,   //Rx, Ry, Rz
false, false,          //rudder, throttle
true, true, true);   //accelerator, brake, steering

//Setup steering, brake and accel pins
const int steerPin = A0;
const int brakePin = A1;
const int accelPin = A2;
//Setup Shifter pins
const int bluePin = 10;
const int yellowPin = 11;
const int brownPin = 12;
const int greenPin = 13;
//Setup Mode and View pins
const int modePin = 7;
const int viewPin = 8;
//Setup Values
int steerValue;
int brakeValue;
int accelValue;


void setup() {

//Initialise button pins
pinMode(7, INPUT_PULLUP); //Mode
pinMode(8, INPUT_PULLUP); //View
pinMode(10, INPUT_PULLUP); //Shifter (Blue)
pinMode(11, INPUT_PULLUP); //Shifter (Yellow)
pinMode(12, INPUT_PULLUP); //Shifter (Brown)
pinMode(13, INPUT_PULLUP); //Shifter (Green)

//Setup buttons - Mode, View, Gears 1-6
Joystick.setButton(0, 0);
Joystick.setButton(1, 0);
Joystick.setButton(2, 0);
Joystick.setButton(3, 0);
Joystick.setButton(4, 0);
Joystick.setButton(5, 0);
Joystick.setButton(6, 0);
Joystick.setButton(7, 0);

//Steering Options - X Axis or Steering
//Joystick.setXAxisRange(0, 1023); //Steering Wheel - Joystick.setXAxisRange(min, max);
Joystick.setSteeringRange(0, 960);

//Brake Options - Y Axis or Brake
//Joystick.setYAxisRange(0, 1023); //Brake Pedal - Joystick.setYAxisRange(min, max);
Joystick.setBrakeRange(400, 767);

//Accelerator Options - Z Axis or Acceleratro
//Joystick.setZAxisRange(0, 1023); //Accel Pedal - Joystick.setZAxisRange(min, max);
Joystick.setAcceleratorRange(490, 915);

//Start Joystick
Joystick.begin();
}

//Start loop
void loop() {
  BrakePedal();
  SteerWheel();
  AccelPedal();
  ReadButtons();
  ReadShifter();
}

void SteerWheel(){
  steerValue = analogRead(steerPin);
  //Joystick.setXAxis(steerValue);
  Joystick.setSteering(steerValue);
  delay(1);
}

void BrakePedal(){
  brakeValue = analogRead(brakePin);
  //Joystick.setYAxis(brakeValue);
  Joystick.setBrake(brakeValue);
  Serial.println(brakeValue); // Testing analog input
  delay(1);
}

void AccelPedal(){
  accelValue = analogRead(accelPin);
  //Joystick.setZAxis(accelValue);
  Joystick.setAccelerator(accelValue);
  delay(1);
}

void ReadButtons(){
 
  //Set state of buttons
  int modePinState = digitalRead(modePin);
  int viewPinState = digitalRead(viewPin);

  if(modePinState == 1 ) {
    Joystick.setButton(0, 0);
  }
  else {
    Joystick.setButton(0, 1);
  }

  if(viewPinState == 1) {
    Joystick.setButton(1, 0);
  }
  else{
    Joystick.setButton(1, 1);
  }

  delay(50);
}

void ReadShifter(){
 
  //Set state of Shifter Gear
  int bluePinState = digitalRead(bluePin);
  int yellowPinState = digitalRead(yellowPin);
  int brownPinState = digitalRead(brownPin);
  int greenPinState = digitalRead(greenPin);

  //Neutral
  if(bluePinState == 1 && yellowPinState == 1 && brownPinState == 1 && greenPinState == 1) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 0);
  }
 
  //Gear 6
  if(bluePinState == 0 && yellowPinState == 1 && brownPinState == 0 && greenPinState == 1) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 1);
  }
 
  //Gear 5
  if(bluePinState == 1 && yellowPinState == 1 && brownPinState == 0 && greenPinState == 0) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 1);
    Joystick.setButton(7, 0);
  }

  //Gear 4
  if(bluePinState == 0 && yellowPinState == 1 && brownPinState == 1 && greenPinState == 1) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 1);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 0);
  }

  //Gear 3
  if(bluePinState == 1 && yellowPinState == 1 && brownPinState == 1 && greenPinState == 0) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 1);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 0);
  }

  //Gear 2
  if(bluePinState == 0 && yellowPinState == 0 && brownPinState == 1 && greenPinState == 1) {
    Joystick.setButton(2, 0);
    Joystick.setButton(3, 1);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 0);
  }

  //Gear 1
  if(bluePinState == 1 && yellowPinState == 0 && brownPinState == 1 && greenPinState == 0) {
    Joystick.setButton(2, 1);
    Joystick.setButton(3, 0);
    Joystick.setButton(4, 0);
    Joystick.setButton(5, 0);
    Joystick.setButton(6, 0);
    Joystick.setButton(7, 0);
  }
  delay(50);
}
--- End code ---


The next step for me is cleaning up the cab and putting it all back together, then I'll look into sequential style gear shifting (up/down) and getting FFB working which looks like it could be a mission  :dizzy:

baritonomarchetto:
I am not a coder but a tinkerer, so I am not the person that could give best practice informations to anyone, unfortunately. There are some modifications to your actual code I would do, anyway:
- being gear positions mutually exclusive, you could have used "else if" statements instead of "if" after the neutral position declaration
- you don't need all those delay functions in your code: remove them all. If you will notice some "instability" (unlikely), add a 5ms (or even less) single delay function at the end of the loop.
- it would be more efficient to check switches and send the button press/release at state change instead of at every loop. This makes the code a little bit more complex and then less easy to modify... If you are curious, I have used such approach in my monsterbash and earthshaker boards (and jammarduino before them...I am at the phone now, but some googlefu will suffice to find them).

When I say "well documented libraries" I refer to authors instuctions about the use of those libraries, not to the inner working routines underneath pre digested functions the coder gives to the final user. In addition, every library has a full set of (often well commented) "official" examples that, combined with dedicated examples shared by community members (like those I wrote for our hobby) will help new users to move the first steps (and, like in this case, reach the final goal!)

Vee21:
Thanks baritonomarchetto, Iíve been playing around with the code based on your suggestions to make it bit neater and more efficient.

Iíve been busy cleaning up the cab, sanding painting and putting it all back together and finally enjoying it.

My next goal is to get Force Feedback working, games just arenít the same without itÖ

The steering wheel has a potentiometer attached to the motor and the wheel itís self is attached direct to the motor so itís a direct drive style setup not a belt driven setup.

From what Iíve researched Iíll need at a minimum a motor driver, the BT7960 seems like the go to choice so Iíll be picking up one of those. Iím still unsure how itís all going to work together, has anyone done something like this before?

Empo:
Following this!  :)  Great job so far!

Navigation

[0] Message Index

[*] Previous page

Go to full version