diff --git a/ESP32-S3-Analog/ESP32-S3-Analog.ino b/ESP32-S3-Analog/ESP32-S3-Analog.ino index 38c3b79..669e0da 100644 --- a/ESP32-S3-Analog/ESP32-S3-Analog.ino +++ b/ESP32-S3-Analog/ESP32-S3-Analog.ino @@ -1,3 +1,13 @@ +// Enable this mode to pass raw analog data to the game without any post- +// processing. +// The game has a built-in mechanism to calculate which sensor is triggered +// and the force of the hit, so it's recommended to enable this mode. +// This also the provides the most similar experience with the arcade. +// If turned on, the microcontroller will ony do a fast sigle-pass convolution +// over the piezoelectric sensors' inputs, and then pass the data to the game +// directly. +#define RAW_ANALOG_MODE 1 + #define PLAYERS 2 #define CHANNELS 4 @@ -5,9 +15,12 @@ // See cache.h for implementation #define SAMPLE_CACHE_LENGTH 16 -// The thresholds are also dependent on SAMPLE_CACHE_LENGTH, if you -// changed SAMPLE_CACHE_LENGTH, you should also adjust thresholds +// The maximum value of a hit (not the minumum value to trigger a heavy hit) +// To configure the light and heavy thresholds, do it in the game settings #define MAX_THRES 5000 + +#if !RAW_ANALOG_MODE +// The minimum value to trigger a light hit #define HIT_THRES 1000 // If the reset time is too short, the game may not be able to @@ -15,6 +28,7 @@ // minimum value so that the game won't miss any hit. If the game // occassionally miss the drum input, increase this value #define RESET_TIME 40 +#endif // Sensitivity multipliers for each channel, 1.0 as the baseline #define P1_L_DON_SENS 1.0 @@ -52,13 +66,6 @@ #include "Joystick_ESP32S2.h" #include "cache.h" -Cache inputWindow[PLAYERS][CHANNELS]; -unsigned long power[PLAYERS][CHANNELS]; -unsigned long lastPower[PLAYERS][CHANNELS]; - -bool triggered[PLAYERS]; -unsigned long triggeredTime[PLAYERS][CHANNELS]; - const byte inPins[PLAYERS][CHANNELS] = { P1_L_DON_IN, P1_L_KAT_IN, P1_R_DON_IN, P1_R_KAT_IN, P2_L_DON_IN, P2_L_KAT_IN, P2_R_DON_IN, P2_R_KAT_IN @@ -72,15 +79,20 @@ const float sensitivities[PLAYERS][CHANNELS] = { P2_L_DON_SENS, P2_L_KAT_SENS, P2_R_DON_SENS, P2_R_KAT_SENS }; -uint axisValues[PLAYERS][CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; +Cache inputWindow[PLAYERS][CHANNELS]; +unsigned long power[PLAYERS][CHANNELS]; +#if !RAW_ANALOG_MODE +unsigned long lastPower[PLAYERS][CHANNELS]; +bool triggered[PLAYERS]; +unsigned long triggeredTime[PLAYERS][CHANNELS]; int outputValue[PLAYERS] = {0, 0}; uint resetTimer[PLAYERS] = {0, 0}; - short maxIndex[PLAYERS] = {0, 0}; float maxPower[PLAYERS] = {0, 0}; +#endif -uint shifter = 0; +uint axisValues[PLAYERS][CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 10, 4, true, true, false, true, true, false, @@ -90,13 +102,17 @@ void setup() { for (byte p = 0; p < PLAYERS; p++) { for (byte i = 0; i < CHANNELS; i++) { power[p][i] = 0; +#if !RAW_ANALOG_MODE lastPower[p][i] = 0; triggered[p] = false; +#endif pinMode(inPins[p][i], INPUT); pinMode(outPins[p][i], OUTPUT); } +#if !RAW_ANALOG_MODE maxIndex[p] = -1; maxPower[p] = 0; +#endif } USB.PID(0x4869); USB.VID(0x4869); @@ -117,14 +133,17 @@ void loop() { for (byte i = 0; i < CHANNELS; i++) { inputWindow[p][i].put(analogRead(inPins[p][i])); power[p][i] = sensitivities[p][i] * (power[p][i] - inputWindow[p][i].get(1) + inputWindow[p][i].get()); - +#if !RAW_ANALOG_MODE if (lastPower[p][i] > maxPower[p] && power[p][i] < lastPower[p][i]) { maxPower[p] = lastPower[p][i]; maxIndex[p] = i; } lastPower[p][i] = power[p][i]; +#else + axisValues[p][i] = AXIS_RANGE * (power[p][i] > MAX_THRES ? 1 : ((float)power[p][i] / MAX_THRES)); +#endif } - +#if !RAW_ANALOG_MODE if (!triggered[p] && maxPower[p] >= HIT_THRES) { triggered[p] = true; digitalWrite(outPins[p][maxIndex[p]], HIGH); @@ -151,11 +170,12 @@ void loop() { if (triggered[p]) { resetTimer[p]++; } +#endif } - - Joystick.setXAxis((axisValues[0][0] > 0 ? axisValues[0][0] : -axisValues[0][1])); - Joystick.setYAxis((axisValues[0][2] > 0 ? axisValues[0][2] : -axisValues[0][3])); - Joystick.setRxAxis((axisValues[1][0] > 0 ? axisValues[1][0] : -axisValues[1][1])); - Joystick.setRyAxis((axisValues[1][2] > 0 ? axisValues[1][2] : -axisValues[1][3])); + + Joystick.setXAxis(axisValues[0][0] > axisValues[0][1] ? axisValues[0][0] : -axisValues[0][1]); + Joystick.setYAxis(axisValues[0][2] > axisValues[0][3] ? axisValues[0][2] : -axisValues[0][3]); + Joystick.setRxAxis(axisValues[1][0] > axisValues[1][1] ? axisValues[1][0] : -axisValues[1][1]); + Joystick.setRyAxis(axisValues[1][2] > axisValues[1][3] ? axisValues[1][2] : -axisValues[1][3]); Joystick.sendState(); }