const int PIN_PAS = 2; // Slide Switch (ON = Pedalling, OFF = Stationary)
const int PIN_PWM = 3;
const int PIN_UP = 4; // Button (UP)
const int PIN_DOWN = 5; // Button (DOWN)
const int LED_1 = 7; // Stays on for PAS 2, 3, 4, 5
const int LED_2 = 8; // Stays on for PAS 3, 4, 5
const int LED_3 = 9; // Stays on for PAS 4, 5
const int LED_4 = 10; // Lights up only on PAS 5
const int MIN_THROTTLE_PWM = 56;
const int MAX_THROTTLE_PWM = 214;
int pasLevel = 1;
const int MAX_LEVEL = 5;
const float levelMultipliers[] = {0.00, 0.00, 0.20, 0.45, 0.70, 1.00};
unsigned long lastDebounceTime = 0;
const int debounceDelay = 220;
unsigned long lastSerialPrint = 0;
void setup() {
Serial.begin(115200); // Turns on the text output window
pinMode(PIN_PAS, INPUT_PULLUP);
pinMode(PIN_UP, INPUT_PULLUP);
pinMode(PIN_DOWN, INPUT_PULLUP);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
pinMode(PIN_PWM, OUTPUT);
analogWrite(PIN_PWM, MIN_THROTTLE_PWM);
Serial.println("💻 SIMULATOR READY!");
Serial.println("-> Click UP/DOWN buttons to test your stacking LEDs.");
Serial.println("-> Slide Pin 2 to GND to simulate pedalling power.");
}
void loop() {
unsigned long currentTime = millis();
// --- 1. SWITCH INTERACTION & PAS STEPPING ---
if ((currentTime - lastDebounceTime) > debounceDelay) {
if (digitalRead(PIN_UP) == LOW && pasLevel < MAX_LEVEL) {
pasLevel++;
lastDebounceTime = currentTime;
Serial.print("🔼 Pressed UP. Active Step: PAS ");
Serial.println(pasLevel);
}
if (digitalRead(PIN_DOWN) == LOW && pasLevel > 1) {
pasLevel--;
lastDebounceTime = currentTime;
Serial.print("🔽 Pressed DOWN. Active Step: PAS ");
Serial.println(pasLevel);
}
}
// --- 2. UPDATE PROGRESSIVE STACKING LED MAPPING ---
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
switch(pasLevel) {
case 1: break;
case 2:
digitalWrite(LED_1, HIGH);
break;
case 3:
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, HIGH);
break;
case 4:
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, HIGH);
digitalWrite(LED_3, HIGH);
break;
case 5:
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, HIGH);
digitalWrite(LED_3, HIGH);
digitalWrite(LED_4, HIGH);
break;
}
// --- 3. SIMULATED PAS OVERRIDE ---
// If the switch is off (HIGH), the bike is standing still
if (digitalRead(PIN_PAS) == HIGH) {
analogWrite(PIN_PWM, MIN_THROTTLE_PWM);
if (currentTime - lastSerialPrint > 1000) {
Serial.print("[💤 Stationary] PAS ");
Serial.print(pasLevel);
Serial.print(" (Multiplier: ");
Serial.print(levelMultipliers[pasLevel] * 100);
Serial.println("%) | Output to Fardriver: 56 (0% Idle)");
lastSerialPrint = currentTime;
}
return;
}
// --- 4. ARTIFICIAL CADENCE GENERATION ---
long calculatedPWM = 180;
// --- 5. COMBINE WITH 5-LEVEL USER MULTIPLIER ---
float currentMultiplier = levelMultipliers[pasLevel];
int finalOutputPWM = (int)((calculatedPWM - MIN_THROTTLE_PWM) * currentMultiplier) + MIN_THROTTLE_PWM;
finalOutputPWM = constrain(finalOutputPWM, MIN_THROTTLE_PWM, MAX_THROTTLE_PWM);
// --- 6. SEND SMOOTHED SIGNAL TO MOTOR ---
analogWrite(PIN_PWM, finalOutputPWM);
if (currentTime - lastSerialPrint > 300) {
Serial.print("[🚴 PEDALLING] PAS ");
Serial.print(pasLevel);
Serial.print(" (Multiplier: ");
Serial.print(currentMultiplier * 100);
Serial.print("%) | Output to Fardriver: ");
Serial.println(finalOutputPWM);
lastSerialPrint = currentTime;
}
}