Spaces:
Running
Running
File size: 3,638 Bytes
96a5049 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#include "engine_control.h"
#include "config.h"
#include <Arduino.h>
// Вспомогательные функции для преобразования значений
float mapf(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
EngineControl::EngineControl() :
rpm(0),
map(0),
tps(0),
lambda(0),
knockLevel(0),
engineTemp(0),
voltage(0),
learningEnabled(false),
knockEvents(0),
currentFuelCorrection(1.0),
currentIgnitionCorrection(0.0)
{
}
void EngineControl::begin() {
// Настройка пинов
pinMode(HALL_SENSOR_PIN, INPUT);
pinMode(MAP_SENSOR_PIN, INPUT);
pinMode(TPS_PIN, INPUT);
pinMode(LAMBDA_SENSOR_PIN, INPUT);
pinMode(ENGINE_TEMP_SENSOR_PIN, INPUT);
pinMode(BATTERY_VOLTAGE_PIN, INPUT);
pinMode(KNOCK_SENSOR_1_3_PIN, INPUT);
pinMode(KNOCK_SENSOR_4_5_PIN, INPUT);
// Загрузка таблиц обучения
fuelLearning.load();
ignitionLearning.load();
}
void EngineControl::update() {
// Чтение сенсоров
rpm = analogRead(HALL_SENSOR_PIN);
map = analogRead(MAP_SENSOR_PIN);
tps = analogRead(TPS_PIN);
lambda = analogRead(LAMBDA_SENSOR_PIN);
engineTemp = analogRead(ENGINE_TEMP_SENSOR_PIN);
voltage = analogRead(BATTERY_VOLTAGE_PIN);
// Преобразование значений АЦП
rpm = mapf(rpm, 0, 4095, 0, 7000);
map = mapf(map, 0, 4095, 0, 100);
tps = mapf(tps, 0, 4095, 0, 100);
lambda = mapf(lambda, 0, 4095, 0.7, 1.3);
engineTemp = mapf(engineTemp, 0, 4095, -40, 150);
voltage = mapf(voltage, 0, 4095, 0, 15);
if (learningEnabled && rpm > START_RPM_THRESHOLD) {
float engineLoad = map; // В данном случае используем MAP как нагрузку
// Обучение топливоподачи по лямбда-зонду
if (lambda < 0.98) {
fuelLearning.update(engineLoad, rpm, 0.98);
} else if (lambda > 1.02) {
fuelLearning.update(engineLoad, rpm, 1.02);
}
// Чтение датчиков детонации
float knock1 = analogRead(KNOCK_SENSOR_1_3_PIN);
float knock2 = analogRead(KNOCK_SENSOR_4_5_PIN);
knockLevel = max(knock1, knock2);
// Обучение УОЗ по детонации
ignitionLearning.learn(engineLoad, rpm, knockLevel);
// Если была детонация, увеличиваем счетчик
if (knockLevel > DETONATION_THRESHOLD) {
knockEvents++;
}
}
// Получение текущих коррекций
float engineLoad = map;
currentFuelCorrection = fuelLearning.getCorrection(engineLoad, rpm);
currentIgnitionCorrection = ignitionLearning.getCorrection(engineLoad, rpm);
}
float EngineControl::getLearningProgress() const {
return (fuelLearning.getProgress() + ignitionLearning.getProgress()) / 2.0;
}
float EngineControl::getIgnitionAdvance() {
float engineLoad = map;
float baseAdvance = 10.0; // Базовый УОЗ
// Добавляем коррекцию от обучения
float ignitionCorr = ignitionLearning.getCorrection(engineLoad, rpm);
return baseAdvance + ignitionCorr;
}
bool EngineControl::saveLearningTables() {
return fuelLearning.save() && ignitionLearning.save();
}
bool EngineControl::loadLearningTables() {
return fuelLearning.load() && ignitionLearning.load();
}
|