Logitech Pedals+Shifter using One Arduino Leonardo

Hi All,

First time posting and first time trying to 'create' a DIY project using Arduino, so please forgive me for any mistakes. I also do not know any programming and have only been googling questions I had to some questions that I ran into.

First of all, I have only ordered the stuff I need after watching this video tutorial: https://youtu.be/k5CtXG1rpZg

My main goal is to make an adapter for my pedals. However, I also had the idea that I can use the same arduino board for my shifter, after watching this video tutorial:
https://youtu.be/dLpWEu8kCec

After reading an old topic here, I think that I can do this by following the below wiring diagram (I just made this, sorry if it looks confusing):

And after looking at the two separate code provided for the two projects, I think it's possible to combine them onto one board by using the below code:

#include <Joystick.h>

// H-shifter mode analog axis thresholds
#define HS_XAXIS_12        400
#define HS_XAXIS_56        500
#define HS_YAXIS_135       800
#define HS_YAXIS_246       300

// Sequential shifter mode analog axis thresholds
#define SS_UPSHIFT_BEGIN   670
#define SS_UPSHIFT_END     600
#define SS_DOWNSHIFT_BEGIN 430
#define SS_DOWNSHIFT_END   500

// Handbrake mode analog axis limits
#define HB_MAXIMUM         530
#define HB_MINIMUM         400
#define HB_RANGE           (HB_MAXIMUM-HB_MINIMUM)

// Digital inputs definitions
#define DI_REVERSE         1
#define DI_MODE            3
#define DI_RED_CENTERRIGHT 4
#define DI_RED_CENTERLEFT  5
#define DI_RED_RIGHT       6
#define DI_RED_LEFT        7
#define DI_BLACK_TOP       8
#define DI_BLACK_RIGHT     9
#define DI_BLACK_LEFT      10
#define DI_BLACK_BOTTOM    11
#define DI_DPAD_RIGHT      12
#define DI_DPAD_LEFT       13
#define DI_DPAD_BOTTOM     14
#define DI_DPAD_TOP        15

// Shifter state
#define DOWN_SHIFT         -1
#define NO_SHIFT           0
#define UP_SHIFT           1

// Shifter mode
#define SHIFTER_MODE       0
#define HANDBRAKE_MODE     1

//int zAxis_ = 0; only used for 5AXIS
//int RxAxis_ = 0; only used for 5AXIS                   
int RyAxis_ = 0;  
int RzAxis_ = 0;          
int Throttle_ = 0;         

const bool initAutoSendState = true; 

// LED blink counter
int led=0;

// Shifter state
int shift=NO_SHIFT;

// Handbrake mode
int mode=SHIFTER_MODE;

int b[16];

int gear=0;                          // Default value is neutral

// Constant that maps the phyical pin to the joystick button.
//const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState = 0;

// Create the Joystick
Joystick_ Joystick;

//combined setup() for pedals and shifter
void setup()
{
	// G29 shifter analog inputs configuration, A0 changed to A4, and A2 changed to A3
	pinMode(A4, INPUT_PULLUP);   // X axis
	pinMode(A3, INPUT_PULLUP);   // Y axis

	pinMode(2, INPUT); 

	for(int i=0; i<16; i++) b[i] = 0;
	b[DI_MODE] =0;
	
	// Initialize Joystick Library
	Joystick.begin();
  }

//was loop() but changed to pedals() for no conflict?
void pedals(){
	/*
	zAxis_ = analogRead(A0);  
	zAxis_ = map(zAxis_,0,1023,0,255);
	 Joystick.setZAxis(zAxis_);  
	*/

	/*
	RxAxis_ = analogRead(A1);
	 RxAxis_ = map(RxAxis_,0,1023,0,255);
	 Joystick.setRxAxis(RxAxis_);
	*/

	RyAxis_ = analogRead(A0);
	RyAxis_ = map(RyAxis_,0,1023,0,255);
	Joystick.setRyAxis(RyAxis_);

	RzAxis_ = analogRead(A1);
	RzAxis_ = map(RzAxis_,1023,0,255,0);            
	Joystick.setRzAxis(RzAxis_);
	  
	Throttle_ = analogRead(A2);
	Throttle_ = map(Throttle_,1023,0,255,0);         
	Joystick.setThrottle(Throttle_);                

	delay (50);
}

//was loop() but changed to shifter() for no conflict?
void shifter() {

	int x=analogRead(0);                 // X axis
	int y=analogRead(2);                 // Y axis

	int _isreverse = digitalRead(2);
	int _gear_ = 0;

if( _isreverse == 1 ){

    _gear_ = 8;
    b[DI_REVERSE]= 1;

}else{ 
  

  if(b[DI_MODE]==0)                    // H-shifter mode?
  {
    if(x<HS_XAXIS_12)                  // Shifter on the left?
    {
      if(y>HS_YAXIS_135) _gear_=1;       // 1st gear
      if(y<HS_YAXIS_246) _gear_=2;       // 2nd gear
    }
    else if(x>HS_XAXIS_56)             // Shifter on the right?
    {
      if(y>HS_YAXIS_135) _gear_=5;       // 5th gear
      if(y<HS_YAXIS_246) _gear_=6;       // 6th gear
     
    }
    else                               // Shifter is in the middle
    {
      if(y>HS_YAXIS_135) _gear_=3;       // 3rd gear
      if(y<HS_YAXIS_246) _gear_=4;       // 4th gear
    }
  }
}
  
  if(gear!=6) b[DI_REVERSE]=0;         // Reverse gear is allowed only on 6th gear position
  
   if (_gear_ != gear ){
      gear = _gear_;
      desactivar();
      Joystick.setButton(gear-1, HIGH);
   }
   delay(50);
}

void desactivar(){
  // Depress virtual button for current gear
  for(int i = 0; i <= 10 ; i++ )  Joystick.setButton(i, LOW);
}

For reference, below are the original codes provided by amstudio:

Pedals Code:

#include <Joystick.h>

Joystick_ Joystick;

//int zAxis_ = 0; 
//int RxAxis_ = 0;                    
int RyAxis_ = 0;  
int RzAxis_ = 0;          
int Throttle_ = 0;         

const bool initAutoSendState = true; 

void setup()
{
      Joystick.begin();
  }
   
void loop(){
    RyAxis_ = analogRead(A0);
    RyAxis_ = map(RyAxis_,0,1023,0,255);
    Joystick.setRyAxis(RyAxis_);

    RzAxis_ = analogRead(A1);
    RzAxis_ = map(RzAxis_,1023,0,255,0);            
    Joystick.setRzAxis(RzAxis_);
  
    Throttle_ = analogRead(A2);
    Throttle_ = map(Throttle_,1023,0,255,0);         
    Joystick.setThrottle(Throttle_);                
 
    delay (50);
}

Shifter Code:

#include <Joystick.h>

// Create the Joystick
Joystick_ Joystick;

// H-shifter mode analog axis thresholds
#define HS_XAXIS_12        400
#define HS_XAXIS_56        500
#define HS_YAXIS_135       800
#define HS_YAXIS_246       300

// Sequential shifter mode analog axis thresholds
#define SS_UPSHIFT_BEGIN   670
#define SS_UPSHIFT_END     600
#define SS_DOWNSHIFT_BEGIN 430
#define SS_DOWNSHIFT_END   500

// Handbrake mode analog axis limits
#define HB_MAXIMUM         530
#define HB_MINIMUM         400
#define HB_RANGE           (HB_MAXIMUM-HB_MINIMUM)

// Digital inputs definitions
#define DI_REVERSE         1
#define DI_MODE            3
#define DI_RED_CENTERRIGHT 4
#define DI_RED_CENTERLEFT  5
#define DI_RED_RIGHT       6
#define DI_RED_LEFT        7
#define DI_BLACK_TOP       8
#define DI_BLACK_RIGHT     9
#define DI_BLACK_LEFT      10
#define DI_BLACK_BOTTOM    11
#define DI_DPAD_RIGHT      12
#define DI_DPAD_LEFT       13
#define DI_DPAD_BOTTOM     14
#define DI_DPAD_TOP        15

// Shifter state
#define DOWN_SHIFT         -1
#define NO_SHIFT           0
#define UP_SHIFT           1

// Shifter mode
#define SHIFTER_MODE       0
#define HANDBRAKE_MODE     1

// LED blink counter
int led=0;

// Shifter state
int shift=NO_SHIFT;

// Handbrake mode
int mode=SHIFTER_MODE;

int b[16];

int gear=0;                          // Default value is neutral

// Constant that maps the phyical pin to the joystick button.
//const int pinToButtonMap = 9;

void setup() {
   // G29 shifter analog inputs configuration, A0 changed to A4 and A2 changed to A3
  pinMode(A4, INPUT_PULLUP);   // X axis
  pinMode(A3, INPUT_PULLUP);   // Y axis

  pinMode(2, INPUT); 

  for(int i=0; i<16; i++) b[i] = 0;
  b[DI_MODE] =0;
  // Initialize Joystick Library
  Joystick.begin();
  
}

// Last state of the button
int lastButtonState = 0;

void loop() {

  int x=analogRead(0);                 // X axis
  int y=analogRead(2);                 // Y axis

  int _isreverse = digitalRead(2);
  int _gear_ = 0;

if( _isreverse == 1 ){

      _gear_ = 8;
      b[DI_REVERSE]= 1;

}else{ 
  

  if(b[DI_MODE]==0)                    // H-shifter mode?
  {
    if(x<HS_XAXIS_12)                  // Shifter on the left?
    {
      if(y>HS_YAXIS_135) _gear_=1;       // 1st gear
      if(y<HS_YAXIS_246) _gear_=2;       // 2nd gear
    }
    else if(x>HS_XAXIS_56)             // Shifter on the right?
    {
      if(y>HS_YAXIS_135) _gear_=5;       // 5th gear
      if(y<HS_YAXIS_246) _gear_=6;       // 6th gear
     
    }
    else                               // Shifter is in the middle
    {
      if(y>HS_YAXIS_135) _gear_=3;       // 3rd gear
      if(y<HS_YAXIS_246) _gear_=4;       // 4th gear
    }
   
  }

}
  
  
  if(gear!=6) b[DI_REVERSE]=0;         // Reverse gear is allowed only on 6th gear position
  
   if (_gear_ != gear ){
      gear = _gear_;
      desactivar();
      Joystick.setButton(gear-1, HIGH);
   }
   delay(50);
}

void desactivar(){
  // Depress virtual button for current gear
  for(int i = 0; i <= 10 ; i++ )  Joystick.setButton(i, LOW);
}

I am unable to test it right now since the parts were ordered a few hours ago, but I wanted to seek help in advance, just in case I run into potential issues.

Also, what does the delay(50) do in both codes?

Thank you in advance!

it is simple. there are three section: before setup(), setup() itself and loop(). combine same sections together.

#include <Joystick.h>
Joystick_ Joystick;

and

Joystick.begin();

need only once.

Hello kolaha,

Thank you for the reply. I didn't realize you can combine the same sections together.

I had some trouble with the loop() part because I actually wrote a better code for both shifter and pedals, but the shifter loop needed delay of 100 but pedals code need to have no delay.

But I resolved it by using millis() instead of delay() to set a delay for the shifter code while being able to run the pedal code without delay, in the same loop().

Thanks for your help!

Can you share your new code? Or that code in above also works? I want to make adapter just like you. I'm new on arduino stuff

Logitech_Pedals_Shifter_USB_Smoothed.ino (7.2 KB)

Here is my code, please take note that the below values may need to be adjusted for you:

// H-shifter mode analog axis thresholds
#define HS_XAXIS_12        390 //default 390
#define HS_XAXIS_56        680 //default 680

It is responsible for reading shifter left and right position. May need to adjust if shifter doesnt read gears 1, 2, 5 and 6 properly.

Thanks mate, I really appreciate it!