Всем привет!
Я в программировании не сильно силен, кое-что понимаю, но в целом «дуб».
Передо мной стала задача сделать себе контроллер ДХО на ардуино.
Принцип такой…
В качестве дхо используются лампы противотуманок, управление по плюсу через реле(пин D3)
К пину А1 подключен через делитель провод + с авто, через него контролируется напряжение, чтобы понять заведен двигатель или нет.
К пину D7 так же через делитель подключен провод от зажигания.
К пину D5 аналогично зажиганию подключен провод от ближнего света (+).
Логика должна быть такая.
1) если зажигание включено и напряжение в бортсети выше 13.1В - включаем ДХО через 2 секунды.
2) если при любых условиях включается ближний, дхо тухнут. Если горели то тухнут, если только выполнилось 1 условие и одновременно включен ближний, то и не загораются.
3) после выключения ближнего, но при соблюдении 1 условия, ДХО снова включаются через 2 секунды.
4) при выключении зажигания, дхо тухнут.
5) если перед выключением зажигания, ближний был включен 60 секунд, то мы включаем дхо на 30 секунд.(вежливый свет в ночное время).
все это я закинул в чатжпт, он с горем пополам выдал мне скетч ниже…
Работает все, кроме 4 пункта. Он хаотично может сам включиться при выключении зажигания, даже если ближний не был включен. Либо ближний буквально пару секунд проработал и выключился, но все равно после выключения зажигания включается реле на 30 секунд. Иногда даже когда ближний в момент выключения зажигания был выключен, а включался пару секунд назад. Реле выключается и сразу же включается снова на 30 секунд.
И этот косяк я так и не смог побороть с нейросетью. Его исправления уже ведут к полному отказу. Скетч вообще толком не работает.
Еще есть косяк с таймером выключения дхо в обычном режиме, просто не работает. Но тут уже ладно, пускай выключается сразу.
В общем нужна помощь в поправке кода чтобы он работал. Что не так здесь? Может кто-то так подскажет(с учетом того что я не сильно силен тут, мне чем подробнее тем лучше), может за символическую плату доведет до ума?
В самом коде более менее ориентируюсь.
Заранее спасибо!
Еще нюанс. Сейчас, если выключить эту функцию «вежливого света» , выставить 0 вместо 30 секунд, то происходит двойной щелчок реле
Я в программировании не сильно силен, кое-что понимаю, но в целом «дуб».
Передо мной стала задача сделать себе контроллер ДХО на ардуино.
Принцип такой…
В качестве дхо используются лампы противотуманок, управление по плюсу через реле(пин D3)
К пину А1 подключен через делитель провод + с авто, через него контролируется напряжение, чтобы понять заведен двигатель или нет.
К пину D7 так же через делитель подключен провод от зажигания.
К пину D5 аналогично зажиганию подключен провод от ближнего света (+).
Логика должна быть такая.
1) если зажигание включено и напряжение в бортсети выше 13.1В - включаем ДХО через 2 секунды.
2) если при любых условиях включается ближний, дхо тухнут. Если горели то тухнут, если только выполнилось 1 условие и одновременно включен ближний, то и не загораются.
3) после выключения ближнего, но при соблюдении 1 условия, ДХО снова включаются через 2 секунды.
4) при выключении зажигания, дхо тухнут.
5) если перед выключением зажигания, ближний был включен 60 секунд, то мы включаем дхо на 30 секунд.(вежливый свет в ночное время).
все это я закинул в чатжпт, он с горем пополам выдал мне скетч ниже…
Работает все, кроме 4 пункта. Он хаотично может сам включиться при выключении зажигания, даже если ближний не был включен. Либо ближний буквально пару секунд проработал и выключился, но все равно после выключения зажигания включается реле на 30 секунд. Иногда даже когда ближний в момент выключения зажигания был выключен, а включался пару секунд назад. Реле выключается и сразу же включается снова на 30 секунд.
И этот косяк я так и не смог побороть с нейросетью. Его исправления уже ведут к полному отказу. Скетч вообще толком не работает.
Еще есть косяк с таймером выключения дхо в обычном режиме, просто не работает. Но тут уже ладно, пускай выключается сразу.
В общем нужна помощь в поправке кода чтобы он работал. Что не так здесь? Может кто-то так подскажет(с учетом того что я не сильно силен тут, мне чем подробнее тем лучше), может за символическую плату доведет до ума?
В самом коде более менее ориентируюсь.
Заранее спасибо!
Скетч:
// Определение пинов
const int pinIgnition = 7; // Пин зажигания
const int pinLowBeam = 5; // Пин ближнего света
const int pinRelayDRL = 3; // Пин реле ДХО (ПТФ)
const int pinVoltage = A1; // Пин для измерения напряжения бортсети
// Пороговые значения
const float voltageThreshold = 13.1; // Пороговое напряжение для включения ДХО
const unsigned long delayDRLOn = 2000; // Задержка на включение ДХО (2 секунд)
const unsigned long delayDRLOff = 0; // Задержка на выключение ДХО (1 секунд)
const unsigned long delayAfterIgnitionOff = 30000; // ДХО включены на 30 секунд после выключения зажигания
const unsigned long lowBeamCheckTime = 60000; // Время проверки, был ли включен ближний свет за 60 секунд
// Переменные
bool drlState = false; // Состояние ДХО (включено/выключено)
unsigned long drlOnTimer = 0; // Таймер для задержки включения ДХО
unsigned long drlOffTimer = 0; // Таймер для задержки выключения ДХО
unsigned long lowBeamLastOnTime = 0; // Последнее время включения ближнего света
bool ignitionPrevState = false; // Предыдущее состояние зажигания
// Настройки фильтрации
const int filterSamples = 5; // Количество образцов для фильтрации
int ignitionReadings[filterSamples]; // Массив для хранения образцов зажигания
int lowBeamReadings[filterSamples]; // Массив для хранения образцов ближнего света
void setup() {
pinMode(pinIgnition, INPUT);
pinMode(pinLowBeam, INPUT);
pinMode(pinRelayDRL, OUTPUT);
digitalWrite(pinRelayDRL, LOW); // По умолчанию ДХО выключено
Serial.begin(9600);
// Инициализация массивов
for (int i = 0; i < filterSamples; i++) {
ignitionReadings[i] = 0;
lowBeamReadings[i] = 0;
}
}
void loop() {
// Чтение и фильтрация сигналов
bool ignitionOn = filterInput(pinIgnition, ignitionReadings);
bool lowBeamOn = filterInput(pinLowBeam, lowBeamReadings);
float voltage = readVoltage();
unsigned long currentTime = millis();
// Лог для отладки
Serial.print("Ignition: "); Serial.print(ignitionOn);
Serial.print(", LowBeam: "); Serial.print(lowBeamOn);
Serial.print(", Voltage: "); Serial.println(voltage);
// Обновление времени включения ближнего света
if (lowBeamOn) lowBeamLastOnTime = currentTime;
// Условия управления ДХО
handleDRL(ignitionOn, lowBeamOn, voltage, currentTime);
// Обновляем предыдущее состояние зажигания
ignitionPrevState = ignitionOn;
}
// Функция фильтрации входного сигнала
bool filterInput(int pin, int* readings) {
// Сдвигаем значения в массиве
for (int i = filterSamples - 1; i > 0; i--) {
readings[i] = readings[i - 1];
}
readings[0] = digitalRead(pin); // Читаем текущее значение
// Рассчитываем среднее значение
int sum = 0;
for (int i = 0; i < filterSamples; i++) {
sum += readings[i];
}
return sum / filterSamples > 0.5; // Возвращаем истинное значение, если среднее больше 0.5
}
// Функция управления ДХО
void handleDRL(bool ignitionOn, bool lowBeamOn, float voltage, unsigned long currentTime) {
// Условие для включения ДХО
if (ignitionOn && voltage > voltageThreshold && !lowBeamOn) {
if (!drlState) {
if (drlOnTimer == 0) drlOnTimer = currentTime; // Запуск таймера
if (currentTime - drlOnTimer >= delayDRLOn) {
drlState = true;
digitalWrite(pinRelayDRL, HIGH); // Включаем ДХО
Serial.println("DRL включено");
}
}
} else {
drlOnTimer = 0; // Сбрасываем таймер включения
}
// Условие для выключения ДХО
if (drlState && (!ignitionOn || voltage <= voltageThreshold)) {
if (drlOffTimer == 0) drlOffTimer = currentTime; // Запуск таймера
if (currentTime - drlOffTimer >= 1000) { // Задержка 1 секунда для стабилизации
drlState = false;
digitalWrite(pinRelayDRL, LOW); // Выключаем ДХО
Serial.println("DRL выключено");
}
} else {
drlOffTimer = 0; // Сбрасываем таймер выключения
}
// Если включен ближний свет, немедленно выключаем ДХО
if (drlState && lowBeamOn) {
drlState = false;
digitalWrite(pinRelayDRL, LOW); // Выключаем ДХО
Serial.println("DRL выключено из-за ближнего света");
}
// Проверка состояния ближнего света после выключения зажигания
if (!ignitionOn && ignitionPrevState) {
if (lowBeamLastOnTime + lowBeamCheckTime > currentTime) {
if (!drlState) { // Если ДХО выключено, включаем
drlState = true;
digitalWrite(pinRelayDRL, HIGH); // Включаем ДХО на 30 секунд
Serial.println("DRL включено на 30 секунд после выключения зажигания");
unsigned long endTime = currentTime + delayAfterIgnitionOff;
while (millis() < endTime) {
// Ждем 30 секунд, ничего не делаем
}
drlState = false; // После задержки выключаем
digitalWrite(pinRelayDRL, LOW);
Serial.println("DRL выключено после задержки");
}
} else {
drlState = false; // Оставляем ДХО выключенными
digitalWrite(pinRelayDRL, LOW);
Serial.println("DRL осталось выключено после выключения зажигания");
}
}
}
// Функция для чтения напряжения бортсети через делитель
float readVoltage() {
int sensorValue = analogRead(pinVoltage);
return sensorValue * (5.0 / 1023.0) * ((1000.0 + 470.0) / 470.0); // Учитываем делитель напряжения
}
Изменено: