Arduino Controlled PSE Pump Code
This is the code for controlling the Mercedes W220 PSE with an Arduino as described here.
/* Code for controlling the Mercedes W220 PSE with an Arduino */ // Assign Remote Control Pins static const int RemA = 10; //A static const int RemB = 11; //B static const int RemC = 12; //C static const int RemD = 13; //D // Assign PSE Pressure Sensor Pin static const int PPin = A0; // Assign Trunk Lid Switch Pin static const int TPin = A1; int TrunkPrevState; // Assign Relay Pins static const int RelMotor = 2; static const int RelPos = 3; static const int RelNeg = 4; static const int RelFLDr = 5; static const int RelDrs = 6; static const int RelTrunk = 8; static const int RelHR = 9; static const int RelTrunkSol = 7; // Double Click Variables int ButtonAState; unsigned long timePress = 0; unsigned long timePressLimit = 0; int clicks = 0; // Long Press Variables long buttonTimer = 0; long longPressTime = 1000; boolean buttonActive = false; boolean longPressActive = false; // Assign Arduino Auto Shutdown Relay Pin static const int SPin = A2; // Timer Variable for Auto Shutdown unsigned long time; unsigned long timeout = 14400000; //4 hours //-------------------------------------------------------------------------------------------------------- void setup() { // Define pin modes pinMode(PPin, INPUT); pinMode(TPin, INPUT_PULLUP); pinMode(SPin, OUTPUT); pinMode(RelMotor, OUTPUT); pinMode(RelPos, OUTPUT); pinMode(RelNeg, OUTPUT); pinMode(RelFLDr, OUTPUT); pinMode(RelDrs, OUTPUT); pinMode(RelTrunk, OUTPUT); pinMode(RelHR, OUTPUT); pinMode(RelTrunkSol, OUTPUT); pinMode(RemA, INPUT); pinMode(RemB, INPUT); pinMode(RemC, INPUT); pinMode(RemD, INPUT); // Making sure all relays are OFF digitalWrite(RelMotor, HIGH); digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); digitalWrite(RelFLDr, HIGH); digitalWrite(RelDrs, HIGH); digitalWrite(RelTrunk, HIGH); digitalWrite(RelHR, HIGH); digitalWrite(RelTrunkSol, HIGH); digitalWrite(SPin, HIGH); // Read trunk's current state TrunkPrevState = digitalRead(TPin); } //-------------------------------------------------------------------------------------------------------- void loop() { // Auto Shutdown Timer-------------------------------------------------------------- time = millis(); // Time elapsed since Arduino started if (time > timeout && digitalRead(TPin) == HIGH) { //Turn off Arduino if trunk is and was closed. Else add 30 seconds to the timer. if (TrunkPrevState == HIGH && digitalRead(TPin) == HIGH) { digitalWrite(SPin, LOW); } else { timeout = timeout + 30000; } } // Button A pressed -------------------------------------------------------------- if (digitalRead(RemA) == HIGH) { LockAll(); } // Button B pressed once or twice------------------------------------------------- // Credit - The_Little_Cousin : https://forum.arduino.cc/index.php?topic=425587.msg2932300#msg2932300 if (digitalRead(RemB) == HIGH) { delay(100); if (digitalRead(RemB) == LOW) { if (clicks == 0) { timePress = millis(); timePressLimit = timePress + 1000; clicks = 1; } else if (clicks == 1 && millis() < timePressLimit) { //Double press action UnlockAll(); //Set variables back to 0 timePress = 0; timePressLimit = 0; clicks = 0; } } } //Single press if (clicks == 1 && timePressLimit != 0 && millis() > timePressLimit) { timePress = 0; timePressLimit = 0; clicks = 0; //Single press action UnlockDriver(); } // Button C long-pressed -------------------------------------------------------------- // Credit xn1ch1 : https://www.instructables.com/id/Arduino-Dual-Function-Button-Long-PressShort-Press/ if (digitalRead(RemC) == HIGH) { if (buttonActive == false) { buttonActive = true; buttonTimer = millis(); } if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) { longPressActive = true; //Long-press action - Unlock the trunk UnlockTrunk(); } } else { if (buttonActive == true) { if (longPressActive == true) { longPressActive = false; } else { //Short-press action - Nothing } buttonActive = false; } } // Button D pressed -------------------------------------------------------------- if (digitalRead(RemD) == HIGH) { DropHeadRest(); } // Trunk lid closed ----------------------------------------------------------------- // When the trunk state changes from open(LOW) to closed (HIGH) if (TrunkPrevState == LOW && digitalRead(TPin) == HIGH) { LockTrunk(); } // Store current trunk state TrunkPrevState = digitalRead(TPin); } //-------------------------------------------------------------------------------------------------------- void LockAll() /* Lock car with +ve pressure, which pulls the Door Lock Button down, then returns to atmospheric press */ { // Doors are locked in 2 steps since there's not enough pressure. Possibly due to a small leak. //+ve Pressure digitalWrite(RelPos, LOW); digitalWrite(RelNeg, HIGH); //Driver Door digitalWrite(RelFLDr, LOW); MotorRun(3); digitalWrite(RelFLDr, HIGH); //Remaining Doors digitalWrite(RelDrs, LOW); MotorRun(5); digitalWrite(RelDrs, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void UnlockAll() /* Unlock car with -ve pressure , which moves Door Lock Button up, then returns to atmospheric pressure. */ { // Doors are locked in 2 steps since there's not enough pressure. Possibly due to a small leak. //-ve Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, LOW); //Passenger Doors digitalWrite(RelDrs, LOW); MotorRun(6); digitalWrite(RelDrs, HIGH); //Driver Door digitalWrite(RelFLDr, LOW); MotorRun(3); digitalWrite(RelFLDr, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void UnlockDriver() /* Unlock car with -ve pressure , which moves Driver Door Lock Button up, then returns to atmospheric pressure. */ { //-ve Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, LOW); //Driver Door digitalWrite(RelFLDr, LOW); MotorRun(3); digitalWrite(RelFLDr, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void DropHeadRest() /* Drop rear headrests with -ve pressure. */ { //-ve Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, LOW); //Rear Seat Head Restraints digitalWrite(RelHR, LOW); MotorRun(3); digitalWrite(RelHR, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void LockTrunk() /* Manually close Boot/Trunk by pulling down on RTG Handle until latch goes click, 1) +ve pressure, Boot/Trunk Catch Actuator pulls boot closed, 2) –ve pressure, retracts the Retractable Trunklid Grip (RTG) Handle, 3) Returns to atmospheric pressure. */ { // Open PSE Trunk HECK valve digitalWrite(RelTrunk, LOW); //+ve Pressure digitalWrite(RelPos, LOW); digitalWrite(RelNeg, HIGH); //Trunk Catch Actuator pulls boot closed MotorRun(7); //-ve Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, LOW); // Retract RTG Handle MotorRun(4); // Close PSE Trunk HECK valve digitalWrite(RelTrunk, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void UnlockTrunk() /* Open Boot/Trunk with trunk latch solenoid and +ve pressure, which extends RTG Handle, and unlocks Boot/Trunk latch, releasing lid which fully opens, then returns to atmospheric pressure. */ { //+ve Pressure digitalWrite(RelPos, LOW); digitalWrite(RelNeg, HIGH); // Open PSE Trunk HECK valve digitalWrite(RelTrunk, LOW); // Open Solenoid Valve in trunk lock digitalWrite(RelTrunkSol, LOW); // Open Boot/Trunk latch MotorRun(1.5); // Close Solenoid Valve in trunk lock digitalWrite(RelTrunkSol, HIGH); // Extend RTG Handle MotorRun(4); // Close PSE Trunk HECK valve digitalWrite(RelTrunk, HIGH); //Release Pressure digitalWrite(RelPos, HIGH); digitalWrite(RelNeg, HIGH); delay (100); } //-------------------------------------------------------------------------------------------------------- void MotorRun(float t) /* Turns on motor relay for t seconds Checks PPin for pressure extremes every 100ms and turns off motor if out of bounds. */ { int pressure; delay (100); //Start the motor digitalWrite(RelMotor, LOW); for (int i = 0; i <= (t * 10); i++) // t is converted from sec to multiples of 100ms (delay below) { pressure = analogRead(PPin); if (i > 10) // Only check after 1 sec has passed to ignore spikes at startup { if (pressure < 80 || pressure > 640) { // Immediately stop motor and exit function digitalWrite(RelMotor, HIGH); delay (100); return; } else { delay (100); //Wait and recheck } } } // Stop the motor after t secs have passed digitalWrite(RelMotor, HIGH); delay (100); } //--------------------------------------------------------------------------------------------------------