Arduino Controlled PSE Pump Code
This is the code for the Arduino Controlled PSE pump.
/*
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);
}
//--------------------------------------------------------------------------------------------------------