Товары из Китая

GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)


  • Цена: $2.21
  • Впереди середина зимы и самые сильные морозы. Многим предстоит столкнуться с проблемой разряда АКБ своих автомобилей. Каждый решает данную проблему по-своему: кто-то собирает старт джамперы на суперконденсаторах, кто-то использует литиевые паурбанки, кто-то же забирает АКБ на ночь домой. Лично я, учитывая свою специфику использования авто, решил собрать простой GSM сигнализатор на базе Arduino Pro Mini и GSM-модуля SIM800L, который уведомит меня, если заряд АКБ достигнет критического значения.

    Зачем все это?

    Аккумулятору в моем авто уже 8 лет. С одной стороны, несмотря на свой возраст, он еще ни разу не подводил даже в сильные морозы. Однако с другой стороны, приходит понимание того, что жизненный цикл АКБ скоро закончится. Подкрепилось оно недавним случаем довольно тяжелого запуска после длительного простоя на морозе — стартеру едва хватило тока для пуска двигателя. Неуверенность в надежности подуставшего АКБ также усугубляется рваным графиком поездок на авто: бывает 1000 км за несколько дней, а бывает неделя простоя без поездок. Наиболее естественным и простым решением данной проблемы было бы просто заменить АКБ на новый. Однако инженер-экспериментатор, сидящий внутри меня, не может сдаться так быстро. Поэтому начался поиск альтернативных решений, способных продлить жизнь старому АКБ. Одним их таких решений является суперконденсаторный старт джампер, недавно здесь как раз был описан DIY проект оного. Устройство мне понравилось, но по стоимости оно выходит почти как новый АКБ, а ведь аккум все равно придется рано или поздно заменить (не лазить же под капот при каждом запуске). Поэтому я решил пойти другим путем и сделать недорогое устройство, которое бы просто информировало о том, что заряд АКБ приближается к критическому значению (в первую очередь при длительном простое авто). Так можно своевременно зарядить аккумулятор путем запуска двигателя.

    Выбор комплектующих

    Подобные устройства уже существуют на рынке (некоторые сигнализации с автозапуском, GPS трекеры и т.п.). Однако все они обладают рядом существенных на мой взгляд недостатков: дороговизна, внедрение в проводку авто, передача данных об авто через сторонние интернет-серверы и др. Мне же хотелось простое дешевое устройство, работающее с минимальным вмешательством в проводку авто, не зависящее от сторонних серверов и выполняющее сугубо поставленную задачу.

    Наиболее простым, дешевым и всеядным с точки зрения распространения сигнала решением, на мой взгляд, по-прежнему является GSM диапазон. Тем более у меня уже есть опыт использования мобильной связи для получения данных с Ардуино. В 2018 я публиковал обзор: GSM передатчик показаний счетчиков воды на базе модуля SIM800L (DIY). Данное устройство себя отлично показало в плане надежности и энергоэффективности, бесперебойно проработав без малого три года на одном заряде небольшого литиевого АКБ. Актуальность данная разработка уже потеряла, поэтому было решено переделать её под новую задачу, тем более что почти весь необходимый функционал в ней уже есть.

    Итак, в основе устройства лежат два модуля: плата Arduino Pro Mini, которая производит необходимые измерения и формирует пакет данных, а также GSM-модуль SIM800L, который передает необходимые данные по сотовой сети.

    Функционал и схема

    Основные функции, требуемые от устройства:

    — постоянное измерение и усреднение напряжение АКБ автомобиля;

    — периодическая отправка данных о напряжении АКБ на заданный номер;

    — в случае, если напряжение АКБ ниже заданного порогового значения — немедленная отправка СМС, а также звонок;

    — фильтрация «лженизкого» напряжения АКБ — например, когда работает магнитола и/или другие потребители при выключенном двигателе;

    — подключение двумя проводами в OBD2 разъем (питание в диагностическом OBD2 разъеме авто присутствует всегда);

    — низкое потребление тока, чтобы не разряжать АКБ дополнительно.

    В итоге родилась следующая схема. Ниже комментарии к каждой её части.

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    1. Простой делитель входного напряжения на двух резисторах.

    2. Стабилизатор питания на 4,2 В.

    Напряжение питания бортовой сети авто нестабильно и меняется в широких пределах от ~7 до 15 В. Плата Arduno и GSM модуль рассчитаны на питание от 4..4,2 В. Также для точного измерения напряжения питание платы Arduino должно быть как можно более стабильным, т.к. напряжение питания выступает в роли опорного для АЦП. Подходящего DC/DC преобразователя у меня не оказалось, поэтому я решил использовать популярный линейный понижающий преобразователь LM317 (а точнее его низкотемпературного собрата LM217). Однако он плохо показал себя с точки зрения стабильности выходного напряжения в широком диапазоне температур. Выходом стал простой источник опорного напряжения TL431 (очень часто встречаются в компьютерных БП). В даташите на него уже приведена схема стабилизированного источника питания на 5В, мне оставалось лишь подобрать резисторы R3 и R4 так, чтобы на выходе было 4,2 В.Такое решение обладает очень хорошей температурной стабильностью (об этом чуть позже).

    3. Конденсатор C1 очень важен для стабильной работы GSM модуля. Емкость снижать не рекомендую.

    4. Полевой транзистор, отключающий GSM-модуль. На самом деле можно обойтись без него, т.к. модуль имеет режим энергосбережения, который можно активировать программно (с приемлемым для данного проекта током потребления ~1мА). Но аппаратное отключение было реализовано в проекте-доноре, поэтому было решено его оставить.

    Далее эта несложная схема была реализована на кусочке макетной платы:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Программная часть

    Ниже под спойлером приведен код прошивки. Постарался закомментировать его максимально подробно. Помимо напряжения, я также добавил функцию измерения температуры чипа Atmega328P, оно не отличается особой точностью, но примерное представление о температуре (с точностью в пару градусов) получить можно.

    Скетч
    #include <SoftwareSerial.h>                         // Стандартная библиотека для виртуального последовательного порта
    
    #include <LowPower.h> // Библиотека эффективного сна
    SoftwareSerial SIM800(9, 8); // Виртуальные RX, TX
    #define Vcc 4.201 // опорное напряжение с TL431
    #define k 3.915 // коэффициент делителя напряжения
    #define count 43200 // с какой переодичностью после выкл двиг отправлять СМС © - 12ч
    unsigned long tick = count - 600; // первое тестовое СМС будет отправлено через 600 сек (10 мин)
    unsigned long engOn = 0;
    float Vbat;
    float Vmin;
    float u;
    double temp;

    void setup() {
    pinMode(2, OUTPUT); // Управление транзистором, через который подключен GSM модуль
    digitalWrite(2, LOW); // Состояние по-умолчанию: выключен
    Vbat = analogRead(A2) * Vcc * k / 1024; // Начальные значения Vbat, Vmin и температуры temp
    Vmin = Vbat;
    temp = GetTemp();
    }
    void loop() {
    u = analogRead(A2) * Vcc * k / 1024; // в цикле измеряем мгновенное напряжение u
    if (u > 13.2) { // если оно больше 13,2 В - двигатель запущен
    engOn++; // ведем отсчет кол-ва секунд работы двигателя
    if (engOn > 1200) tick = 0; // если двигатель работает более 20 мин (1200с), считаем АКБ заряженным и обнуляем таймер отправки отчетных СМС
    LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); // сон 1 сек
    } else if (u < (Vbat - 0.1)) { // если напряжение меньше 13,2 В и изменилось скачком на 0,1 и более вольт
    checkVmin(); // вызов функции неперерывного определения минимального напряжения Vmin
    } else { // если напряжение меньше 13,2 В и НЕ изменилось скачком на 0,1 и более вольт
    Vbat = 0.9 * Vbat + 0.1 * u; // обновляем средние Vbat и temp
    temp = 0.9 * temp + 0.1 * GetTemp();
    if (u < Vmin) Vmin = u; // обновляем Vmin
    tick++; // отсчитываем 1 сек
    engOn = 0; // обнуляем счетчик работы двигателя engOn
    LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); // сон 1 сек
    if (tick > count) { // если счетчик переодической отправки достиг порогового значения
    sendSMS(0); // вызываем функцию отправки СМС без звонка (0 в скобках)
    tick = 0; // обнуляем счетчик отправки СМС
    }
    if (Vbat < 12.3) { // если среднее напряжение менее 12,3 В
    sendSMS(1); // вызов функции отправки СМС со звонком (1 в скобках)
    for (int i = 0; i < 6 * 3600; i++) { // сон 6 часов (3600c*6)
    LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
    }
    }
    }
    }
    void checkVmin() { // функция непрерывного измерения минимального напряжения
    unsigned long timer = millis() + 2 * 60000; // длительность работы функции (2 мин)
    while (timer > millis()) {
    u = analogRead(A2) * Vcc * k / 1024; // измерерние u
    if (u < Vmin) Vmin = u; // обносление значение Vmin
    }
    Vbat = u; // обновление среднего значение Vbat перед выходом из функции
    }
    void sendSMS(boolean call) { // Функция отправки СМС и звонка
    digitalWrite(2, HIGH); // Включаем GSM модуль
    delay(30000); // Пауза для установки связи
    SIM800.begin(9600); // Скорость обмена данными с модемом
    delay(500); // Дожидаемся передачи команды по Serial и даем GSM модулю 0,5 с на выполнение команды
    SIM800.println("AT"); // Автонастройка скорости
    delay(500);
    SIM800.println("AT+CMGF=1"); // Включить TextMode для СМС
    delay(500);
    SIM800.println("AT+CMGS="+798549xxx03""); // Номер, на который шлем СМС
    delay(500);
    SIM800.println("Vbat: " + String(Vbat, 2) + " V, Vmin: " + String(Vmin, 2) + " V, t: " + String(temp, 1) + " degC" + "rn" + (String)((char)26)); // Формирование текста СМС
    Vmin = Vbat; // Обнуление значение Vmin
    delay(30000); // Пауза 30 сек на отправку СМС
    if (call) { // Если call = 1, то передаем модулю команду набора номера
    SIM800.println("ATD+798549xxx03;");
    delay(30000); // Пауза на осуществление звонка
    }
    SIM800.println("AT+CPOWD=1"); // Команда выключения
    SIM800.flush(); // Очистка послед. порта
    delay(2000);
    digitalWrite(2, LOW); // Обесточиваем GSM модуль
    }
    double GetTemp(void) // Функция получения температуры чипа (найдена на просторах сети)
    {
    unsigned int wADC;
    double t;
    ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
    ADCSRA |= _BV(ADEN); // enable the ADC
    delay(20); // wait for voltages to become stable.
    ADCSRA |= _BV(ADSC); // Start the ADC
    while (bit_is_set(ADCSRA, ADSC)); // Detect end-of-conversion
    wADC = ADCW; // Reading register "ADCW" takes care of how to read ADCL and ADCH.
    t = (wADC - 324.31 ) / 1.22; // The offset of 324.31 could be wrong. It is just an indication.
    return (t); // The returned temperature is in degrees Celsius.
    }

    Логика работы его следующая (разумеется все пороговые напряжения подлежат изменению):

    1. Если напряжение в сети автомобиля больше 13,2 В, что говорит о работе генератора — ничего не делаем, МК спит;

    2. Если напряжение меньше 13,2 В, но больше 12,3 В, то обновляем показания с усреднением 1 раз в сек; отправляем СМС о напряжении и температуре 1 раз в 12 часов (тестовый режим).

    3. Если напряжение меняется скачком более чем на 0,1 В от среднего, то на 2 мин включается функция непрерывного измерения напряжения с фиксацией минимального значения (система ждет запуска двигателя). Это реализовано для оценки «провала» напряжения при запуске, что также является косвенным признаком износа АКБ.

    4. Если среднее напряжение АКБ ниже 12,3 В — отправляем СМС, осуществляем звонок.

    Пороговое значение 12,3 В — спорный момент. Возможно, это значение будет скорректировано в будущем. Я выбрал его на основании изучения таблиц заряда АКБ (типа той, что ниже) как примерно соответствующее 50-60% заряда:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Напряжение АКБ и температура фильтруются с помощью функции скользящего среднего:

    Vbat = 0.9*Vbat + 0.1*u;

    то есть каждое новое значение на 90% состоит из предыдущего значения и на 10% из вновь измеренного. Коэффициенты можно изменять (в сумме должна быть 1), это будет влиять на скорость изменения фильтруемой величины, как и частота вызова функции. Данная функция очень удобна своей простотой, а также позволяет существенно повысить точность измерения. Я часто её применяю при работе с аналоговыми сигналами.

    Благодаря тому, что измерения производятся с низкой частотой (1 сек), а между ними МК спит, ток потребления весьма скромен и составляет ~1,6 мА. Сколько-нибудь заметно ощущаться аккумулятором авто такой ток не будет.

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Итоговый вид устройства в разобранном и собранном виде:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Контакты подключения сделаны из жести, необходимые размеры: ширина — 1,8 мм, толщина 0,8 мм. Подключаются в гнезда 4/5 (земля) и 16 (+12 В). Распиновка разъема OBD2:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Устройство в работе

    Первым делом испытания морозильной камерой на предмет корректности измерений при низких температурах. Здесь полный порядок — показания корректны и не изменяются при снижении температуры:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    Далее установка в авто и тестирование:

    GSM сигнализатор о разряде АКБ автомобиля за 5$ (DIY)

    1-ое СМС на скрине выше:

    12,69 В — текущее усредненное напряжение АКБ, 11,39 В — минимальное (при срабатывании замков дверей, приводов складывания зеркал), температура -7,6 °С

    2-ое СМС:

    12,69 В — текущее усредненное напряжение АКБ, минимальное 6,39 В (был запуск двигателя). Меня такое значение смутило — показалось низким даже для старого АКБ. Позже также с помощью платы Ардуино была снята «осциллограмма» напряжения непосредственно на клеммах АКБ при запуске (просьба отписаться если интересно как сделать это). Минимальное значение составило 7,4 В. Вывод — 1 В — падение напряжения на клеммах и проводах.

    3е и 4е СМС:

    Сообщения, отправленный по заданному интервалу 12ч (тестовый режим), в последствии планирую увеличить до 24 либо 48 часов.

    Можно заметить, что в последних двух СМС Vmin больше Vbat, этот баг я уже поправил в коде выше.

    Также был добавлен сброс таймера отправки СМС по расписанию, если двигатель после запуска работает более 20 мин. Это позволит сэкономить деньги на СМС при регулярных поездках — когда двигатель авто запускается чаще, чем период отправки СМС.

    Итог

    Устройство находится в работе вторую неделю. СМС уведомления успешно приходят по расписанию. Однако, из-за частых поездок и относительно высокой температуры воздуха, оценить снижение АКБ в простое пока не удалось. На следующей неделе в Москве обещают до -30°С — по результатам работы системы дополню обзор.

    Также в планах доработать прошивку еще одной функцией — измерением dV/dt, то есть считать изменение напряжения за единицу времени. Например, если напряжение АКБ падает на 0,1 В за час или быстрее, то, вероятно, не выключен какой-то потребитель. В этом случае можно посылать уведомление/звонок не дожидаясь разряда до 12,3 В.

    P.S.

    Читая комментарии прихожу к выводу, что основная функция устройства многими интерпретируется некорректно. Основная задача устройства не отловить пороговое напряжение АКБ, при котором мотор едва запустится, а проинформировать заранее. Поэтому выбрано относительно высокое пороговое напряжение 12,3 В. Возможно, оно будет еще увеличено. То есть непосредственных действий при получении СМС уведомлений не нужно (например посреди ночи).


СМОТРИ ТАКЖЕ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *