Skip to content

Commit

Permalink
Improve CAN messages for turn on/off the eFan
Browse files Browse the repository at this point in the history
  • Loading branch information
ffrizzo committed Sep 30, 2023
1 parent 96f5419 commit c458ef5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 35 deletions.
61 changes: 41 additions & 20 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#include "main.h"

const byte FAN_STAGE_TO_HEX[16] = {0x0, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0};

STM32_CAN Can1(CAN1, DEF);

unsigned long previousCANMillis = 0;
CAN_message_t outCanMsg;

int previousACStatus = LOW;
unsigned long acStatusChangedMillis = 0;

void setup() {
initialize();
}
Expand All @@ -17,12 +27,15 @@ void initialize() {

pinMode(AC_INPUT, INPUT_PULLDOWN);

pinMode(AC_PRESSURE_TYPE, INPUT_PULLUP);
pinMode(AC_PRESSURE_SENSOR_TYPE, INPUT_PULLUP);
pinMode(AC_PRESSURE_SWITCH_HIGH, INPUT_PULLUP);
pinMode(AC_PRESSURE_SENSOR, INPUT_ANALOG);

pinMode(EXTERNAL_TEMPERATURE_SENSOR, INPUT_ANALOG);

previousACStatus = digitalRead(AC_INPUT);
acStatusChangedMillis = millis() - (30 * 1000);

Can1.begin();
Can1.setBaudRate(500000);
}
Expand All @@ -34,7 +47,7 @@ void processCan(long currentMillis) {

Serial.println("Processing CAN Messages...");
processCanICL2();
processCanICL3();
processCanICL3(currentMillis);
previousCANMillis = currentMillis;
}

Expand All @@ -52,9 +65,12 @@ void processCanICL2() {
Can1.write(outCanMsg);
}

void processCanICL3() {
void processCanICL3(long currentMillis) {
int acStatus = digitalRead(AC_INPUT);
Serial.printf("AC status is: %s\n", acStatus == 1 ? "on" : "off");
if (acStatus != previousACStatus) {
acStatusChangedMillis = currentMillis;
}

outCanMsg.id = CAN_ICL3;
outCanMsg.len = 8;
Expand All @@ -70,7 +86,7 @@ void processCanICL3() {
break;
}

outCanMsg.buf[1] = calculateFanStage(acStatus);
outCanMsg.buf[1] = calculateFanStage(acStatus, currentMillis);
outCanMsg.buf[2] = 0x00;
outCanMsg.buf[3] = readTemperatureSensor();
outCanMsg.buf[5] = 0x00;
Expand All @@ -81,8 +97,20 @@ void processCanICL3() {
previousACStatus = acStatus;
}

byte calculateFanStage(int acStatus) {
if (digitalRead(AC_PRESSURE_TYPE) == HIGH) {
byte calculateFanStage(int acStatus, long currentMillis) {
// eFan should change status after 30 secs of AC Status have beeing changed
int diff = (currentMillis - acStatusChangedMillis) * 0.001;
if (diff < 30) {
if (acStatus == HIGH) {
return FAN_STAGE_TO_HEX[0];
}

// if ac status was changed to off keep fun running for other 30secs
// Set the ac status to high will guarantee the fan runs on right stage
acStatus = HIGH;
}

if (digitalRead(AC_PRESSURE_SENSOR_TYPE) == HIGH) {
return calculateFanStageWithPressureSwitch(acStatus);
}

Expand Down Expand Up @@ -123,22 +151,15 @@ byte calculateFanStateWithPressureSensor(int acStatus) {
}

byte calculateFanStageWithPressureSwitch(int acStatus) {
// Pressure switch works with ground to provide a signal for second stage relay
bool pressureIsHigh = digitalRead(AC_PRESSURE_SWITCH_HIGH) == LOW;
int stage = 0;
if (acStatus == LOW) {
if (pressureIsHigh) {
stage = FAN_STAGE_AT_HIGH_PRESSURE;
} else {
stage = 0;
}

} else {
if (pressureIsHigh) {
stage = FAN_STAGE_AT_HIGH_PRESSURE;
} else {
// If AC is ON eFan should run at the FAN_STAGE_LOW_PRESSURE
stage = FAN_STAGE_AT_LOW_PRESSURE;
}
int stage = 0;
if (pressureIsHigh) {
stage = FAN_STAGE_AT_HIGH_PRESSURE;
} else if (acStatus == HIGH) {
// If AC is ON eFan should run at the FAN_STAGE_LOW_PRESSURE
stage = FAN_STAGE_AT_LOW_PRESSURE;
}

Serial.printf("Fan stage %d\n", stage);
Expand Down
21 changes: 6 additions & 15 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#define AC_INPUT PA5

#define AC_PRESSURE_TYPE PA4
#define AC_PRESSURE_SENSOR_TYPE PA4
#define AC_PRESSURE_SWITCH_HIGH PA6
#define AC_PRESSURE_SENSOR PB0

Expand All @@ -15,22 +15,13 @@
#define CAN_ICL2 0x613
#define CAN_ICL3 0x615

#define CAN_INTERVAL 200
#define CAN_INTERVAL 200 // milliseconds

#define MIN_FAN_STAGE 1
#define MAX_FAN_STAGE 15

#define FAN_STAGE_AT_LOW_PRESSURE 4
#define FAN_STAGE_AT_HIGH_PRESSURE 12

const byte FAN_STAGE_TO_HEX[15] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0};

STM32_CAN Can1(CAN1, DEF);

unsigned long previousCANMillis = 0;
CAN_message_t outCanMsg;

int previousACStatus = LOW;
#define FAN_STAGE_AT_LOW_PRESSURE 3
#define FAN_STAGE_AT_HIGH_PRESSURE 10

void initialize();
void processCan(long currentMillis);
Expand All @@ -40,14 +31,14 @@ void processCan(long currentMillis);
// https://www.ms4x.net/index.php?title=CAN_Bus_ID_0x613_ICL2
void processCanICL2();
// https://www.ms4x.net/index.php?title=CAN_Bus_ID_0x615_ICL3
void processCanICL3();
void processCanICL3(long currentMillis);

/*
* On E36 the pressure switch is a ON/OFF. On E46 a pressure sensor is used.
* Is it possible to replace a pressure switch with a pressure sensor to achieve a more linear
* activation of the fan stage.
*/
byte calculateFanStage(int acStatus);
byte calculateFanStage(int acStatus, long currentMillis);
byte calculateFanStateWithPressureSensor(int acStatus);
byte calculateFanStageWithPressureSwitch(int acStatus);
byte readTemperatureSensor();
Expand Down

0 comments on commit c458ef5

Please sign in to comment.