Code works only once

Hello everyone, thanks for all the help. I'm new here, but checked forum and google already doesn't find any proper solution. If anyone can help, that would be great. I'm gonna share the problem first, if anyone interested can follow rest of the topic.

The code below works perfectly when upload to the Leonardo and connect it the FIRST time, but if you unplug and connect again Logitech Shifter effects the handbrake (z axis) but Handbrake itself(10k potantiometer) doesn't works. also it happens if it stays plugged for a while without use.

#include <Joystick.h>
#include <SimRacing.h>

// Joystick definition
Joystick_ Joystick(
    JOYSTICK_DEFAULT_REPORT_ID,
    JOYSTICK_TYPE_JOYSTICK,
    17,  // 10 buttons (2 sequential + 8 H-shifter) + 7 Logitech gears
    0,   // No hat switch
    false, false, // No X and Y axes
    true, false, false, false, false, false, false, false, false); // Z axis (handbrake)

// Sequential shifter buttons
const int ButtonUpPin = 2;
const int ButtonDownPin = 3;

// H-shifter buttons (8 buttons)
const int HShifterPins[] = {4, 5, 6, 7, 8, 9, 10, 11};

// Analog handbrake pin
const int HandbrakePin = A5;

// Logitech shifter pins
const int Pin_ShifterX = A0;
const int Pin_ShifterY = A2;
const int Pin_ShifterRev = 12;  // Logitech reverse gear pin

SimRacing::LogitechShifter shifter(Pin_ShifterX, Pin_ShifterY, Pin_ShifterRev);
const int Gears[] = {1, 2, 3, 4, 5, 6, -1};
const int NumGears = sizeof(Gears) / sizeof(Gears[0]);

// State variables
int ButtonUpState = 0;
int ButtonDownState = 0;
int HShifterStates[8] = {0};

// ADC values for handbrake and Logitech shifter
const int ADC_Max = 1023;

void setup() {
    // Sequential shifter and H-shifter inputs
    pinMode(ButtonUpPin, INPUT_PULLUP);
    pinMode(ButtonDownPin, INPUT_PULLUP);
    for (int i = 0; i < 8; i++) {
        pinMode(HShifterPins[i], INPUT_PULLUP);
    }

    // Handbrake
    pinMode(HandbrakePin, INPUT);
    Joystick.setZAxisRange(0, ADC_Max);

    // Logitech shifter
    shifter.begin();

    // Joystick initialization
    Joystick.begin(false);
    Joystick.setXAxisRange(0, ADC_Max);
    Joystick.setYAxisRange(ADC_Max, 0);  // X and Y are inverted (if necessary)

    // Initial state transmission
    updateJoystick();
}

void loop() {
    // Sequential shifter
    int currentUpState = !digitalRead(ButtonUpPin);
    if (currentUpState != ButtonUpState) {
        Joystick.setButton(0, currentUpState); // Button 0: up
        ButtonUpState = currentUpState;
    }

    int currentDownState = !digitalRead(ButtonDownPin);
    if (currentDownState != ButtonDownState) {
        Joystick.setButton(1, currentDownState); // Button 1: down
        ButtonDownState = currentDownState;
    }

    // H-shifter
    for (int i = 0; i < 8; i++) {
        int currentHState = !digitalRead(HShifterPins[i]);
        if (currentHState != HShifterStates[i]) {
            Joystick.setButton(i + 2, currentHState); // Buttons 2-9: H-shifter
            HShifterStates[i] = currentHState;
        }
    }

    // Logitech shifter
    shifter.update();
    for (int i = 0; i < NumGears; i++) {
        if (shifter.getGear() == Gears[i]) {
            Joystick.pressButton(i + 10); // Buttons 10-16: Logitech gears
        } else {
            Joystick.releaseButton(i + 10);
        }
    }

    // Handbrake
    int handbrakeValue = analogRead(HandbrakePin);
    Joystick.setZAxis(handbrakeValue);

    // Sending joystick state
    Joystick.sendState();

    delay(10);
}

void updateJoystick() {
    // Update all initial states
    loop();
}

Only solution I found is reconnect all cables from breadboard and leonardo and build all circuit again. As you can understand this is not a real or sustainable solution.

I'm building my own racing simulation devices using arduino leonardo. All the projects I'm trying to do works separetely, while combine them facing with issues. In the end I find myself opening topic here.

All I need is building a hub to connect all devices separetely. Devices will be

  1. DB9 rs232 port(For Logitech Shifter) 5V GND 2Analog pin 1DigitalPin
  2. Custom made H Shifter for 7 + 1 Rear Gear (8 Limit switches) Gnd 1digital pin Each
  3. Sequential Shifter for Up and down Gear (2 Limit Switches) Gnd 1digital pin Each
  4. HandBrake (10k Potantiometer) 5V GND 1 Analog pin
  5. 1x Dot matrix for Gear Indicator 5V GND 3DigitalPin
  6. 2x ws2812b-8 for Rev light 5V GND 1 Digital Pin

Do you belive 1 arduino will be enough for all these?
Do I need any extra power suply ?
What can I do decrease to digital pin numbers to finish all project with one leonardo? (I have 74HC595 but couldn't figured out how to use it yet.

After finish Arduino part I'm gonna do the GUI interface like Logitech GHub.

But I'm wondering when all conneccted to the hub, Is it possible to create code blogs and control devices one by one?
Example activate or deactive ports.

Thanks again, I hope someone can help me to find real solution.

When you reconnect, did you then press the reset switch to restart the app at setup?

Nope, not even touched the single cable or board. No physical or software conditions have been changed. It happens even if it stays plugged for a while without use.

Sorry, I misunderstood. Good luck.

You appear to be calling the loop() function explicitly which is unusual but probably not your main problem.

**Edit **

It seems odd that you do this:

before this:

I don't know these hardware devices 'joystick' and 'shifter' or their respective libraries, however, if you find yourself having to reload code to get a device to work correctly, then the chances are that some initialization is failing and the devices are retaining some state which is cleared out only during the activities associated with a code upload. That is you must ensure that all device initialization is done correctly by looking at examples which come with the libraries and other working examples.

If I use this three and spesificly code for them all three works without any problem. Actually everything works together untill I add Logitech shifter adaptor. When I add the Logitech add-on, it disables the potentiometer on the second use and acts as a z axis.

Here is the code for 3 and logitech adaptor code itself

Custom made group

#include <Joystick.h>

// Create a Joystick instance
Joystick_ Joystick(
    JOYSTICK_DEFAULT_REPORT_ID,
    JOYSTICK_TYPE_JOYSTICK,
    10,  // Increased button count to 10 (2 sequential + 8 H-shifter)
    0,   // No hat switches
    false, false, // No X and Y axes
    true, false, false, false, false, false, false, false, false); // Z axis for handbrake

// Pins for sequential shifter buttons
const int ButtonUpPin = 2;
const int ButtonDownPin = 3;

// Pins for H-shifter buttons (8 buttons for the H-pattern)
const int HShifterPins[] = {4, 5, 6, 7, 8, 9, 10, 11};  // 8 additional buttons

// Pin for analog handbrake
const int HandbrakePin = A5;

// States for the buttons
int ButtonUpState = 0;
int ButtonDownState = 0;
int HShifterStates[8] = {0};  // Array to hold the state of the H-shifter buttons

void setup() {
    // Initialize the Joystick library
    Joystick.begin(false);

    // Set up pins for the sequential shifter buttons
    pinMode(ButtonUpPin, INPUT_PULLUP);
    pinMode(ButtonDownPin, INPUT_PULLUP);

    // Set up pins for the H-shifter buttons
    for (int i = 0; i < 8; i++) {
        pinMode(HShifterPins[i], INPUT_PULLUP);
    }

    // Set up pin for the handbrake
    pinMode(HandbrakePin, INPUT);

    // Set Z axis range for the handbrake
    Joystick.setZAxisRange(0, 1023);
}

void loop() {
    // Read the state of the up button
    int currentUpState = !digitalRead(ButtonUpPin);
    if (currentUpState != ButtonUpState) {
        Joystick.setButton(0, currentUpState); // Button 0 for "up"
        ButtonUpState = currentUpState;
    }

    // Read the state of the down button
    int currentDownState = !digitalRead(ButtonDownPin);
    if (currentDownState != ButtonDownState) {
        Joystick.setButton(1, currentDownState); // Button 1 for "down"
        ButtonDownState = currentDownState;
    }

    // Read the state of the H-shifter buttons
    for (int i = 0; i < 8; i++) {
        int currentHState = !digitalRead(HShifterPins[i]);
        if (currentHState != HShifterStates[i]) {
            Joystick.setButton(i + 2, currentHState); // Buttons 2 to 9 for H-shifter
            HShifterStates[i] = currentHState;
        }
    }

    // Read and map the handbrake value
    int handbrakeValue = analogRead(HandbrakePin);
    Joystick.setZAxis(handbrakeValue);

    // Send the Joystick state
    Joystick.sendState();

    delay(10); // Small delay for stability
}

Logitech Adaptor (ready devices, library codes)

/*
 *  Project     Sim Racing Library for Arduino
 *  @author     David Madison
 *  @link       github.com/dmadison/Sim-Racing-Arduino
 *  @license    LGPLv3 - Copyright (c) 2022 David Madison
 *
 *  This file is part of the Sim Racing Library for Arduino.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

 /**
 * @details Emulates the shifter as a joystick over USB.
 * @example ShiftJoystick.ino
 */

// This example requires the Arduino Joystick Library
// Download Here: https://github.com/MHeironimus/ArduinoJoystickLibrary

#include <SimRacing.h>
#include <Joystick.h>

// Set this option to 'true' to send the shifter's X/Y position
// as a joystick. This is not needed for most games.
const bool SendAnalogAxis = false;

// Set this option to 'true' to send the raw state of the reverse
// trigger as its own button. This is not needed for any racing
// games, but can be useful for custom controller purposes.
const bool SendReverseRaw = false;

const int Pin_ShifterX   = A0;
const int Pin_ShifterY   = A2;
const int Pin_ShifterRev = 2;

SimRacing::LogitechShifter shifter(Pin_ShifterX, Pin_ShifterY, Pin_ShifterRev);
//SimRacing::LogitechShifter shifter(SHIFTER_SHIELD_V1_PINS);

const int Gears[] = { 1, 2, 3, 4, 5, 6, -1 };
const int NumGears = sizeof(Gears) / sizeof(Gears[0]);

const int ADC_Max = 1023;  // 10-bit on AVR

Joystick_ Joystick(
	JOYSTICK_DEFAULT_REPORT_ID,      // default report (no additional pages)
	JOYSTICK_TYPE_JOYSTICK,          // so that this shows up in Windows joystick manager
	NumGears + SendReverseRaw,       // number of buttons (7 gears: reverse and 1-6)
	0,                               // number of hat switches (none)
	SendAnalogAxis, SendAnalogAxis,  // include X and Y axes for analog output, if set above
	false, false, false, false, false, false, false, false, false);  // no other axes

void updateJoystick();  // forward-declared function for non-Arduino environments


void setup() {
	shifter.begin();

	// if you have one, your calibration line should go here
	
	Joystick.begin(false);  // 'false' to disable auto-send
	Joystick.setXAxisRange(0, ADC_Max);
	Joystick.setYAxisRange(ADC_Max, 0);  // invert axis so 'up' is up

	updateJoystick();  // send initial state
}

void loop() {
	shifter.update();

	if (SendAnalogAxis == true || shifter.gearChanged()) {
		updateJoystick();
	}
}

void updateJoystick() {
	// set the buttons corresponding to the gears
	for (int i = 0; i < NumGears; i++) {
		if (shifter.getGear() == Gears[i]) {
			Joystick.pressButton(i);
		}
		else {
			Joystick.releaseButton(i);
		}
	}

	// set the analog axes (if the option is set)
	if (SendAnalogAxis == true) {
		int x = shifter.getPosition(SimRacing::X, 0, ADC_Max);
		int y = shifter.getPosition(SimRacing::Y, 0, ADC_Max);
		Joystick.setXAxis(x);
		Joystick.setYAxis(y);
	}

	// set the reverse button (if the option is set)
	if (SendReverseRaw == true) {
		bool reverseState = shifter.getReverseButton();
		Joystick.setButton(NumGears, reverseState);  // "NumGears" is the 0-indexed max gear + 1
	}

	Joystick.sendState();
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.