Охлаждение двигателя автомобиля. Снимаем вискомуфту, ставим "плавный" электровентилятор.
- Войдите на сайт для отправки комментариев
Очередная задача от дружище. Митусибиши паджеро спорт. Вискомуфта видать слабенькое место. у многих клинит и карлсон всегда вращается больше нужного, выстуживая ДВС. Зимой это плохо, расход топлива и холодный салон. Достался нахаляву электровентялятор от мерседеса 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(); }
}
Если кому интересна эта тема, спрашивайте.
Макс, зачем это все? У мерседеса все не слава богу, с него на японские машины детали ставить западло :)
Вместо визкомуфты ставьте обыкновенные электровентиляторы без "мозгов", которые включаются обычным датчиком за 50руб через обычное же реле :) - так делают все
Я то бы себе так и сделал, но чего не сделаешь для друга. ) Тем более как ему объяснить, что вентялтор тот уже б/у, и тем более от мерседеса, у которого всё "не слава богу".
интересна была исследовательская работа. Можно пойти дальше. отыскать в шине инфу о наружной t , t масла АКПП и тоже задествовать эти данные в управлении карлосоном.
интересна была исследовательская работа. Можно пойти дальше. отыскать в шине инфу о наружной t , t масла АКПП и тоже задествовать эти данные в управлении карлосоном.
Вполне вас понимаю :)
Лень двигатель прогресса. Для опроса факта включения кондиционера хотел изначально подавать с муфты включения компрессора +12В на вход ардуино, через оптопару конечно. Но т.к. тут велико ЭДС самоиндукции (муфта мощный эл. магнит) и лень было тянуть провода, нашел таки данную информацию в кан шине:
Включение кондиционера: сообщение с ID 445 байт №3 (начинается с нулевого), бит№3 (начинается с нулевого) - 1 включен, 0 - выключен.
Вдруг это кому поможет - кто будет ковырять CAN на паджеро спорт (возможно и на других моделях митсубиши такие же ID листы CAN шины).
Скетч чуть позже выложу с опросом А/С уже по CAN.
Скетч. Состояние А/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(); } }У мерседеса все не слава богу, с него на японские машины детали ставить западло :)
Ну да, вот и для дебилов КИА и Хюндай - легендарные автомобили.
Лень двигатель прогресса. Для опроса факта включения кондиционера хотел изначально подавать с муфты включения компрессора +12В на вход ардуино, через оптопару конечно. Но т.к. тут велико ЭДС самоиндукции (муфта мощный эл. магнит) и лень было тянуть провода, нашел таки данную информацию в кан шине:
Включение кондиционера: сообщение с ID 445 байт №3 (начинается с нулевого), бит№3 (начинается с нулевого) - 1 включен, 0 - выключен.
Вдруг это кому поможет - кто будет ковырять CAN на паджеро спорт (возможно и на других моделях митсубиши такие же ID листы CAN шины).
Скетч чуть позже выложу с опросом А/С уже по CAN.
Вечер добрый, как с вами можно связаться ???