Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino Leonardo-Based Gaming Steering Wheel with Pedals and Gear Shifter

View and Edit Project In Cirkit DesignerImage of Arduino Leonardo-Based Gaming Steering Wheel with Pedals and Gear Shifter

Circuit Documentation

Summary

This circuit is designed to function as a gaming steering wheel with three pedals and a gear shifter. It allows for 900-degree rotation and includes the following components:

The circuit is controlled by an Arduino Leonardo (Rev3b) microcontroller, which reads inputs from the encoder, potentiometers, and push buttons, and processes these inputs to simulate a gaming steering wheel setup.

Component List

Arduino Leonardo (Rev3b)

PR-Rotary Potentiometer

8 Push Button Board PCB

IO Expander

600 PPR Optical Rotary Encoder

Wiring Details

Arduino Leonardo (Rev3b)

PR-Rotary Potentiometer

8 Push Button Board PCB

IO Expander

600 PPR Optical Rotary Encoder

Code Documentation

#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Bounce2.h>

/*
 * Gaming Steering Wheel with 3 Pedals and Gear Shifter
 * Allows 900-degree rotation
 * Components:
 * - 600 PPR Optical Rotary Encoder (Steering Wheel)
 * - 3 Potentiometers (Pedals)
 * - 8 Push Buttons (Gear Shifter)
 * - IO Expander with additional push buttons
 */

// Pin definitions for Arduino
const int encoderPinA = 2; // D2/SDA
const int encoderPinB = 3; // D3 PWM/SCL
const int pedal1Pin = A0;  // A0
const int pedal2Pin = A1;  // A1
const int pedal3Pin = A2;  // A2
const int buttonPins[] = {4, 5, 6, 7, 8, 9, 10, 11}; // D4 to D11
const int ledPin = 13; // Built-in LED for error indication

// IO Expander
Adafruit_MCP23017 mcp;
const int ioExpanderButtonPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17}; // P00 to P07 and P10 to P17

// Variables for encoder
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
volatile bool encoderUpdated = false; // Flag to indicate encoder update

// Debouncing variables
const int debounceDelay = 50; // 50 ms debounce delay
Bounce buttonDebouncers[8];
bool buttonStates[8] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}; // Initialize button states
bool ioExpanderButtonStates[16] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}; // Initialize IO expander button states

// Non-blocking delay variables
unsigned long previousMillis = 0;
const long interval = 100;

// Global variables for pedal values
int pedal1Value, pedal2Value, pedal3Value;

void setup() {
  Serial.begin(115200); // Increased baud rate for faster communication

  // Initialize encoder pins
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE); // D2 on Leonardo
  attachInterrupt(digitalPinToInterrupt(encoderPinB), updateEncoder, CHANGE); // D3 on Leonardo

  // Initialize pedal pins
  pinMode(pedal1Pin, INPUT);
  pinMode(pedal2Pin, INPUT);
  pinMode(pedal3Pin, INPUT);

  // Initialize button pins with debouncers
  for (int i = 0; i < 8; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
    buttonDebouncers[i].attach(buttonPins[i]);
    buttonDebouncers[i].interval(debounceDelay