P.S. Данный пост не говорит как делать правильно, а лишь описывает путь пройденный мной и с чем я столкнулся . Никого не призываю повторять, если только есть опытный в этом человек так как код может быть не идеален .
1 часть
Есть такая задача. Сделать не дорогой автозапуск для авто с простейшими элементами и с минимум вложений , чтобы был лишь автозапуск без лишнего геморроя и со всеми нужными функциями.
Что мы имеем ?
1. Сама сигнализация, стоимость её около 10у.е.( да ребят я из Беларуси=)

2.Arduino nano
3.Огромное желание что то смастерить самому без знания основ программирования.
Наше ТЗ
1.Чтобы машина запускалась с задержкой после включения зажигания ( так как выходной сигнал на стартер с этого модуля около 1 секунды, наша задача выждать время для прогрева свечей в зимнее время или для срабатывания подкачивающих насосов и так далее)
2. Чтобы было отключение стартера поле того как машина завелась ( реализация такова что когда машина завелась на лампочку генератора приходит +12 Вольт, эти 12 вольт будут сигналом для отключения программы ардуино)
3. Чтобы задержка перед пуском была на разное время ( меня интересует 2 режима работы, когда двигатель холодный то задержка перед подачей сигнала на стартер должно составлять 10 секунд , когда двигатель уже 40 градусов или более то задержка 2 секунды и на запуск, сигнал на запуск не менее 4 секунд, реализовать это не сложно так как датчик ОЖ(охлаждающей жидкости) это обычный NTC терморезистор и из него нужно вынуть показания, пределы таковы если R<=150 Om (тогда задержка 2 секунды) если R>=400 Ом (тогда задержка 10 секунд) промежуточное значение от 150 до 400 (так же с задержкой 10 секунд)
4. После завершения сигнала на выход или получения сигнала +12 вольт с генератора программа должна остановиться и ждать следующего сигнала на запуск с модуля.
Я человек в этой истории новый но знаю про ИИ) Поэтому изначально обратился к нему за просьбой, после суток извращения с ним и разными предложениями по написанию кода со всеми проверками на WOKWI я нашел единственно работающий примерно по моему ТЗ код .
Самая большая проблема и мольва о помощи, помочь допилить код со всеми доработками и правильными измерениями.
Вот такое ТЗ я поставил ИИ :
Давай напишем новый код для ардуино нано. Действия программы такие:
При кратковременной подаче напряжения +12В на пин запускалась программа.
Программа должна измерять какое NTC сопротивления подаеться на ввод, есть два выбора работы программы.
1 если сопротивление ровно 150 Ом и до 0 Ом тогда программа задерживает сигнал на 2 секунды и дает на выход сигнал длинною 4 секунд
2 если сопротивление ровно 400 Ом и до 1000 Ом тогда программа задерживает сигнал на 10 секунды и дает на выход сигнал длинною 4 секунд
Должен быть еще пин который управляется кратковременным подачей +12 вольт , при появлении на нем +12 вольт или истечению времени выходного сигнала программа должна остановиться и запустить лишь тогда когда снова подадим на ввод +12 вольт
все действия должны писать Serial.println
Не кидайте камнями я вообще в этом ДУБ ) Есть только желание что то сделать самому и не тратить очень много времени для написания одной программы.
ВОТ ЧТО МНЕ ДАЛ ИИ (Сделано ИИ , используете на свой страх и риск)
P.S. для проверки на WOWKI я указал что входной сигнал +5 В а сигнал стоп это GND . На самом деле было очень много кодов сделанных ИИ но это примерно похожий по логике работы который нужен мне.
Заранее извиняюсь если есть какие либо ошибки по добавлению поста или темы .
Не знаю выйдет из этого поста что либо но очень надеюсь что найдется знающий человек который будет готов помочь в данном деле. Заранее всех благодарю за содействие и огромный привет Alex
2 часть
Прошло несколько недель с момента первой примерки кода и проверки его ) На данный момент логика немного переработана и сделана более податлива для дальнейших настроек в случае если кто то захочет повторить. Код был немного доработан и собран для проверке на машине. Пока все проверки проводились на столе с использованием резисторов для понимания как работает программа , какая погрешность и в чем проблемы.
Что необходимо:
Для управления входных сигналов - реле 12 вольт
Для выходного сигнала - реле 5 вольт (так как нужно коммутировать 12 вольтовый сигнал)
Для защиты - парочка диодов
Для подтягивающего сопротивления - взято сопротивление 5 кОм
Для эталонного сопротивления - взято сопротивление 10 кОм
Для управления - Ардуино нано
Для питания ардуино - 5 вольтовый стабилизатор
Для ардуино сделан такой код. (Сделано ИИ , используете на свой страх и риск)
Данный код можно подправлять под каждые показания своего термистора . Сделать это не сложно зная значение сопротивление термистора при его температуре. Чем больше данных тем точнее работа и правильность показаний.
Данные расчеты будут верны если эталонное сопротивление будет подключено к 5 вольт и к аналоговому входу а0, а уже наш термистор соответственно через GND к а0.
Логика работы кода:
При кратковременной подаче напряжения +12В на пин запускается программа.
Программа измеряет какое NTC сопротивления подаеться на ввод. Дальше есть два выбора работы программы.
1 если температура больше или равна 10 *С программа задерживает сигнал на 1 секунду и дает на выход сигнал длинною 2.5 секунд
2 если температура меньше 10 *С тогда программа задерживает сигнал на 10 секунды и дает на выход сигнал длинною 2.5 секунд
Аварийный стоп ( в моем случаем +12 вольт после того как пошла зарядка генератора, можно использовать что то другое) как только появился сигнал программа прекращает работы и ждет следующей подачи сигнала 12 вольт на управляющий пин. Все действия пишуться в Serial.println для отладки работы программы ( комментаторы говорят что это мешает работы программы, следуя их совету после полной проверки лучше удалить).
Что получилось на макетной плате.


Не судите строго ) Понятное дело что можно сделать лучше, но для моих нужд достаточно. Лучше все проверить внимательно, схема предоставлена для наглядности
На данном этапе вся схема работает исправно все сигналы видит правильно, расчет сопротивления верный , есть погрешность но для моих целей этого более чем достаточно.
Если есть идеи как что либо улучшить, предлагайте.
1 часть
Есть такая задача. Сделать не дорогой автозапуск для авто с простейшими элементами и с минимум вложений , чтобы был лишь автозапуск без лишнего геморроя и со всеми нужными функциями.
Что мы имеем ?
1. Сама сигнализация, стоимость её около 10у.е.( да ребят я из Беларуси=)

2.Arduino nano
3.Огромное желание что то смастерить самому без знания основ программирования.
Наше ТЗ
1.Чтобы машина запускалась с задержкой после включения зажигания ( так как выходной сигнал на стартер с этого модуля около 1 секунды, наша задача выждать время для прогрева свечей в зимнее время или для срабатывания подкачивающих насосов и так далее)
2. Чтобы было отключение стартера поле того как машина завелась ( реализация такова что когда машина завелась на лампочку генератора приходит +12 Вольт, эти 12 вольт будут сигналом для отключения программы ардуино)
3. Чтобы задержка перед пуском была на разное время ( меня интересует 2 режима работы, когда двигатель холодный то задержка перед подачей сигнала на стартер должно составлять 10 секунд , когда двигатель уже 40 градусов или более то задержка 2 секунды и на запуск, сигнал на запуск не менее 4 секунд, реализовать это не сложно так как датчик ОЖ(охлаждающей жидкости) это обычный NTC терморезистор и из него нужно вынуть показания, пределы таковы если R<=150 Om (тогда задержка 2 секунды) если R>=400 Ом (тогда задержка 10 секунд) промежуточное значение от 150 до 400 (так же с задержкой 10 секунд)
4. После завершения сигнала на выход или получения сигнала +12 вольт с генератора программа должна остановиться и ждать следующего сигнала на запуск с модуля.
Я человек в этой истории новый но знаю про ИИ) Поэтому изначально обратился к нему за просьбой, после суток извращения с ним и разными предложениями по написанию кода со всеми проверками на WOKWI я нашел единственно работающий примерно по моему ТЗ код .
Самая большая проблема и мольва о помощи, помочь допилить код со всеми доработками и правильными измерениями.
Вот такое ТЗ я поставил ИИ :
Давай напишем новый код для ардуино нано. Действия программы такие:
При кратковременной подаче напряжения +12В на пин запускалась программа.
Программа должна измерять какое NTC сопротивления подаеться на ввод, есть два выбора работы программы.
1 если сопротивление ровно 150 Ом и до 0 Ом тогда программа задерживает сигнал на 2 секунды и дает на выход сигнал длинною 4 секунд
2 если сопротивление ровно 400 Ом и до 1000 Ом тогда программа задерживает сигнал на 10 секунды и дает на выход сигнал длинною 4 секунд
Должен быть еще пин который управляется кратковременным подачей +12 вольт , при появлении на нем +12 вольт или истечению времени выходного сигнала программа должна остановиться и запустить лишь тогда когда снова подадим на ввод +12 вольт
все действия должны писать Serial.println
Не кидайте камнями я вообще в этом ДУБ ) Есть только желание что то сделать самому и не тратить очень много времени для написания одной программы.
ВОТ ЧТО МНЕ ДАЛ ИИ (Сделано ИИ , используете на свой страх и риск)
C++:
const int inputPin = 2; // Пин старта (активен +5V)
const int stopPin = 3; // Пин СТОП (активен GND)
const int outputPin = 4; // Выход
const int resistancePin = A0; // Пин сопротивления
// Пороги сопротивления (настроить!)
const int RESISTANCE_150OHM = 680;
const int RESISTANCE_400OHM = 350;
// Переменные состояния
bool buttonPressed = false;
unsigned long triggerTime = 0;
unsigned long lastDebounceTime = 0;
const int debounceDelay = 50; // мс
void setup() {
pinMode(inputPin, INPUT); // БЕЗ подтяжки к VCC!
pinMode(stopPin, INPUT_PULLUP);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(stopPin), interruptHandler, FALLING);
}
void loop() {
// Чтение кнопки START с защитой от дребезга
int currentState = digitalRead(inputPin);
if (currentState == HIGH && !buttonPressed) {
if (millis() - lastDebounceTime > debounceDelay) {
buttonPressed = true;
triggerTime = millis();
Serial.println("Старт! Таймер запущен");
}
lastDebounceTime = millis();
}
// Логика таймера
if (buttonPressed) {
int sensorValue = analogRead(resistancePin);
unsigned long delayTime = 10000; // По умолчанию 10 сек
if (sensorValue >= RESISTANCE_150OHM) {
delayTime = 2000;
Serial.println("Режим 150 Ом (2 сек)");
}
else if (sensorValue <= RESISTANCE_400OHM) {
delayTime = 10000;
Serial.println("Режим 400 Ом (10 сек)");
}
if (millis() - triggerTime >= delayTime) {
digitalWrite(outputPin, HIGH);
Serial.println("Выход ВКЛ");
delay(5000); // Удерживаем 5 сек
digitalWrite(outputPin, LOW);
Serial.println("Выход ВЫКЛ");
buttonPressed = false;
}
}
}
void interruptHandler() {
digitalWrite(outputPin, LOW);
buttonPressed = false;
Serial.println("СТОП! Сброс таймера");
}
P.S. для проверки на WOWKI я указал что входной сигнал +5 В а сигнал стоп это GND . На самом деле было очень много кодов сделанных ИИ но это примерно похожий по логике работы который нужен мне.
Заранее извиняюсь если есть какие либо ошибки по добавлению поста или темы .
Не знаю выйдет из этого поста что либо но очень надеюсь что найдется знающий человек который будет готов помочь в данном деле. Заранее всех благодарю за содействие и огромный привет Alex
2 часть
Прошло несколько недель с момента первой примерки кода и проверки его ) На данный момент логика немного переработана и сделана более податлива для дальнейших настроек в случае если кто то захочет повторить. Код был немного доработан и собран для проверке на машине. Пока все проверки проводились на столе с использованием резисторов для понимания как работает программа , какая погрешность и в чем проблемы.
Что необходимо:
Для управления входных сигналов - реле 12 вольт
Для выходного сигнала - реле 5 вольт (так как нужно коммутировать 12 вольтовый сигнал)
Для защиты - парочка диодов
Для подтягивающего сопротивления - взято сопротивление 5 кОм
Для эталонного сопротивления - взято сопротивление 10 кОм
Для управления - Ардуино нано
Для питания ардуино - 5 вольтовый стабилизатор
Для ардуино сделан такой код. (Сделано ИИ , используете на свой страх и риск)
Новый код .:
#include <avr/wdt.h>
#include <avr/pgmspace.h> // Для работы с PROGMEM
// Константы пинов и общие параметры
const int startPin = 4;
const int stopPin = 3;
const int outputPin = 6;
const int sensorPin = A0;
const float R_25 = 10000.0;
const float VCC = 5.0;
// Обновлённые калибровочные данные из изображения
const int numPoints = 12;
// Таблицы перенесены в программную память для экономии ОЗУ
const float resistanceTable[numPoints] PROGMEM = {
7500.0, 6500.0, 4000.0, 3000.0, 2000.0, 1200.0,
900.0, 700.0, 500.0, 350.0, 270.0, 180.0
};
const float temperatureTable[numPoints] PROGMEM = {
-10.0, 0.0, 10.0, 20.0, 30.0, 40.0,
50.0, 60.0, 70.0, 80.0, 90.0, 100.0
};
// Объявление состояний системы
enum SystemState {
IDLE,
DELAY_PHASE,
OUTPUT_PHASE,
WAIT_START_RELEASE
};
// Переменные состояния
volatile SystemState currentState = IDLE;
volatile bool stopRequested = false; // Флаг для обработки прерывания в loop()
unsigned long lastDebounceTime = 0;
const unsigned long DEBOUNCE_DELAY = 50;
unsigned long phaseStartTime;
unsigned long currentDelayTime;
// Прототипы функций
float readTemperatureFromTable(float resistance);
float readTemperature(float* resistanceValue);
void printReadyState();
void setup() {
wdt_disable();
pinMode(startPin, INPUT); // Используем внешний pull-down резистор
pinMode(stopPin, INPUT); // Используем внешний pull-down резистор
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
Serial.begin(9600);
// Прерывание по нарастающему фронту (кнопка замыкает на +5V)
attachInterrupt(digitalPinToInterrupt(stopPin), emergencyStop, RISING);
Serial.println("=== ТЕРМОРЕГУЛЯТОР (С КАЛИБРОВКОЙ) ===");
printReadyState();
wdt_enable(WDTO_8S);
}
void loop() {
wdt_reset();
// Обработка флага экстренной остановки, установленного в прерывании
if (stopRequested) {
digitalWrite(outputPin, LOW);
currentState = WAIT_START_RELEASE;
stopRequested = false; // Сброс флага
Serial.println("\n!!! АВАРИЙНЫЙ СТОП !!!");
}
handleThermoregulator();
}
void handleThermoregulator() {
// Кнопка нажата, когда читается HIGH
int startButtonState = digitalRead(startPin);
int stopButtonState = digitalRead(stopPin);
switch(currentState) {
case IDLE:
if (startButtonState == HIGH && (millis() - lastDebounceTime > DEBOUNCE_DELAY)) {
lastDebounceTime = millis();
startSystem();
}
break;
case WAIT_START_RELEASE:
// В этом состоянии кнопка должна быть отпущена (LOW), чтобы вернуться в IDLE
if (startButtonState == LOW && (millis() - lastDebounceTime > DEBOUNCE_DELAY) && (stopButtonState == LOW)) {
lastDebounceTime = millis();
currentState = IDLE;
printReadyState();
}
break;
case DELAY_PHASE:
if (millis() - phaseStartTime >= currentDelayTime) {
startOutputPhase();
}
break;
case OUTPUT_PHASE:
if (millis() - phaseStartTime >= 2500) {
completeCycle();
}
break;
}
}
void startSystem() {
float resistance;
float temp = readTemperature(&resistance);
if (temp == -999.0) {
Serial.println("Система не запущена из-за ошибки датчика.");
return;
}
Serial.print("\nСтарт системы. Температура: ");
Serial.print(temp, 2);
Serial.print(" °C | Сопротивление: ");
Serial.print(resistance, 0);
Serial.println(" Ом");
currentDelayTime = (temp >= 10.0) ? 1000 : 10000;
Serial.print("Задержка: ");
Serial.print(currentDelayTime / 1000.0);
Serial.println(" сек");
currentState = DELAY_PHASE;
phaseStartTime = millis();
}
void startOutputPhase() {
currentState = OUTPUT_PHASE;
phaseStartTime = millis();
digitalWrite(outputPin, HIGH);
Serial.println("Выход АКТИВИРОВАН (2,5 сек)");
}
void completeCycle() {
digitalWrite(outputPin, LOW);
Serial.println("Цикл завершен");
currentState = WAIT_START_RELEASE;
}
// Функцию прерывания делаем максимально быстрой
void emergencyStop() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > DEBOUNCE_DELAY) {
stopRequested = true; // Просто устанавливаем флаг
}
lastInterruptTime = interruptTime;
}
// Функция для чтения температуры из таблицы с интерполяцией
float readTemperatureFromTable(float resistance) {
// Получаем первое значение сопротивления из PROGMEM
float firstResistance = pgm_read_float_near(resistanceTable);
// Если сопротивление выше максимального значения в таблице
if (resistance >= firstResistance) {
return pgm_read_float_near(temperatureTable);
}
// Получаем последнее значение сопротивления из PROGMEM
float lastResistance = pgm_read_float_near(&resistanceTable[numPoints - 1]);
// Если сопротивление ниже минимального значения в таблице
if (resistance <= lastResistance) {
return pgm_read_float_near(&temperatureTable[numPoints - 1]);
}
// Линейная интерполяция
for (int i = 0; i < numPoints - 1; i++) {
float res1 = pgm_read_float_near(&resistanceTable[i]);
float res2 = pgm_read_float_near(&resistanceTable[i + 1]);
if (resistance <= res1 && resistance >= res2) {
float temp1 = pgm_read_float_near(&temperatureTable[i]);
float temp2 = pgm_read_float_near(&temperatureTable[i + 1]);
float tempDiff = temp2 - temp1;
float resDiff = res1 - res2;
float resDelta = res1 - resistance;
return temp1 + (resDelta / resDiff) * tempDiff;
}
}
return -999.0;
}
// Функция чтения температуры с датчика, с добавленной отладочной информацией
float readTemperature(float* resistanceValue) {
int adcValue = analogRead(sensorPin);
Serial.print("ОТЛАДКА: Значение АЦП: ");
Serial.println(adcValue);
if (adcValue <= 0 || adcValue >= 1023) {
Serial.println("Ошибка датчика: нереалистичные показания АЦП!");
if (resistanceValue) *resistanceValue = 0;
return -999.0;
}
// Расчёт сопротивления термистора. Предполагается: Rx -> GND, R25 -> VCC
float resistance = R_25 * (float)adcValue / (1023.0 - (float)adcValue);
if (resistanceValue) *resistanceValue = resistance;
Serial.print("ОТЛАДКА: Рассчитанное сопротивление: ");
Serial.print(resistance, 0);
Serial.println(" Ом");
float temp = readTemperatureFromTable(resistance);
Serial.print("ОТЛАДКА: Интерполированная температура: ");
Serial.print(temp, 2);
Serial.println(" °C");
if (temp == -999.0 || temp < -50.0 || temp > 150.0) {
Serial.print("Ошибка датчика: аномальная температура (");
Serial.print(temp);
Serial.println(" °C).");
return -999.0;
}
return temp;
}
void printReadyState() {
Serial.println("Система готова к работе");
Serial.println("Для запуска подай +5В на pin2");
Serial.println("----------------------------");
}
Данные расчеты будут верны если эталонное сопротивление будет подключено к 5 вольт и к аналоговому входу а0, а уже наш термистор соответственно через GND к а0.
Логика работы кода:
При кратковременной подаче напряжения +12В на пин запускается программа.
Программа измеряет какое NTC сопротивления подаеться на ввод. Дальше есть два выбора работы программы.
1 если температура больше или равна 10 *С программа задерживает сигнал на 1 секунду и дает на выход сигнал длинною 2.5 секунд
2 если температура меньше 10 *С тогда программа задерживает сигнал на 10 секунды и дает на выход сигнал длинною 2.5 секунд
Аварийный стоп ( в моем случаем +12 вольт после того как пошла зарядка генератора, можно использовать что то другое) как только появился сигнал программа прекращает работы и ждет следующей подачи сигнала 12 вольт на управляющий пин. Все действия пишуться в Serial.println для отладки работы программы ( комментаторы говорят что это мешает работы программы, следуя их совету после полной проверки лучше удалить).
Что получилось на макетной плате.


Не судите строго ) Понятное дело что можно сделать лучше, но для моих нужд достаточно. Лучше все проверить внимательно, схема предоставлена для наглядности
На данном этапе вся схема работает исправно все сигналы видит правильно, расчет сопротивления верный , есть погрешность но для моих целей этого более чем достаточно.
Если есть идеи как что либо улучшить, предлагайте.
Изменено: