Охлаждение двигателя автомобиля. Снимаем вискомуфту, ставим "плавный" электровентилятор.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Очередная задача от дружище. Митусибиши паджеро спорт. Вискомуфта видать слабенькое место. у многих клинит и карлсон всегда вращается больше нужного, выстуживая ДВС.  Зимой это плохо, расход топлива и холодный салон. Достался нахаляву электровентялятор от мерседеса W204 со своим блоком управления. Погуглив форум мерсоводов, узнал, что нужно подавать на блок управления  сигнал ШИМ 10Гц  10%. При таком сигнале вентилятор в покое, остановлен (если не подавать ничего - уходит в аварию и обороты на максмимум). Максимум оборотов соответствует ШИМ сигналу 90%. 

1. этап. Подключил выход 9 ардуино через транзистор BD139. При помощи библиотеки PWM.h получилось подать такой ШИМ сигнал. Вентилятором управлять научился. Далее нужно было определять температуру ДВС. 

2. этап. Получение инфы о температуре ДВС. Не хотелось ставить свой "ардуинский" датчик t . т.к. будут отклонения или же заморочки с внедрением прямо в полость циркуляции ОЖ. 

Поэтому, не ища лёгких путей , было решено найти данную информацию в CAN шине. Но насчёт наличия температуры ДВС в CAN шине были сомнения, т.к. щиток приборов аналоговый и на него идёт свой обычный аналоговый датчик t . 

Для анализа CAN шины можно сделать простой сниффер из ардуино и can модуля MCP2515 . Но у меня уже был куплен по-лучше. Fordometer. (Позволяет анализировать данные в графическом виде, не говоря о том что корректирует пробеги и пишет ключи на форды, но здесь не об этом).

Далее вместо штатного датчика t ДВС был установлен переменный резистор 0...10 кОм. Подцепили обычную ELM диагностику и начали вращать резистор , увидели, что у нас получается обманывать ЭБУ автомобиля, и что t ДВС в параметрах меняется от -11градусов до 120 градусов. 

Далее отцепили диагностику, воткнули анализатор CAN шины и начали вращать резистор. Записали лог данных шины. На графике по идее должны увидеть эдакие титьки (два раза вращали резистор от края до края).

Далее анализируя в CAN шине сообщение за сообщнием мои опасения на счёт отсутствия там температуры уже становились серьёзными, титек не было.

 

и вот полчаса пропялившись в экран, смотрю последнее сообщение с ID 608. И вот они ТИТЬКИ, ну почти

 

Короче в сообщении ID 608 нулевой байт отвечает за температуру ДВС. 

Формула такая t ДВС = 0 байт - 40

Далее написал скетч для плавного управления вентилятором в зависимтости от температуры ДВС и работы кондиционера. 

#include <PWM.h>
#include <mcp_can.h>
#include <SPI.h>

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);                               // Set CS to pin 10

#define CondPin    16
#define FANrelay   9
byte FANspeed = 0;                           //скорость вентилятора %
byte lastFANspeed = FANspeed;

bool     canOK = 1;  // состояние приёма нужного сообщения с кан шины
bool     A_C = 0;    // состояние кондиционера
bool     diag = 0;   //

int     EngTemp = 0; // t антифриза,  считанная с ЭБУ
int     ATTemp  = 0; // t масла АКПП, считанная с ЭБУ


unsigned long prev = 0;

int CoolTempOFF = 90; // t охл жидкости ДВС, меньше или равно которой полностью выключится вентилятор
int ATTempOFF =   83; // t масла АКПП, при которой выключится вентилятор
byte counter = 0;


void setup() {
InitTimersSafe();
SetPinFrequencySafe(FANrelay, 10);
pwmWrite (FANrelay,  230);

CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ);
  CAN0.init_Mask(0,0,0x07FF0000);                // Init first mask...
  CAN0.init_Filt(0,0,0x06080000);                // Init first filter...
  CAN0.init_Filt(1,0,0x06080000);                // Init second filter...
  CAN0.init_Mask(1,0,0x07FF0000);                // Init second mask... 
  CAN0.init_Filt(2,0,0x06080000);                // Init third filter...
  CAN0.init_Filt(3,0,0x06080000);                // Init fouth filter...
  CAN0.init_Filt(4,0,0x06080000);                // Init fifth filter...
  CAN0.init_Filt(5,0,0x06080000);                // Init sixth filter...
CAN0.setMode(MCP_NORMAL);

Serial.begin(9600);
pinMode (CondPin, INPUT_PULLUP);
pinMode (CAN0_INT,INPUT_PULLUP);                       // Setting pin 2 for /INT input

}




void loop() {
if (Serial.available()>0) {
  byte inbyte  = Serial.read();
       if (inbyte == '1') diag = 1;
  else if (inbyte == '0') diag = 0;
  }
////////////// прочитаем CAN шину 

if(!digitalRead(CAN0_INT))                    // If pin 2 is low, read receive buffer
    {
      uint32_t rxId = 0; byte len = 0; byte rxBuf[8]= {0};
      CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
      if (rxId == 0x608) {EngTemp = rxBuf[0]-40; counter = 0; canOK = 1;}
    }

// ниже действия раз в 500 мс

if (millis() - prev > 500){
  

A_C = !digitalRead(CondPin);               // проверяем состояние кондиционера , включен или выключен


////////////// распечатаем данные в монитор отладки

if (diag){
Serial.print (F("Engine Temp: ")); 
if (canOK) Serial.print (EngTemp); 
else Serial.print (F("CAN TEMP FAIL!")); 
Serial.print (F("   A/C: "));
if (A_C) Serial.print (F("ON")); else Serial.print (F("OFF"));
Serial.print (F("  FANspeed: ")); Serial.print (FANspeed);  Serial.print (F(" %"));
if (canOK) Serial.println (F("  CAN_OK!")); else Serial.println (F("  CAN_FAIL! EmergencyMode."));
}



////////////// управляем вентилятором в зависимости от t ДВС  и состояния A/C
if (canOK){
      if (EngTemp<= CoolTempOFF && ATTemp <= ATTempOFF && !A_C) FANspeed = 0;  //  полностью выключаем вентилятор 
else  if (A_C && EngTemp <= 97) FANspeed = 85;                                // если включен конд и t ДВС меньше 97 скорость 75%
else  if (EngTemp>90 && EngTemp <= 100) FANspeed = map (EngTemp, 91,100, 10, 99);
else  if (EngTemp>100) FANspeed = 100;}
else  FANspeed = 90;

 if (lastFANspeed!= FANspeed) { 
 byte pwm = map (FANspeed, 0, 100, 0 , 90); 
      pwm = constrain (pwm, 0, 90);
  pwmWrite (FANrelay,  230-(pwm*230/100)); lastFANspeed=FANspeed; }


////////////// счетчик, который растёт если не получаем нужного CAN сообщения, если достигает 15, то вентилятор в аварию (вкл. на 90%)
  counter ++ ; 
  if (counter >= 15) {counter = 15; canOK = false; } 
  prev = millis(); }

  

}

Если кому интересна эта тема, спрашивайте. 

b707
Offline
Зарегистрирован: 26.05.2017

Макс, зачем это все? У мерседеса все не слава богу, с него на японские машины детали ставить западло :) 

Вместо визкомуфты ставьте обыкновенные электровентиляторы без "мозгов", которые включаются обычным датчиком за 50руб через обычное же реле :) - так делают все

MaksVV
Offline
Зарегистрирован: 06.08.2015

Я то бы себе так и сделал, но чего не сделаешь для друга. ) Тем более как ему объяснить, что вентялтор тот уже б/у, и тем более от мерседеса, у которого всё "не слава богу". 

MaksVV
Offline
Зарегистрирован: 06.08.2015

интересна была исследовательская работа. Можно пойти дальше. отыскать в шине инфу о наружной t , t масла АКПП и тоже задествовать эти данные в управлении карлосоном. 

b707
Offline
Зарегистрирован: 26.05.2017

MaksVV пишет:

интересна была исследовательская работа. Можно пойти дальше. отыскать в шине инфу о наружной t , t масла АКПП и тоже задествовать эти данные в управлении карлосоном. 

Вполне вас понимаю :)

MaksVV
Offline
Зарегистрирован: 06.08.2015

Лень двигатель прогресса. Для опроса факта включения кондиционера хотел изначально подавать с муфты включения компрессора +12В на вход ардуино, через оптопару конечно. Но т.к. тут велико ЭДС самоиндукции (муфта мощный эл. магнит) и лень было тянуть провода, нашел таки данную информацию в кан шине: 

Включение кондиционера:  сообщение с ID 445 байт №3 (начинается с нулевого), бит№3 (начинается с нулевого)  - 1 включен, 0 - выключен. 

Вдруг это кому поможет - кто будет ковырять CAN на паджеро спорт (возможно и на других моделях митсубиши такие же ID листы CAN шины). 

Скетч чуть позже выложу с опросом А/С уже по CAN.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Скетч. Состояние А/C выполнено по CAN, чуть поправлен алгоритм управления вентилятором в зависимости от t ДВС. 

#include <PWM.h>
#include <mcp_can.h>
#include <SPI.h>

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);                               // Set CS to pin 10

#define CondPin    16                        // пин опроса состояния А/С по аналогу 
#define FANrelay   9                         // пин сигнала ШИМ
byte FANspeed = 0;                           // скорость вентилятора %
byte lastFANspeed = FANspeed;                // последняя скорость вентилятора

bool     canOK = 1;  // состояние наличия приёма нужного сообщения с кан шины о температуре ДВС
bool     A_C = 0;    // состояние кондиционера
bool     diag = 0;   // флаг вывода инфы в отладку

int     EngTemp = 0; // t антифриза,  считанная с ЭБУ

unsigned long prev = 0;  // переменная для таймера "раз в полсекунды"

byte counter = 0; // аварийный счетчик


void setup() {

// ниже настройки ШИМ
InitTimersSafe();
SetPinFrequencySafe(FANrelay, 10);
pwmWrite (FANrelay,  230);

// ниже настройки CAN и аппаратные фильтры приема сообщений
// по фильтрам настроен приём только двух сообщений - ID 608 и ID 445
pinMode (CAN0_INT,INPUT_PULLUP);                 // Setting pin 2 for /INT input
CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ);
  CAN0.init_Mask(0,0,0x07FF0000);                // Init first mask...
  CAN0.init_Filt(0,0,0x06080000);                // Init first filter...
  CAN0.init_Filt(1,0,0x06080000);                // Init second filter...
  CAN0.init_Mask(1,0,0x07FF0000);                // Init second mask... 
  CAN0.init_Filt(2,0,0x04450000);                // Init third filter...
  CAN0.init_Filt(3,0,0x04450000);                // Init fouth filter...
  CAN0.init_Filt(4,0,0x04450000);                // Init fifth filter...
  CAN0.init_Filt(5,0,0x04450000);                // Init sixth filter...
CAN0.setMode(MCP_NORMAL);

pinMode (CondPin, INPUT_PULLUP);  // вход для опроса состояния A/C по аналлогу. 

Serial.begin(9600);               // настройка порта вывода в терминал 

}




void loop() {
if (Serial.available()>0) {
  byte inbyte  = Serial.read();
       if (inbyte == '1') diag = 1;
  else if (inbyte == '0') diag = 0;
  }
////////////// прочитаем CAN шину 

if(!digitalRead(CAN0_INT))                    // если пришло нужное нам сообщение по CAN
    {
      uint32_t rxId = 0; byte len = 0; byte rxBuf[8]= {0};
      CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
           if (rxId == 0x608) {EngTemp = rxBuf[0]-40; counter = 0; canOK = 1;} // считываем tДВС и сбрасываем аварийный счетчик в ноль
      else if (rxId == 0x445) {A_C = bitRead(rxBuf[3], 3);}  // считываем состояние кондиционера (закоментировать для аналогового варианта)
    }

// ниже действия раз в 500 мс

if (millis() - prev > 500){
  

//A_C = !digitalRead(CondPin); // проверяем состояние кондиционера , включен или выключен (раскоментировать для аналогового варианта)


////////////// распечатаем данные в монитор отладки (в терминале на скорости 9600 без новой строки и каретки отправить 1 для вкл отладки, 0 - для отключения)

if (diag){
Serial.print (F("Engine Temp: ")); 
if (canOK) Serial.print (EngTemp); 
else Serial.print (F("CAN TEMP FAIL!")); 
Serial.print (F("   A/C: "));
if (A_C) Serial.print (F("ON")); else Serial.print (F("OFF"));
Serial.print (F("  FANspeed: ")); Serial.print (FANspeed);  Serial.print (F(" %"));
if (canOK) Serial.println (F("  CAN_OK!")); else Serial.println (F("  CAN_FAIL! EmergencyMode."));
}



////////////// управляем вентилятором в зависимости от t ДВС  и состояния A/C
if (canOK){
      if (EngTemp<= 90  && !A_C) FANspeed = 0;                                //  полностью выключаем вентилятор 
else  if (A_C && EngTemp <= 93) FANspeed = 30;                                //  если включен конд и t ДВС меньше 93 скорость 30%
else  if (EngTemp>90 && EngTemp <= 100) FANspeed = map (EngTemp, 91,100, 10, 99); // если tДВС от91 до 100 плавно рулим карлсоном. 
else  if (EngTemp>100) FANspeed = 100;}
else  FANspeed = 90;                                                          // если не получаем сообщений от CAN вентилятор в аварию (на 90%)

 if (lastFANspeed!= FANspeed) {                     // если скорость вентилятора изменилось то выполняем
 byte pwm = map (FANspeed, 0, 100, 0 , 90);         // переводим сигнал к варианту что 100 % скорости это 90% ШИМ (так работает вентилятор мерседес)
      pwm = constrain (pwm, 0, 90);                 // на всякий случай ограничиваем значение ШИМ от 0 до 90%
  pwmWrite (FANrelay,  230-(pwm*230/100)); lastFANspeed=FANspeed; }  // обновляем значение сигнала ШИМ


////////////// счетчик, который растёт если не получаем нужного CAN сообщения, если достигает 15, то вентилятор в аварию (вкл. на 90%)
  counter ++ ; 
  if (counter >= 15) {counter = 15; canOK = false; } 
  prev = millis(); }

  

}

 

NE_XT
NE_XT аватар
Offline
Зарегистрирован: 22.05.2012

b707 пишет:

У мерседеса все не слава богу, с него на японские машины детали ставить западло :)

Ну да, вот и для дебилов  КИА и Хюндай - легендарные автомобили.

troiaold
Offline
Зарегистрирован: 23.06.2022

MaksVV пишет:

Лень двигатель прогресса. Для опроса факта включения кондиционера хотел изначально подавать с муфты включения компрессора +12В на вход ардуино, через оптопару конечно. Но т.к. тут велико ЭДС самоиндукции (муфта мощный эл. магнит) и лень было тянуть провода, нашел таки данную информацию в кан шине: 

Включение кондиционера:  сообщение с ID 445 байт №3 (начинается с нулевого), бит№3 (начинается с нулевого)  - 1 включен, 0 - выключен. 

Вдруг это кому поможет - кто будет ковырять CAN на паджеро спорт (возможно и на других моделях митсубиши такие же ID листы CAN шины). 

Скетч чуть позже выложу с опросом А/С уже по CAN.

Вечер добрый, как с вами можно связаться ???