// =====объявим константы========
#define LED_PIN 13 //пин светодиода на плате (уже припаян к 13-му выводу)
#define ADC_PIN A0 //пин измерения напряжения (можно использовать любой А вывод (А0...A7))
#define MOSFET_PIN 2 //пин управления транзистором (любой пин кроме 0,1,13,A6,A7,ADC_PIN)
#define VREF 5000 // опорное напряжение (питание ардуино), мВ
#define K_DEVIDER 3 //коэффициент делителя (R1+R2)/R2
#define DELAY_TIME 300000 // время задержки отключения питания, мс
#define OFF_VOLTAGE 10000 //пороговое напряжение отключения регистратора, мв
#define ON_VOLTAGE 10500 //пороговое напряжение включения регистратора, мв
// завершили объявлять константы
//создаём глобальные переменные
bool low_Voltage = true; //запоминаем текущее состояние АКБ (напряжения низкое или нет)
uint32_t serial_time; //переменная для запоминания времени последней отправки данных в Serial
//Настроим порты ввода-вывода
void setup() { // эта часть кода выполнится один раз при подаче питания
pinMode(ADC_PIN, INPUT); // сообщим что ADC_PIN будет входом (мерять напряжеие)
pinMode(MOSFET_PIN, OUTPUT); // сообщим что MOSFET_PIN будет выходом (выдавать напряжение)
pinMode(LED_PIN, OUTPUT); // сообщем что на светодиод будем подавать напряжение
Serial.begin(115200); // инициализируем передачу по серийному порту (если хотим)
}
//основной цикл
void loop() { //эта часть кода будет в бесконечном цикле
if ((batt_voltage() < OFF_VOLTAGE) and (low_Voltage == false)) { // если напряжение ниже порога, но напряжение включено
Serial.println("Low Voltage"); // выведем сообщение Low Voltage
digitalWrite(LED_PIN, LOW); // погасим светодиод
low_Voltage = true; // присвоим переменной low_Voltage логическую 1
uint32_t start_time = millis(); // создадим переменную таймера и запишем в неё текущее время в мс
while ((millis() - DELAY_TIME) > start_time) { // будем выполнять цикл пока не пройдёт DELAY_TIME время.
show_voltage();
if (batt_voltage() > ON_VOLTAGE) { // если в вдруг напряжение стало выше порога включения
digitalWrite(LED_PIN, HIGH); // зажигаем светодиод
low_Voltage = false; // переменной low_Voltage присвоим логический 0
break; // досрочно выходим из цикла
}
}
if (low_Voltage) { // если переменная low_Voltage имеет логическую 1
Serial.println("Power OFF"); // выведем сообщение Power OFF
digitalWrite(MOSFET_PIN, LOW); // закроем транзистор и отключим питание от нагрузки (регистратора)
}
}
if ((batt_voltage() > ON_VOLTAGE) and (low_Voltage == true)) { // если напряжение выше порога включения, но напряжение отключено
Serial.println("Power ON"); // если транзистор выключен - напишем сообщение Power ON
digitalWrite(LED_PIN, HIGH); // зажжём светодиод
low_Voltage = false; // переменной low_Voltage присвоим логический 0
digitalWrite(MOSFET_PIN, HIGH); // откроем транзистор и подадим питание на нагрузку
}
show_voltage();
}
//конец бесконечного цикла
//функция показа напряжения каждую секунду
void show_voltage(){
if ((millis() - 1000) > serial_time) { // каждую секунду
serial_time = millis(); //сбрасываем таймер чтоб заново отсчитывать секунду
Serial.println(batt_voltage() / 1000); // выведем в терминал текущее напряжение акб
}
}
//функция измерения напряжения (усреднение по 16-и замерам)
float batt_voltage() {
float current_voltage = 0; //создаём переменную с плавающей запятаой
for (int i = 0; i < 16; i++) {
current_voltage += analogRead(ADC_PIN); //добавляем в неё значения АЦП (0...1024) 16 раз
}
current_voltage /= 16; // делим на 16 - получаем значение от 0 (0 В) до 1024 (15 В)
current_voltage = current_voltage / 1024 * VREF * K_DEVIDER; // переводим полученное значение в милливольты
return current_voltage; //возвращаем полученное значение
}