Spaces:
Running
Running
File size: 3,683 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 |
#include "idle_control.h"
#include "config.h"
#include <Arduino.h>
#include "maps.h"
IdleController::IdleController() :
targetRPM(800),
currentPosition(0),
lastUpdateTime(0),
isAirConditionerOn(false),
engineTemp(20.0),
engineControl(nullptr),
pid(0.1, 0.05, 0.02) // Начальные значения коэффициентов ПИД
{
}
void IdleController::begin() {
// Настройка ШИМ каналов для РХХ
ledcSetup(0, IDLE_VALVE_PWM_FREQ, IDLE_VALVE_PWM_RES); // Канал 0 для пина A
ledcSetup(1, IDLE_VALVE_PWM_FREQ, IDLE_VALVE_PWM_RES); // Канал 1 для пина B
ledcAttachPin(IDLE_VALVE_PIN_A, 0); // Привязываем пин A к каналу 0
ledcAttachPin(IDLE_VALVE_PIN_B, 1); // Привязываем пин B к каналу 1
// Начальные значения ШИМ
ledcWrite(0, 0);
ledcWrite(1, 0);
// Инициализация ПИД-регулятора
pid.SetMode(true); // Включаем автоматический режим
pid.SetOutputLimits(0, 255);
pid.SetSampleTime(50);
lastUpdateTime = millis();
// Установка начального положения
updateValvePosition(0);
}
void IdleController::updateValvePosition(float position) {
position = constrain(position, 0, 255);
currentPosition = position;
// Преобразование позиции в ШИМ
int pwmValue = mapf(position, 0, 255, 0, (1 << IDLE_VALVE_PWM_RES) - 1);
// Управление моторчиком РХХ
ledcWrite(0, pwmValue);
ledcWrite(1, 0);
}
void IdleController::update(float currentRPM) {
unsigned long currentTime = millis();
float dt = (currentTime - lastUpdateTime) / 1000.0;
lastUpdateTime = currentTime;
// Проверяем наличие объекта управления двигателем
if (!engineControl) return;
// Получаем текущую температуру двигателя
float engineTemp = engineControl->getEngineTemp();
// Корректируем целевые обороты в зависимости от температуры
float adjustedTargetRpm = targetRPM;
if (engineTemp < 60) { // Если двигатель холодный
adjustedTargetRpm += (60 - engineTemp) * 6.67f; // Увеличиваем на 400 RPM при 0°C, линейно уменьшая до 60°C
}
// Добавляем компенсацию для кондиционера
if (isAirConditionerOn) {
adjustedTargetRpm += 50; // Увеличиваем на 50 RPM при включенном кондиционере
}
// Обновляем ПИД
pid.SetSetpoint(adjustedTargetRpm);
pid.SetInput(currentRPM);
if (pid.Compute()) {
// Применяем выход ПИД к положению РХХ
setPosition(pid.GetOutput());
}
}
void IdleController::setEngineTemperature(float temp) {
engineTemp = temp;
}
void IdleController::setAirConditioner(bool isOn) {
isAirConditionerOn = isOn;
}
void IdleController::loadSettings() {
// Здесь должна быть загрузка настроек из EEPROM или SD
// Пока используем значения по умолчанию
settings.targetRPM = 800;
settings.valveMinPosition = 0;
settings.valveMaxPosition = 255;
settings.rpmTolerance = 50;
}
void IdleController::saveSettings() {
// Здесь должно быть сохранение настроек в EEPROM или SD
}
|