Spaces:
Sleeping
Sleeping
| 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 | |
| } | |