Add files for shifter, fix was to enable sending analog axis in example

This commit is contained in:
Sem
2026-04-06 22:28:32 +02:00
commit 463b7042eb
8 changed files with 268 additions and 0 deletions

5
Logitec-G920-USB-Shifter/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@@ -0,0 +1,17 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:sparkfun_promicro8]
platform = atmelavr
board = sparkfun_promicro8
framework = arduino
lib_deps =
dmadison/Sim Racing Library@^2.0.2
mheironimus/Joystick@^2.1.1

View File

@@ -0,0 +1,18 @@
#include <Arduino.h>
// put function declarations here:
int myFunction(int, int);
void setup() {
// put your setup code here, to run once:
int result = myFunction(2, 3);
}
void loop() {
// put your main code here, to run repeatedly:
}
// put function definitions here:
int myFunction(int x, int y) {
return x + y;
}

View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html

View File

@@ -0,0 +1,124 @@
/*
* 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 Logitech Driving Force shifter (included with
* the G923 / G920 / G29 wheels) as a joystick over USB.
* @example LogitechShifter_Joystick.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 = true;
// 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;
// Power (VCC): DE-9 pin 9
// Ground (GND): DE-9 pin 6
// Note: DE-9 pin 3 (CS) needs to be pulled-up to VCC!
const int Pin_ShifterX = A0; // DE-9 pin 4
const int Pin_ShifterY = A2; // DE-9 pin 8
const int Pin_ShifterRev = 2; // DE-9 pin 2
// This pin requires an extra resistor! If you have made the proper
// connections, change the pin number to the one you're using
const int Pin_ShifterDetect = SimRacing::UnusedPin; // DE-9 pin 7, requires pull-down resistor
SimRacing::LogitechShifter shifter(
Pin_ShifterX, Pin_ShifterY,
Pin_ShifterRev,
Pin_ShifterDetect
);
//SimRacing::LogitechShifter shifter = SimRacing::CreateShieldObject<SimRacing::LogitechShifter, 2>();
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();
}