PDA

Просмотр полной версии : Блок питания для NEXUS7-2012,2013 или любого планшета -печатка, прошивка, инструкция


Страницы : [1] 2

oleg707
30.03.2018, 23:23
Поскольку в старой моей теме (http://pccar.ru/showthread.php?t=23236) накопилось много мусора ( и разных вариантов и версий блоков питания), тут выкладываю последнюю на данный момент модель своего блока питания.

Проект даётся ДАРОМ - то есть если вы имеете все необходимые детали и в состоянии повторить ( спаять, запрограммировать и т.п.), имеете оборудование для сборки, настройки и проверки, то УДАЧИ. :friends:( открытых аналогов проекта я до сих пор не видел).

Блоки на заказ больше не делаю. Тему поддерживаю, поскольку это хобби.

НОВАЯ ВЕРСИЯ блока c встроеннным хабом, юсб изолятором (гальваническая развязка), звуковой картой (аналоговый и цифровой выход), портом под изикап >>>> исходные файлы для самостоятельной сборки BP5.PLUS (http://pccar.ru/showpost.php?p=414804&postcount=298)

Это BP5mini (уже есть решения новее) , с оптимизированной печатной платой, который проехал со мной уже около 20000 км. Самая длинная поездка была почти сутки за раз. После трех поколений оптимизаций BP5mini развился в BP5mini+2.2
Блок отлично себя показал. Хорошо держит просадки напряжения (https://youtu.be/W_JQ5_Ru7d0) при старте.
Потребление блока питания в выключенном состоянии 0(Ампер)

Печатная плата и прошивка находятся тут (http://pccar.ru/showpost.php?p=406254&postcount=107), открывать в DipTrace (https://diptrace.com/rus/download/download-diptrace/)
Тестовые прошивки искать с конца темы или ТУТ (https://drive.google.com/drive/folders/1CE1Zw7LCBj_QRcN1BK0tEOqIdWEIlcdp?usp=sharing).

временные фото сделанные наспех, потом сфотографирую нормально
http://pccar.ru/attachment.php?attachmentid=49959&thumb=1&d=1531063871494644946549466

Инструкция по подключению (https://drive.google.com/open?id=10_ZZ0i-cSHM71u-uLxVaRlIOuGV7epXW), на базе BP5mini. Подключать можно не полностью, а МОДУЛЬНО ( то есть только батарею планшета и датчик холла, например)

Краткий принцип работы в виде файла (http://pccar.ru/showpost.php?p=403887&postcount=30) БП5mini (+поиск неисправностей)
Краткий принцип работы(описание на форуме) (http://pccar.ru/showpost.php?p=405633&postcount=39) БП5mini (+поиск неисправностей)
Рекомендованный порядок настройки БП после сборки (http://pccar.ru/showpost.php?p=406984&postcount=130).

Для тех, кто не может скомпилировать скетчи, выкладываю свою сборку (одну из) ардуино.
https://mega.nz/#!FlhiWTgZ!fhH_QTRTFIWeh5Uid1rigkZSrDTmov-sHJEXG-538Sc
https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing

Для контроля значений, которые прописаны в памяти процессора.
Чтение и запись настроек пользователя из памяти процессора. (http://pccar.ru/showpost.php?p=402466&postcount=21)

Очень хорошая информация про аккумуляторы (https://electrotransport.ru/ussr/index.php?topic=2103.0)

Ссылка на свежайшие версии файлов. Синхронизируются с моим компьютером (http://pccar.ru/showpost.php?p=406918&postcount=129).
Часто задаваемые вопросы
Кратко о моей конфигурации.
NEXUS-7-2012-wifi (еще новый покупал). Батарея у меня выкинута вместе с контроллером. Датчик холла выпаян, БП включает режим OTG. В ЮСБ также подключен хаб, в котором только звуковая карта.

Как устроено автоматическое отключение планшета при вытаскивании ключа?
При вытаскивании ключа ( выключении зажигания) на датчик холла планшета подаётся масса, экран тухнет, планшет засыпает.
После суток ожидания (время настраивается) с батареи планшета убирается подпитка (4,0В). Масса на датчике холла остается.


Может у Вас есть рисованная схема как у Вас реализовано подключение?
Пока нет. И вряд ли будет, потому как обвязка, допустим, микросхемы ( конденсаторы, резисторы) смотрится в даташите и соответствует рекомендованной производителем. Поэтому вместо одной детали в теории ( на схеме) легко мождет стать 5 деталей на практике ( на печатной плате).

Продаете ли вы свой блок питания?
Да, пишите в личку. С учетом того, что я смог приблизить процесс к производственному, снизилась цена и улучшилось качество.[/QUOTE]

Какой корпус подходит для вашего блока питания?
У каждого свои запросы касаемо корпуса. Некоторые встраивают всё в большой корпус 2-дин магнитолы, некоторые хотят только алюминиевый ( из условий безопасности и теплоотвода), некоторым вообще корпус не нужен. Понимая, что я всё равно не могу разработать абсолютно универсального решения, я просто постарался сделать плату как можно меньше, но не в ущерб теплоотдаче и безопасности.

Можно ли изменить время сна/включения/выключения/ожидания, значения напряжений разряженного аккумулятора?
ВСЕ значения при необходимости меняются в скетче ( программе управления). Я постарался каждое значение снабдить подробным комментарием.
По умолчанию все уже настроено так, как работает у меня в машине, то есть ничего менять не нужно. Но если вы хотите что-либо изменить под себя,
то вот пример из скетча:
//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 2 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

const byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
byte reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = timeUntilALLOff; // пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long rezerv3 =0;
unsigned long rezerv4 =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

Требуется ли калибровка блока питания?
После сборки самостоятельно, в зависимости от точности ваших резисторов, погрешность измерений напряжений аккумулятора и плюса после замка зажигания может колебаться +- 0,2В.
Для того, чтобы не подбирать резисторы и не думать, как изменить программу управления (скетч) я добавил калибровку блока с записью в энергонезависимую память процессора (EEPROM). Память при обновлении прошивок не стирается.
Для калибровки нужно сделать процедуру (https://youtu.be/MmqlD5PbX7Q). ( на примере прапрадедушки БП5мини).
У тех, кто покупал у меня блоки питания, калибровка уже выполнена.

логика работы BP5mini
Полный алгоритм блока сложный, идёт проверка многих условий ( например выключили зажигание или просто стартуем, от
этого меняется скорость выключения планшета, чтобы при старте не моргал а при штатном выключении быстро тух экран,
перезарядка, начало зарядки генератора перед включением REM после заводки и многое другое - я постарался привести
состояние работы машины к логике работы современных автомобилей. ),
Поэтому полный принцип работы можно посмотреть в скетче.
Все тайминги меняются, порядок включения и выключения пинов тоже меняется. Просто правим скетч под себя (если
нужно).

-----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
Проверили напряжения. Если всё нормально, то примерный алгоритм такой:

Через 0,1с включаем самозапитку процессора
Через 1,1с включаем питание на батарею планшета.
Через 1,2с включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. (*можно не подключать, опционально)
Через 1,3с включаем минус на Y-OTG (включается определение перифирии планшетом).
Через 1,4с Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб.
Через 1,7с включаем питание на видеорегистратор, выход REM.
Через 2,0с включаем экран.
То есть ПОЛНОЕ время включения 2 секунды.

-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
выключаем усилитель звука (REM).
Через 1,0с тушим экран (если прошло 2 минуты с момента включения блока )
пауза 3с чтобы не 'пукал' усилитель при отключении звуковой карты
Через 3,0с вЫключаем минус на Y-OTG, ВЫключаем хаб
через 3,5с вЫключаем +5V зарядки.
Через 7,0с тушим подсветку LCD дисплея 1602 I2C (https://duino.ru/lcd-1602-arduino) ( *если установлен)

Через 2 суток вЫключаем питание на батарею планшета.
Через 4 суток выключаем питание на видеорегистратор, самозапитку процессора, при этом система ПОЛНОСТЬЮ обесточивается.

поведение встроенного светодиода:
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает
Логику работы почти полностью можно перенастроить под себя в скетче. Если вам не хватает какого-либо режима или поведения БП - пишем в личку или вотсапп, по возможности добавляю ваши пожелания в прошивку (скетч).


осциллограммы БП5mini на машине (видео) (https://www.youtube.com/watch?v=qJyoExxWB94&feature=youtu.be)
температура mini360 при нагрузке планшетом (https://www.youtube.com/watch?v=0uxpHuceYlI&feature=youtu.be)

_________________________________________________
_________________________________________________
_________________________________________________
По изготовлению блока питания на заказ писать в личку.

Вопросы можно позадавать на вотсапп, вайбер +485семь3три978484.

oleg707
30.03.2018, 23:27
rezerv

oleg707
16.04.2018, 01:06
тестируя собранные блоки, столкнулся с интересной особенностью dc-dc (mini360) (https://duino.ru/Step-Down-mini.html), но я думаю, это ко всем относится.

На тесте под нагрузкой пропадало на мгновение напряжение на выходе +5В. Так раз в минут 5.
Померил температуру - 95-104°C :015: - очень много, микросхема включает аварийную защиту по перегреву.
К сравнению, на исправных DC-DC температура обычно не превышает 50-55°C ( при токе 1А).
Причём в холостом режиме абсолютно нормально работал, разве что ток был на 0,1- 0,15А больше.
Разбираться не было времени,хоть и было любопытно, микросхема или обвязка, поменял целиком.
Так что я теперь еще пирометром температуру контролирую.:beach:

skanch
16.04.2018, 10:48
На готовых китайских модулях MP1584 решается заменой керамики по входу и выходу (последнее особенно важно).
И если "доводить" до абсолютных параметров, то китайскую обвязку нужно менять согласно даташиту производителя - ты и сам это знаешь...Но в даташите тоже даны усредненные значения при подборе компонентов. И только экспериментальным путем можно "вычислить золотую середину", когда и частота в норме, и пульсации на выходе минимальны, и естественно нагрев под полной нагрузкой незначителен.
Кстати - в "программе для разработчика" от MPS тоже не все гладко и выдаваемые параметры нужно корректировать в реальных условиях.

YAM1966
16.04.2018, 11:24
Через меня прошло уже штук 400 этих mini360 (https://duino.ru/Step-Down-mini.html). Покупаю на али.
Нормальные имеют собственный ток потребления ~6мА, попадаются экземпляры с токами от 10 до 60мА, я считаю это браком и требую от продавца досылку или возврата.
Те, что имеют больший ток в последствии могут даже без нагрузки разогреваться до ~60C.

oleg707
16.04.2018, 22:01
На готовых китайских модулях MP1584 решается заменой керамики по входу и выходу (последнее особенно важно).
И если "доводить" до абсолютных параметров, то китайскую обвязку нужно менять согласно даташиту производителя - ты и сам это знаешь...Но в даташите тоже даны усредненные значения при подборе компонентов. И только экспериментальным путем можно "вычислить золотую середину", когда и частота в норме, и пульсации на выходе минимальны, и естественно нагрев под полной нагрузкой незначителен.
Кстати - в "программе для разработчика" от MPS тоже не все гладко и выдаваемые параметры нужно корректировать в реальных условиях.

Саша, у меня керамика и по входу, и по выходу, дополнительно к модулям. В случае неисправного модуля мне проще поменять его целиком, чем тратить время на поиск неисправного элемента. С остальным - согласен.



Через меня прошло уже штук 400 этих mini360. Покупаю на али.
Нормальные имеют собственный ток потребления ~6мА, попадаются экземпляры с токами от 10 до 60мА, я считаю это браком и требую от продавца досылку или возврата.
Те, что имеют больший ток в последствии могут даже без нагрузки разогреваться до ~60C.
При каком входном - выходном напряжении норм ток 6мА? При этом никаких дополнительных конденсаторов для проверки, я так понимаю, не ставишь?

YAM1966
16.04.2018, 22:49
При каком входном - выходном напряжении норм ток 6мА? При этом никаких дополнительных конденсаторов для проверки, я так понимаю, не ставишь?
12В. Для проверки - голый модуль. Выходное значения не имеет.

НСО154
17.04.2018, 05:29
я считаю это браком и требую от продавца...

Странно конечно.
Считает он)

oleg707
30.04.2018, 09:36
для тех, кто не может скомпилировать скетчи, выкладываю свою сборку ( одну из) ардуино.

https://mega.nz/#!FlhiWTgZ!fhH_QTRTFIWeh5Uid1rigkZSrDTmov-sHJEXG-538Sc

https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing

oleg707
02.05.2018, 13:23
Ребят, нужны советы.
При сборке БП5mini есть такой момент, что управление дс-дс, который идёт на зарядку и на хаб происходит через предназначенный для этого производителем контакт на микросхеме преобразователя ( EN).
То есть нужно подпаяться к этому контакту на микросхеме. Это и есть тот проводок на фото.
Появилась мысль убрать выход +12В на видео регистратор и освободившийся канал включить на управление дс-дс зарядки и хаба, как это сделано в дс-дс, питающим батарею планшета.
При этом даже изменения прошивки не потребуется.

Есть ещё мысли убрать ардуину и поставить голый проц ( на крайний случай перейти на промини, она дороже и могут быть танцы с бубном при прошивке).

То же самое касается дс-дс. Мне проще собрать на печатной плате готовый дс-дс, рассчитанный конкретно под планшет, а не как у китайцев.

Мне вообще без проблем, но ВЫ, как простые пользователи, сможете ли повторить ? И отремонтировать, в случае поломки? Пока, как показала практика, модульный монтаж и ремонт сэкономил людям кучу времени и денег.

mazay66
02.05.2018, 17:17
Ребят, нужны советы.
При сборке БП5mini есть такой момент, что управление дс-дс, который идёт на зарядку и на хаб происходит через предназначенный для этого производителем контакт на микросхеме преобразователя ( EN).
То есть нужно подпаяться к этому контакту на микросхеме. Это и есть тот проводок на фото.
Появилась мысль убрать выход +12В на видео регистратор и освободившийся канал включить на управление дс-дс зарядки и хаба, как это сделано в дс-дс, питающим батарею планшета.
Не вижу особой разницы в методе получения +5В для питания хаба. Оба варианта приемлемы. Зачем менять отработанную схему? Хотя "хозяин-барин". Я, например, знаю точно, что организовать питание планшета с необходимыми задержками можно на простом таймере с транзистором. Без ардуино и проца. А контроль за напряжением бортовой сети выполнять через контакт (EN) подобрав, соответствующим образом делитель напряжения. Ну это другая история. Каждый вариант БП имеет права быть.

oleg707
02.05.2018, 19:48
Не вижу особой разницы в методе получения +5В для питания хаба. Оба варианта приемлемы. Зачем менять отработанную схему? Хотя "хозяин-барин". Я, например, знаю точно, что организовать питание планшета с необходимыми задержками можно на простом таймере с транзистором. Без ардуино и проца. А контроль за напряжением бортовой сети выполнять через контакт (EN) подобрав, соответствующим образом делитель напряжения. Ну это другая история. Каждый вариант БП имеет права быть.
Одному надо 11,9в и 2 часа задержки, другому 11, 4 и 2 суток. А если ещё хочется поэкспериментировать с задержками...
Так что я без проца уже никуда, посмотри программу, там под тысячу строк кода. Причём эту логику ни одно аппаратное решение не повторит.

Обработанная и та, и та схема. Канал на батарею так сделан, просто подали питание через интеллектуальный ключ, дс-дс включился.

Мнение "Зачем менять отработанную схему?"засчитано.

mazay66
02.05.2018, 21:09
Полностью согласен с тем, что запросы разные. Только нет секрета в том, что часть логики можно выполняться не блоком питания, а за счет софта установленного в планшете. Таскер прекрасно выключит планшет хоть через 2 минуты, хоть через 2-е суток, хоть через 2 месяца. Зачем "рубить" для этого питание материнки с БП?

oleg707
02.05.2018, 22:53
Полностью согласен с тем, что запросы разные. Только нет секрета в том, что часть логики можно выполняться не блоком питания, а за счет софта установленного в планшете. Таскер прекрасно выключит планшет хоть через 2 минуты, хоть через 2-е суток, хоть через 2 месяца. Зачем "рубить" для этого питание материнки с БП?

Да, я тоже так думал. Пока зависший планшет за выходные не высадил мне аккумулятор, а ехать надо было срочно.

mazay66
02.05.2018, 23:17
Не убедительный аргумент. Пошли "по второй кругу". Двумя постами выше сказано про использование контакта (EN). Он отключит питание планшета в аварийной ситуации.

oleg707
03.05.2018, 00:02
Не убедительный аргумент. Пошли "по второй кругу". Двумя постами выше сказано про использование контакта (EN). Он отключит питание планшета в аварийной ситуации.

Тут надо два круга объединять ))
С одной стороны имеем зависший планшет и аварийную защиту от полного разряда ( аппаратное решение), таймер на 555? для отключения каждого канала

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

Плюс мне нужно передергивание питания на хаб при каждом включении зажигания и хаба, независимый контроль REM с отключением через 30 минут при включении зажигания и не отключением при заведенном авто, ... ну и далее по списку ))))

К сожалению аппаратное решение давно не удовлетворяет моих запросов.

Хотя новичкам с минимальным бюджетом я иногда рекомендую поставить просто дс-дс и поездить, привыкнуть к кар-пс и понять, что им ещё не хватает, сам так полгода ездил.

skanch
03.05.2018, 09:15
...Я, например, знаю точно, что организовать питание планшета с необходимыми задержками можно на простом таймере с транзистором. Без ардуино и проца.
Как вариант имеет право на жизнь. Правда немного "громоздко" получается - на каждый управляемый канал нужно две микросхемы - таймера с обвязкой (одна на задержку включения, вторая на задержку выключения), плюс ключи для коммутации. А еще и "привязать" общую задержку на выключение во время кручения стартером... Мне - совсем не программисту проще использовать контроллер. Но, как правильно заметил - "хозяин-барин"... Вариантов исполнения может быть много и каждый выбирает конкретно под себя.
P.S. Я экспериментировал на микросхеме - таймере MIC 1555 (http://lib.chipdip.ru/427/DOC001427472.pdf). И размер для меня подходящий, и обвязки минимум. Но остановился всё-таки на использовании контроллера...

oleg707
11.05.2018, 01:41
пока в статусе бета тестирования.
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции.
Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером,
убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить. Отдельной переменной не создавал, искать по переменной STARTUEM

m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета
( для тех, у кого нету датчика холла но хочется подключится к кнопке питания для автоматического включения/выключения экрана).

const boolean HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета.

Если подключено как КНОПКА, то задержка перед нажатием "кнопки"
после включения АСС это SLEEP_timer_pri_vkl_ACC,
а после вЫключения это SLEEP_timer_pri_vykl_ACC.
Удержание нажатия = 0,5с.


byte ver = 30;// БЕТА( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini //выбор типа блока питания.
// дата правки 10.05.18.2326

// для 5mini версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .
/* _
хотелки


______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 5 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволило выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилок)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания - 318 строка
t08- ничего
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить. Отдельной переменной не создавал, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};

uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;

//************************************************** ************************************************** ***********************************************

#include <JeeLib.h> // Low power functions library //для сна
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей

// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей



//LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка дисплея для библиотеки LiquidCrystal_I2C2004V1
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например

LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347

float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024

//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа


//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

int PINrawACC = A0; // замер для 5й версии
int PINrawAKB = A1; // замер для 5й версии
int PINkalibrovki = A2; // замер для 5й версии

//int PINrawACC = A7; // замер для 7й версии
//int PINrawAKB = A8; // замер для 7й версии
//int PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.

//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И


const boolean reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
const boolean power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
const boolean power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
const boolean HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

const unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
const unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
const unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
const unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
const unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
const unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
const unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
const unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
const unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
const unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
const unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
const unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
const unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
const unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
const unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
const unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
const unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.

//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И






int vremia_sna_ATMEGI = 100; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================




void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзюком сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзюком питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; /* 16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки
{




Serial.begin(115200);

if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию =127

// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; //работает!!
DDRB = 0b00111110; //работает!!
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
// wdt_enable (WDTO_2S); // Запуск таймера watchdog: Для тестов не рекомендуется устанавливать значение менее 8 сек. Таймер будет считать ровно столько, сколько указано в константе. По истечении этого времени произойдет перезагрузка. /* Возможные значения для константы WDTO_15MS WDTO_30MS WDTO_60MS WDTO_120MS WDTO_250MS WDTO_500MS WDTO_1S WDTO_2S WDTO_4S WDTO_8S 2 s (WDTO_2S ATMega 8, 168, 328, 1280, 2560) ( wdt_enable (WDTO_8S);) https://geektimes.ru/post/255800/ https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer
//UPRAVLENIE_PINAMI(); //сделать пллавный пуск - определить нужное состояние пинов без их предварительного дергания --- настроили логику и отдали её в функцию UPRAVLENIE_PINAMI.
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки

display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (5000+timeAfterACC)) && (flagACC==0) ) // после 5 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}


void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// для newE и для 0x27
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилок включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилок включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл -выкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока
// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';//
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharIII(kalibrovkaNOW, &strokaI[7]); // вывод РЕЖИМА калибровки

sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 111 0.000| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 1110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}


}//void analogReadU

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
PORTBregistr = 0; // выключили всё
PORTDregistr = 0; // выключили всё
UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию
delay (600); // для зарядки кондёров после снятия нагрузки
analogReadU (10); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП A0 и А1, потом их усреднили(10)раз
kalibrovkaACC = 1200000/Uacc-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
kalibrovkaAKB = 1200000/Uakb-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
{kalibrovkaNOW ++;}
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW == 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 254 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.write(0,kalibrovkaACC);
EEPROM.write(1,kalibrovkaAKB);

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //
delay (10000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();

}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{

if (millis() - pauseTimeACC >= I_dva_C_szina_ON_time ) /* пауза XXX=I_dva_C_szina_ON_timec после появления напряжения на ACC и потом делать следующ(пока включено ACC):*/
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
//lcd.clear(); //очистка дисплея не нужна со строковым выводом
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
sprintf(strokaI," INIT OK ") ;
lcd.setCursor(0, 0);
lcd.print(strokaI);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! !
}
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C

}


} // конец как только включили зажигание ( при любом напряжении батареи)
//} не нужна скобка


if (flagACC ==1 )
{// если flagACC == 1
//проверить
if (((millis() - pauseTimeACC) >= (20)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
//проверить
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение перифирии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+500) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------



if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+500) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}
if ((razreszenie_raboty_I_dva_C_sziny == 0) || (flagHALL ==1)) //Не даём заснуть первые 15с
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------


if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
//Serial.print ("razreszenie_raboty_I_dva_C_sziny = " ); Serial.println (razreszenie_raboty_I_dva_C_sziny);
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{ REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop

analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0){if ( (millis() < 60000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();} } // после 60с или если стоит ЗАПРЕТ(255), калибровку НЕ ДЕЛАЕМ



// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)

// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ





/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/

ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}




/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[1];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


//Serial.print ("HUB = " ); Serial.println (HUB);
if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

UPRAVLENIE_PINAMI();




}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

oleg707
15.05.2018, 22:45
поскольку пользователей блока стало много, и некоторым нужно ну СОВСЕМ разное поведение, и они вынуждены каждое обновление прошивки прописывать свои настройки ( напряжения, режмы работы и т.п. ), я добавил возможность сохранять персональные настройки в энергонезависимую память процессора (EEPROM). ( пока некоторые).

Для тех, кто не изучал скетч, и НЕ понимает, для чего это нужно, обновление ничего не меняет, он "прозрачное".
То есть если вы один раз настраивали блок питания "под себя" и сохранили это в память блока, то последующие обновления прошивки будут пытаться сначала считать эти настройки, а если их нет, то берутся значения "по умолчанию".

49707

oleg707
22.05.2018, 23:58
тестовая версия.
m32 - Реализована возможность ВСЕ настройки пользователя (в том числе и тайминги) писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.

const byte brac_nastrojki_iz_EEPROM = 0;
// если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1,
0 - берём значения из скетча, игнорируя память ( кроме калибровки),
2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)

byte ver = 32;// БЕТА( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini //выбор типа блока питания.
// дата правки 22.05.18.2223

// для 5mini, 5mini2,1 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
byte reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.

unsigned long rezerv2 =0;
unsigned long rezerv3 =0;
unsigned long rezerv4 =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov { // Создаем пользовательскую структуру
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long rezerv2 ;
unsigned long rezerv3 ;
unsigned long rezerv4 ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library //для сна
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024

//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

int PINrawACC = A0; // замер для 5й версии
int PINrawAKB = A1; // замер для 5й версии
int PINkalibrovki = A2; // замер для 5й версии

//int PINrawACC = A7; // замер для 7й версии
//int PINrawAKB = A8; // замер для 7й версии
//int PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







int vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================




void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзюком сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзюком питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; /* 16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки
{



RABOTA_z_EEPROM(); //

Serial.begin(115200);

if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию =127

// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; //работает!!
DDRB = 0b00111110; //работает!!
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
// wdt_enable (WDTO_2S); // Запуск таймера watchdog: Для тестов не рекомендуется устанавливать значение менее 8 сек. Таймер будет считать ровно столько, сколько указано в константе. По истечении этого времени произойдет перезагрузка. /* Возможные значения для константы WDTO_15MS WDTO_30MS WDTO_60MS WDTO_120MS WDTO_250MS WDTO_500MS WDTO_1S WDTO_2S WDTO_4S WDTO_8S 2 s (WDTO_2S ATMega 8, 168, 328, 1280, 2560) ( wdt_enable (WDTO_8S);) https://geektimes.ru/post/255800/ https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer
//UPRAVLENIE_PINAMI(); //сделать пллавный пуск - определить нужное состояние пинов без их предварительного дергания --- настроили логику и отдали её в функцию UPRAVLENIE_PINAMI.
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки

display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (5000+timeAfterACC)) && (flagACC==0) ) // после 5 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()





if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
rezerv2,
rezerv3,
rezerv4,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
rezerv2 = znachenija_polzovatelia.rezerv2;
rezerv3 = znachenija_polzovatelia.rezerv3;
rezerv4 = znachenija_polzovatelia.rezerv4;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// для newE и для 0x27
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилок включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилок включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл -выкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока
// FloatToCharIIIII (rezerv7, &strokaII[0]);
// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';//
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharIII(kalibrovkaNOW, &strokaI[7]); // вывод РЕЖИМА калибровки

sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 111 0.000| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 1110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}


}//void analogReadU

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
PORTBregistr = 0; // выключили всё
PORTDregistr = 0; // выключили всё
UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию
delay (600); // для зарядки кондёров после снятия нагрузки
analogReadU (10); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП A0 и А1, потом их усреднили(10)раз
kalibrovkaACC = 1200000/Uacc-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
kalibrovkaAKB = 1200000/Uakb-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
{kalibrovkaNOW ++;}
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW == 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 254 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.write(0,kalibrovkaACC);
EEPROM.write(1,kalibrovkaAKB);

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //
delay (10000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();

}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{

if (millis() - pauseTimeACC >= I_dva_C_szina_ON_time ) /* пауза XXX=I_dva_C_szina_ON_timec после появления напряжения на ACC и потом делать следующ(пока включено ACC):*/
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
//lcd.clear(); //очистка дисплея не нужна со строковым выводом
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
sprintf(strokaI," INIT OK ") ;
lcd.setCursor(0, 0);
lcd.print(strokaI);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! !
}
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C

}


} // конец как только включили зажигание ( при любом напряжении батареи)
//} не нужна скобка


if (flagACC ==1 )
{// если flagACC == 1
//проверить
if (((millis() - pauseTimeACC) >= (20)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
//проверить
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение перифирии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------



if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}
if ((razreszenie_raboty_I_dva_C_sziny == 0) || (flagHALL ==1)) //Не даём заснуть первые 15с
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------


if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
//Serial.print ("razreszenie_raboty_I_dva_C_sziny = " ); Serial.println (razreszenie_raboty_I_dva_C_sziny);
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{ REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop

analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0){if ( (millis() < 60000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();} } // после 60с или если стоит ЗАПРЕТ(255), калибровку НЕ ДЕЛАЕМ



// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)

// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ





/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/

ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}




/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[1];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


//Serial.print ("HUB = " ); Serial.println (HUB);
if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

UPRAVLENIE_PINAMI();
//Sleepy::loseSomeTime(20);// sleep for XXX seconds



}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _
хотелки


______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 5 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволило выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилок)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания - 318 строка
t08- ничего
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить. Отдельной переменной не создавал, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

oleg707
27.05.2018, 22:20
возникла необходимость контролировать значения, которые прописаны в памяти процессора.
По этому поводу накатал программку, которая читает данные из памяти, декодирует и кидает в ком порт.
Порядок такой:
1 - залили скетч в блок питания ( или в голую ардуину, для теста)
2 - открыли ком порт, выставили скорость 115200
3 - читаем.
Если хотим изменить значения или полностью стереть память - меняем в начале циферку соответственно описанию.
4 - заливаем прошивку для блока питания, например m32.

Если что непонятно - спрашивайте. Есть желание записать видео, но пока нет времени.
49785
const byte rejim_raboty_control_lub_zapis = 0; // определяем, что мы хотим делать этим скетчем.
// 0 - только читаем.
// 1 - пишем значения в еепром процессора.
// 2 - обнуляем память процессора ( как если бы поставили новую ардуину)

//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

//const byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
byte reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.

unsigned long rezerv2 =0;
unsigned long rezerv3 =0;
unsigned long rezerv4 =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =01.01;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
#include <EEPROM.h> // Импортируем библиотеку
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ


const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov { // Создаем пользовательскую структуру
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long rezerv2 ;
unsigned long rezerv3 ;
unsigned long rezerv4 ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

int RAW_address_eeprom = 0; // Переменная для хранения адреса для вывода сырых значений еепром
byte RAW_value_eeprom; // Переменная для хранения значения для вывода сырых значений еепром


void setup() {
Serial.begin(115200);
// Serial.flush();
while (Serial.available())
Serial.read();
delay(50);

myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
rezerv2,
rezerv3,
rezerv4,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia

if (rejim_raboty_control_lub_zapis == 2)// 2 - обнуляем память процессора ( как если бы поставили новую ардуину)
{// 2 - обнуляем память процессора
RAW_address_eeprom =0;
while (RAW_address_eeprom < EEPROM.length()) { // Перебираем адреса, до тех пор, пока не перебирем все
EEPROM.update(RAW_address_eeprom, 255); //
//Serial.println("RAW_address_eeprom: "+String(RAW_address_eeprom)+", RAW_value_eeprom: "+String(RAW_value_eeprom)); // Выводим полученное значение в монитор
RAW_address_eeprom++; // Наращиваем адрес
}
delay(50);
Serial.println (" ");
Serial.println (" rejim_raboty_control_lub_zapis == 2");
Serial.println (" oczistili EEPROM processora");
Serial.println (" teperb proczitaem czto zapisano v pamiaci");
Serial.println (" ");
delay(50);
}// 2 - обнуляем память процессора


// Записываем все данные в EEPROM.
if (rejim_raboty_control_lub_zapis == 1)// 1 - пишем значения в еепром процессора.
{// 1 - пишем значения в еепром процессора.
EEPROM.update(0,kalibrovkaACC);
EEPROM.update(1,kalibrovkaAKB);
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia[0]); // ПИШЕМ данные в EEPROM из созданной переменной

delay(50);
Serial.println (" ");
Serial.println (" rejim_raboty_control_lub_zapis == 1");
Serial.println (" propisali znaczenia iz sketcha v EEPROM processora");
Serial.println (" teperb proczitaem czto zapisano v pamiaci");
Serial.println (" ");
delay(50);
}// 1 - пишем значения в еепром процессора.




// Теперь данные можно считать
myStruct_Znachenija_peremennyh_i_timingov Schitano; // В переменную Schitano будем считывать данные из EEPROM
// for (int i = 0; i < 1; i++) {
delay(50);
EEPROM.get(nachalnyj_address_dannyh_polzovatelja_v _eeprom, Schitano); // Считываем данные из EEPROM в созданную переменную
delay(50);
// выводим в ком порт значения калибровокделителей асс и акб
Serial.flush();
while (Serial.available())
Serial.read();
Serial.println (" ");
Serial.println (" "); Serial.println (" "); Serial.println (" ");
Serial.print (" kalibrovkaACC = ");
Serial.println (kalibrovkaACC);
Serial.print (" kalibrovkaAKB = ");
Serial.println (kalibrovkaAKB);
// выводим в ком порт значения пользователя, которые прописаны в еепром
Serial.print (" reset_HUB_on_power_on = ");
Serial.println (Schitano.reset_HUB_on_power_on);
Serial.print (" power_off_HUB_on_starting = ");
Serial.println (Schitano.power_off_HUB_on_starting);
Serial.print (" power_off_OTG_on_starting = ");
Serial.println (Schitano.power_off_OTG_on_starting);
Serial.print (" HALL_as_power_Switch = ");
Serial.println (Schitano.HALL_as_power_Switch);
Serial.print ("Uperezariadki = ");
Serial.println (Schitano.Uperezariadki);
Serial.print ("UrabotyREM = ");
Serial.println (Schitano.UrabotyREM);
Serial.print ("UnevykluczeniaREM = ");
Serial.println (Schitano.UnevykluczeniaREM);
Serial.print ("Uakb_Kogda_ACC_vYkluczeno = ");
Serial.println (Schitano.Uakb_Kogda_ACC_vYkluczeno);
Serial.print ("Uakb_Kogda_ACC_vkluczeno = ");
Serial.println (Schitano.Uakb_Kogda_ACC_vkluczeno);
Serial.print ("UaccONorOFF = ");
Serial.println (Schitano.UaccONorOFF);
Serial.print ("timeUntilBATOff = ");
Serial.println (Schitano.timeUntilBATOff);
Serial.print ("timeUntilALLOff = ");
Serial.println (Schitano.timeUntilALLOff);
Serial.print ("timeBeforeRemOff = ");
Serial.println (Schitano.timeBeforeRemOff);
Serial.print ("timeAfterACC_starting = ");
Serial.println (Schitano.timeAfterACC_starting);
Serial.print ("timeAfterACC_accOFF = ");
Serial.println (Schitano.timeAfterACC_accOFF);
Serial.print ("timeWhileAkbLow = ");
Serial.println (Schitano.timeWhileAkbLow);
Serial.print ("pauseTimeHALL = ");
Serial.println (Schitano.pauseTimeHALL);
Serial.print ("vremia_obnovlenia_displeya = ");
Serial.println (Schitano.vremia_obnovlenia_displeya);
Serial.print ("PlanshBAT_timer_pri_vkl_ACC = ");
Serial.println (Schitano.PlanshBAT_timer_pri_vkl_ACC);
Serial.print ("FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = ");
Serial.println (Schitano.FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_v kl_ACC);
Serial.print ("OTG_timer_pri_vkl_ACC = ");
Serial.println (Schitano.OTG_timer_pri_vkl_ACC);
Serial.print ("HUB_timer_pri_vkl_ACC = ");
Serial.println (Schitano.HUB_timer_pri_vkl_ACC);
Serial.print ("REGISTRATOR_timer_pri_vkl_ACC = ");
Serial.println (Schitano.REGISTRATOR_timer_pri_vkl_ACC);
Serial.print ("REM_timer_pri_vkl_ACC = ");
Serial.println (Schitano.REM_timer_pri_vkl_ACC);
Serial.print ("SLEEP_timer_pri_vkl_ACC = ");
Serial.println (Schitano.SLEEP_timer_pri_vkl_ACC);
Serial.print ("I_dva_C_szina_ON_time = ");
Serial.println (Schitano.I_dva_C_szina_ON_time);
Serial.print ("OTG_timer_pri_vykl_ACC = ");
Serial.println (Schitano.OTG_timer_pri_vykl_ACC);
Serial.print ("FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = ");
Serial.println (Schitano.FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_v ykl_ACC);
Serial.print ("HUB_timer_pri_vykl_ACC = ");
Serial.println (Schitano.HUB_timer_pri_vykl_ACC);
Serial.print ("SLEEP_timer_pri_vykl_ACC = ");
Serial.println (Schitano.SLEEP_timer_pri_vykl_ACC);
Serial.print ("REM_timer_pri_vykl_ACC = ");
Serial.println (Schitano.REM_timer_pri_vykl_ACC);
Serial.print ("lcd_noBacklight_timer_pri_vykl_ACC = ");
Serial.println (Schitano.lcd_noBacklight_timer_pri_vykl_ACC);
Serial.print ("I_dva_C_szina_OFF_time = ");
Serial.println (Schitano.I_dva_C_szina_OFF_time);
Serial.print ("vremia_uderjanija_najatoj_knopki_POWER = ");
Serial.println (Schitano.vremia_uderjanija_najatoj_knopki_POWER);
Serial.print ("rezerv2 = ");
Serial.println (Schitano.rezerv2);
Serial.print ("rezerv3 = ");
Serial.println (Schitano.rezerv3);
Serial.print ("rezerv4 = ");
Serial.println (Schitano.rezerv4);
Serial.print ("rezerv5 = ");
Serial.println (Schitano.rezerv5);
Serial.print ("rezerv6 = ");
Serial.println (Schitano.rezerv6);
Serial.print ("rezerv7 = ");
Serial.println (Schitano.rezerv7);

delay (3000); // задержка
// теперь выводим сырые данные еепром
Serial.println (" ");
Serial.println (" ");
Serial.println ("teper' wywodim syryje dannyje eeprom");
Serial.println (" ");
RAW_address_eeprom = 0;
while (RAW_address_eeprom < EEPROM.length()) { // Перебираем адреса, до тех пор, пока не перебирем все
RAW_value_eeprom = EEPROM.read(RAW_address_eeprom); // Считываем значение байта
Serial.println("RAW_address_eeprom: "+String(RAW_address_eeprom)+", RAW_value_eeprom: "+String(RAW_value_eeprom)); // Выводим полученное значение в монитор
RAW_address_eeprom++; // Наращиваем адрес
}
Serial.println (" ");
Serial.println (" ");
Serial.println (" ");
while (Serial.available())
Serial.read();

}


void loop() {}
//vers 1.0 270518_2009

oleg707
13.06.2018, 00:56
Есть тема.
В планшете используют по 2 проводника от контроллера батареи до материнской платы, пара на плюс, и пара на минус.
Этим решается несколько проблем:
Общее сопротивление ( и соответственно падение напряжения) меньше.
Ток разделяется на 2.
Нагрев провода меньше

Может и в планшет от блока питания тоже заводить питание парными проводами?

holopovvv
13.06.2018, 17:29
Смотря каким сечением подводить, можно одним но потолще, или двумя но по тоньше). Блок питания получил сегодня, осталось найти время подключить!

oleg707
13.06.2018, 21:24
У меня одним тонким (1 мм) подключено, сантиметров 60, и работает норм. Но производитель для чего то так делает. Правда я добавлял конденсаторов на материнскую плату, как раз для компенсации коротких пиковых бросков тока.

skanch
13.06.2018, 22:17
...Но производитель для чего то так делает.
Делается в первую очередь для увеличения общего сечения каждой силовой линии питания при сохранении плоскости монтажа. На Nexus 9 аккумулятор 6700 мА*ч и на разъем идет по четыре проводника на каждой линии питания.

4989649897

oleg707
13.06.2018, 22:47
Делается в первую очередь для увеличения общего сечения каждой силовой линии питания при сохранении плоскости монтажа. На Nexus 9 аккумулятор 6700 мА*ч и на разъем идет по четыре проводника на каждой линии питания.


Не, 4 это уже перебор :be:
Тут 2 лениво ставить :big:

oleg707
17.06.2018, 11:59
m34 - добавлен режим ОТЛАДКИ.
Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, и прочее непонятное поведение, то для проверки функций включаем OTLADKA = 1;
В этом режиме напряжения аккумулятора и ACC принимаются за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
Естественно, если вы не подадите качественного питания на BP5mini, то дс-дс преобразователи не смогут работать.
При этом, например, на выходе питания хаба получится не +5,0В а ЛЮБОЕ другое напряжение :wacko2:
Для штатной, нормальной работы блока питания ставим OTLADKA = 0;

Этот режим, в основном, предназначен для отлавливания некорректной работы при неправильных подключениях ( случаи НЕ единичные:secret:)


byte ver = 34;// БЕТА( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini //выбор типа блока питания.
// дата правки 17.06.18.0941

// для 5mini, 5mini2,1 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора и ACC принимаются за 14,50(В). для штатной, нормальной работы блока питания ставим OTLADKA = 0;
const byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
byte reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = timeUntilALLOff; // пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long rezerv3 =0;
unsigned long rezerv4 =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov { // Создаем пользовательскую структуру
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long rezerv3 ;
unsigned long rezerv4 ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024

//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

int PINrawACC = A0; // замер для 5й версии
int PINrawAKB = A1; // замер для 5й версии
int PINkalibrovki = A2; // замер для 5й версии

//int PINrawACC = A7; // замер для 7й версии
//int PINrawAKB = A8; // замер для 7й версии
//int PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







int vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================




void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзюком сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзюком питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; /* 16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки
{



RABOTA_z_EEPROM(); //

Serial.begin(115200);

if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию =127

// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; //работает!!
DDRB = 0b00111110; //работает!!
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
// wdt_enable (WDTO_2S); // Запуск таймера watchdog: Для тестов не рекомендуется устанавливать значение менее 8 сек. Таймер будет считать ровно столько, сколько указано в константе. По истечении этого времени произойдет перезагрузка. /* Возможные значения для константы WDTO_15MS WDTO_30MS WDTO_60MS WDTO_120MS WDTO_250MS WDTO_500MS WDTO_1S WDTO_2S WDTO_4S WDTO_8S 2 s (WDTO_2S ATMega 8, 168, 328, 1280, 2560) ( wdt_enable (WDTO_8S);) https://geektimes.ru/post/255800/ https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer
//UPRAVLENIE_PINAMI(); //сделать пллавный пуск - определить нужное состояние пинов без их предварительного дергания --- настроили логику и отдали её в функцию UPRAVLENIE_PINAMI.
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки

display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (5000+timeAfterACC)) && (flagACC==0) ) // после 5 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()





if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ перифирии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ перифирии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
rezerv3,
rezerv4,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
rezerv3 = znachenija_polzovatelia.rezerv3;
rezerv4 = znachenija_polzovatelia.rezerv4;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// для newE и для 0x27
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилок включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилок включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл -выкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока
// FloatToCharIIIII (rezerv7, &strokaII[0]);
// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';//
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharIII(kalibrovkaNOW, &strokaI[7]); // вывод РЕЖИМА калибровки

sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 111 0.000| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 1110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}


}//void analogReadU

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
PORTBregistr = 0; // выключили всё
PORTDregistr = 0; // выключили всё
UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию
delay (600); // для зарядки кондёров после снятия нагрузки
analogReadU (10); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП A0 и А1, потом их усреднили(10)раз
kalibrovkaACC = 1200000/Uacc-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
kalibrovkaAKB = 1200000/Uakb-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
{kalibrovkaNOW ++;}
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW == 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 254 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.write(0,kalibrovkaACC);
EEPROM.write(1,kalibrovkaAKB);

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //
delay (10000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();

}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{

if (millis() - pauseTimeACC >= I_dva_C_szina_ON_time ) /* пауза XXX=I_dva_C_szina_ON_timec после появления напряжения на ACC и потом делать следующ(пока включено ACC):*/
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
//lcd.clear(); //очистка дисплея не нужна со строковым выводом
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
sprintf(strokaI," INIT OK ") ;
lcd.setCursor(0, 0);
lcd.print(strokaI);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! !
}
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C

}


} // конец как только включили зажигание ( при любом напряжении батареи)
//} не нужна скобка


if (flagACC ==1 )
{// если flagACC == 1
//проверить
if (((millis() - pauseTimeACC) >= (20)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
//проверить
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение перифирии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------



if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if ((razreszenie_raboty_I_dva_C_sziny == 0) || (flagHALL ==1)) //Не даём заснуть первые 15с
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------


if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
//Serial.print ("razreszenie_raboty_I_dva_C_sziny = " ); Serial.println (razreszenie_raboty_I_dva_C_sziny);
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{ //REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop

analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0){if ( (millis() < 60000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();} } // после 60с или если стоит ЗАПРЕТ(255), калибровку НЕ ДЕЛАЕМ



// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

// если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора и принимаем их за 14,50В
if (OTLADKA == 1)
{
U_acc_real = 14.50;
U_akb_real = 14.50;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)

// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ





/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/

ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}




/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[1];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


//Serial.print ("HUB = " ); Serial.println (HUB);
if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

UPRAVLENIE_PINAMI();
//Sleepy::loseSomeTime(20);// sleep for XXX seconds



}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _
хотелки


______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 5 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволило выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилок)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания - 318 строка
t08- ничего
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить. Отдельной переменной не создавал, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на выключение питания на регистратор после выключения зажигания.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора и ACC принимаются за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

oleg707
18.06.2018, 21:51
на habr.com нашел хорошую информацию для новичков и не только по проектированию печатных плат (https://habr.com/post/414141/).
Также ОЧЕНЬ полезные комментарии. Оттуда я вытянул еще более интересную пдф-ку
https://docs.toradex.com/102492-layout-design-guide.pdf
И вот там уже можно поучиться.:yes4:

oleg707
23.06.2018, 14:25
так выглядит индикация на дисплее
для версии скетча m34

49920
================
|000:00 110212.10|
|2616 01110 14.50|
================

1 строка

|000:00 110212.10| вывод минут:секунд - ОБЩЕЕ время работы процессора (полное время работы БП без отключения)
|2616 01110 14.50|

|000:00 110212.10| flagAKB - вывод флага AKB
|2616 01110 14.50|

|000:00 110212.10| flagACC - вывод флага AСС
|2616 01110 14.50|


|000:00 110212.10| REM - вывод rem 1-усилитель звука включен, 0 - выключен
|2616 01110 14.50|

|000:00 110212.10| flagREM - вывод флага!!! rem 1-усилитель звука включен, 0,2 - выключен
|2616 01110 14.50|

|000:00 110212.10| вывод напряжения АСС
|2616 01110 14.50|

2 строка

|000:00 110212.10|
|2616 01110 14.50| вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)

|000:00 110212.10|
|2616 01110 14.50| STARTUEM - Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.

|000:00 110212.10|
|2616 01110 14.50| OTG - вывод флага OTG

|000:00 110212.10|
|2616 01110 14.50| HUB - вывод флага HUB

|000:00 110212.10|
|2616 01110 14.50| вывод флага FIVE_Volt_OUT_na_POGO_or_USB ((ПРИЗНАК ЗАРЯДКИ или зарядка на юсб))

|000:00 110212.10|
|2616 01110 14.50| вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен

|000:00 110212.10|
|2616 01110 14.50| вывод напряжения АКБ

oleg707
08.07.2018, 19:39
краткий принцип работы БП5mini
(+поиск неисправностей)
49959
По многочисленным просьбам сделал упрощенное описание принципов работы аппаратной части БП5mini (только на включение).
Поскольку форум не переваривает картинки большого размера и для возможности дополнения информации залил файл на обменник.

просмотреть можно по этой ссылке (https://drive.google.com/file/d/1OS3jjhJHxZBDXa3zCcBlkk-WPVkZzuv3/view?usp=sharing)

oleg707
14.07.2018, 18:59
49968

добавлены комментарии.
функция obrabotka_AKB поставлена первее obrabotka_ACC_ON.
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания.

oleg707
30.07.2018, 22:52
обновление прошивки БП5 мини.
50057
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()

oleg707
28.08.2018, 09:30
Итак итоги тестирования дс -дс показали, что при прочих равных mp1584 немного лучше. Мне также понравился его ток без нагрузки. Поэтому во всех последних версиях я ставлю теперь mp1584 (1,5A без охлаждения прекрасно держит).

oleg707
22.09.2018, 13:01
Всем привет!
Есть интересное предложение.
Задумал такую акцию помощи :yes2:

Суть в следующем:
Я посылаю человеку детали для сборки по себестоимости ( плата, разъем, its724, высокоточные резисторы, конденсаторы, прошитую ардуино нано по желанию.
В общем могу выслать всё для самостоятельной сборки, кроме дисплея.
Ну и плюс стоимость пересылки, естественно.

Взамен я хочу подробного отчёта о сборке и настройке БП и такого же подробного отчёта о подключении к БП к планшету и инсталляции его в автомобиль.
Про БП - тут, в теме, про остальное - в своих проектах.

Естественно, если нужны консультации - помогу по viber или whatsapp в свое свободное время.

Связь со мной, потому как на форум долго могу не заходить:
Viber, WhatsApp+375_29_3_9_пять_два_7_8_7
Добавляете номер в свою записную книжку телефона, открываете WhatsApp (Viber) и пишете сообщение. Я пишу, когда мне удобно поговорить голосом.
___________________

Посчитал, сколько у меня уходит денег на детали и на пересылку почтой ( для БП5mini+ v2.2.)
Учитывая покупку многих запчастей десятками-сотнями штук, выходит 17.3$
Оригинал файла (https://drive.google.com/open?id=1FkkCns1nXA2SOD58cGrqzxvxKKNDLz_F) расчетов с ссылками на запчасти.
50212
___________________
Плюсы вам: очевидны. Имеете нормальный интеллектуальный источник питания с широкими возможностями персональной подстройки в случае необходимости.
Плюсы форуму: больше подробной информации. Больше посещаемость, больше общения.
Плюсы мне: Вы сделаете за меня описание сборки и описание подключения планшета, причем вариаций может быть много.
В остальном с моей стороны это благотворительность для рукастых и головастых парней, и своеобразная благодарность тем взрослым дядькам, которые поддерживали увлечение малолетнего пацана, давая почти бесплатно резисторы и прочую выпаянную фигню в моем детстве.

artolik
22.09.2018, 15:52
Доброго времени всем. Олег я записываюсь. На условия согласен. Остальное обсудим в вайбере,спасибо.

oleg707
22.09.2018, 16:12
связь со мной, потому как на форум долго могу не заходить:
вайбер, вотсапп +375_29_3_9_пять_два_7_8_7

Добавляете номер в свою записную книжку телефона, открываете WhatsApp (Viber) и пишете сообщение. Я пишу, когда мне удобно поговорить голосом.

iMag
01.10.2018, 00:44
Олег,
Кажется, очень правильный подход! Мне, к примеру, понравилось работать руками самому (хотя и пришлось паять всё с нуля). Но не это важно. Важно то, что это прекрасная идея по поддержке темы на форуме. (Конечно, тема умрёт как и многие другие очень хорошие и интересные, но только умирать будет дольше. )))
ЗЫ. Жаль, но мне придёт блок питания уже в сборе (ведь так?). Тогда я его разберу и запаяю по новой! )))

oleg707
02.10.2018, 13:26
Олег,
Кажется, очень правильный подход! Мне, к примеру, понравилось работать руками самому (хотя и пришлось паять всё с нуля). Но не это важно. Важно то, что это прекрасная идея по поддержке темы на форуме. (Конечно, тема умрёт как и многие другие очень хорошие и интересные, но только умирать будет дольше. )))
ЗЫ. Жаль, но мне придёт блок питания уже в сборе (ведь так?). Тогда я его разберу и запаяю по новой! )))

На такой подход меня натолкнули две вещи.
Во первых, обращения людей из, скажем так, развивающихся регионов. Для которых 20-30 долларов непозволительная сумма на хобби, и они готовы потратить своё время на пайку, настройку, отладку и возможное решение проблем, чтобы было дешевле.
Во вторых, многие люди хотели бы сами собрать и имеют соответствующие навыки и даже оборудование. По отзывам они собирали из готовых комплектов за примерно часа полтора.

В принципе, блок запросто можно спаять обычным маленьким паяльником.
Я же, поскольку имею паяльную станцию, наношу небольшое количество припоя и флюса на плату, потом прохожусь феном, постепенно поднимая температуру со 100 до 350 градусов, для имитации запекания в промышленной печке.
Потом критические элементы дополнительно прохожусь паяльником, контролируя всю плату простейшим микроскопом ( лупа 60х).

Тема ( глобально) не умрёт, потому как я уже много где вижу решения, взятые из моего проекта, так что цель моя в общем то достигнута:secret:
Зы. Твой бп придёт собранный, настроенный, откалиброванный и оттестированный.

oleg707
03.10.2018, 11:46
Дублирую на форуме
Краткий принцип работы БП5mini (https://drive.google.com/file/d/1OS3jjhJHxZBDXa3zCcBlkk-WPVkZzuv3/view?usp=sharing)
(+поиск неисправностей)
50258
5025950260
Базовые понятия:
+BAT - постоянное напряжение аккумулятора (+30 (http://www.vovik8.ru/documents2/))
-BAT - масса (-31 (http://www.vovik8.ru/documents2/))
+АСС - выход из замка зажигания (+15 (http://www.vovik8.ru/documents2/))
* - элементы, помеченные таким знаком НЕ обязательные к установке.

следующая часть (http://pccar.ru/showpost.php?p=405634&postcount=40)

oleg707
03.10.2018, 11:57
Предыдущая часть (http://pccar.ru/showpost.php?p=405633&postcount=39)

Итак, подключили массу -BAT, подали питание на +BAT. Должно быть не менее 12В! ( и не более 15В) (на самом деле можно и меньше 12В, только процессор не включит часть модулей при питании ниже 11,7В, поскольку это задано программой для бережного отношения к аккумулятору)
5026150262

Напряжение пошло через предохранитель на "интеллектуальный ключ" - микросхему ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90)., а также на делитель напряжения R3-R7.
Ничего не должно происходить. Никакой реакции.

Включили "зажигание" - подали +12В на +АСС
ток пошел через диод D5 низкоомный резистор R2 на делитель напряжения R5-R6.
Конденсатор С9 служит для аппаратного подавления дребезга в контактной группе ( при пропадании +АСС напряжение не пропадает сразу).

C делителя напряжения R5-R6 около +6В пошло на IN4 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90).
50263

следующая часть
(http://pccar.ru/showpost.php?p=405651&postcount=41)

oleg707
04.10.2018, 00:55
Предыдущая часть (http://pccar.ru/showpost.php?p=405634&postcount=40)

ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90), если по простому, представляет собой управляемый выключатель на 4 канала, с защитой по превышению тока и температуры.
50269
Подавая на канал IN1-IN4 слаботочное напряжение ( в нашем случае >= +5В), этим включаем "силовое" выходное напряжение (+12) на соответствующих каналах OUT1-OUT4.

следующая часть
(http://pccar.ru/showpost.php?p=405661&postcount=42)

oleg707
04.10.2018, 13:37
Предыдущая часть (http://pccar.ru/showpost.php?p=405651&postcount=41)
C делителя R5-R6 около +6В пошло на IN4 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90). На выходе OUT4 появляется +12В, которое через резистор R1 пошло на контакт Vin ардуино.
50270

следующая часть (http://pccar.ru/showpost.php?p=405831&postcount=54)

oleg707
05.10.2018, 12:53
const byte ver = 36;// БЕТА( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini,5mini2.1 //выбор типа блока питания.
// дата правки 29.07.18.1118

// для 5mini, 5mini2,1 5mini2,2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 2 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

const byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
byte reset_HUB_on_power_on = 1; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.5; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.7; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 40000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = timeUntilALLOff; // пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long rezerv3 =0;
unsigned long rezerv4 =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov { // Создаем пользовательскую структуру
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long rezerv3 ;
unsigned long rezerv4 ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024

//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

int PINrawACC = A0; // замер для 5й версии
int PINrawAKB = A1; // замер для 5й версии
int PINkalibrovki = A2; // замер для 5й версии

//int PINrawACC = A7; // замер для 7й версии
//int PINrawAKB = A8; // замер для 7й версии
//int PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







int vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================


void vykluchic_vse()
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
LED = 0; // Светодиод 1 = светит; 0 = не светит
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}

void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{

// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; /* 16pin = PB4 = pin D12 MISO управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
// if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
//if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
// if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.

}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки
{



RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM

Serial.begin(115200);

if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию =127

// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; // настройки порта D
DDRB = 0b00111110; // настройки порта B
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//vykluchic_vse();
/* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
*/
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки

display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (5000+timeAfterACC)) && (flagACC==0) ) // после 5 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()





if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
rezerv3,
rezerv4,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
rezerv3 = znachenija_polzovatelia.rezerv3;
rezerv4 = znachenija_polzovatelia.rezerv4;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// для newE и для 0x27
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл -выкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока
// FloatToCharIIIII (rezerv7, &strokaII[0]);
// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharIII(kalibrovkaNOW, &strokaI[7]); // вывод РЕЖИМА калибровки

sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}


}//void analogReadU

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)

vykluchic_vse();
/*
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
LED = 0; // Светодиод 1 = светит; 0 = не светит
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию
*/
delay (300); // для зарядки кондёров после снятия нагрузки
//analogReadU (5); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП A0 и А1, потом их усреднили(10)раз
kalibrovkaACC = 1200000/Uacc-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
kalibrovkaAKB = 1200000/Uakb-1410; // вычисляем значение калибровки, подав 12В на вход делителя U ( просто подключив питание к блоку питания)
{kalibrovkaNOW ++;}
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW == 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,kalibrovkaACC);
EEPROM.update(1,kalibrovkaAKB);

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII,"c ") ;
IntToCharIII(kalibrovkaACC, &strokaII[1]); // вывод значения калибровки АСС
IntToCharIII(kalibrovkaAKB, &strokaII[5]); // вывод значения калибровки АСС

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //
delay (10000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();

}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
} // конец как только включили зажигание ( при любом напряжении батареи)



if (flagACC ==1 )
{// если flagACC == 1
//проверить
if (((millis() - pauseTimeACC) >= (20)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
//проверить
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------



if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if ((razreszenie_raboty_I_dva_C_sziny == 0) || (flagHALL ==1)) //Не даём заснуть первые 15с
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------


if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
//Serial.print ("razreszenie_raboty_I_dva_C_sziny = " ); Serial.println (razreszenie_raboty_I_dva_C_sziny);
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop

analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0){if ( (millis() < 60000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();} } // после 60с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ



// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

// если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора
if (OTLADKA >= 1)
{
U_akb_real = 14.50; // принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (OTLADKA == 2 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 2 )
}//конец режима отладки.

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ

// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)






/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/

ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}




/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[1];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


//Serial.print ("HUB = " ); Serial.println (HUB);
if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

if (kalibrovkaNOW < 6) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами.
{
UPRAVLENIE_PINAMI();
}
//Sleepy::loseSomeTime(20);// sleep for XXX seconds



}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _
хотелки


______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 5 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания - 318 строка
t08- ничего
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

iMag
06.10.2018, 18:24
Итак, Олег!
Начинаем работу по подключению BP5mini к Нехусу 2012. Случай, когда батарея остаётся в планшете, доступа к ней и к датчику Холла извне нет.
- Вывод "Батарея планшета" подаётся на +5V microUSB.
- +5V POGO никуда не подключается.
- HUB +5V подаётся на хаб.
- -SLEEP (HALL) не подключается.
- -Y-OTG подключается к 4-му контакту microUSB.
- GND PLANS подключается к выводу - microUSB (пятый контакт) И!!! к минусу питания хаба.
- ЦЗ-IN никуда не подключается.
- REM out (+12V) никуда не подключается.
- registrator+30 никуда не подключается.
- ACC подключается к контакту зажигания KEY ON.
- +30 подключается к постоянному +12V машины.
- GND IN подключается к минусу машины.

Итого, я подключаю всего 7 контактов разъёма: 3 - входные, 4 - выходные. Остальные не подключаю за неимением необходимости.

Олег, я правильно всё себе растолковал?
ЗЫ. По мне, было бы удобно использовать нумерацию ног разъёма, но так как они не обозначены, не стал вносить ещё большее непонимание для других читателей.

oleg707
06.10.2018, 20:39
Итак, Олег!
Начинаем работу по подключению BP5mini к Нехусу 2012. Случай, когда батарея остаётся в планшете, доступа к ней и к датчику Холла извне нет.
- Вывод "Батарея планшета" подаётся на +5V microUSB.
- +5V POGO никуда не подключается.
- HUB +5V подаётся на хаб.
- -SLEEP (HALL) не подключается.
- -Y-OTG подключается к 4-му контакту microUSB.
- GND PLANS подключается к выводу - microUSB (пятый контакт) И!!! к минусу питания хаба.
- ЦЗ-IN никуда не подключается.
- REM out (+12V) никуда не подключается.
- registrator+30 никуда не подключается.
- ACC подключается к контакту зажигания KEY ON.
- +30 подключается к постоянному +12V машины.
- GND IN подключается к минусу машины.

Итого, я подключаю всего 7 контактов разъёма: 3 - входные, 4 - выходные. Остальные не подключаю за неимением необходимости.

Олег, я правильно всё себе растолковал?
ЗЫ. По мне, было бы удобно использовать нумерацию ног разъёма, но так как они не обозначены, не стал вносить ещё большее непонимание для других читателей.
Неправильно :no2:
Для подключения только по ЮСБ ( если не хочется потрошить планшет) можно подключать так:

Вывод "Батарея планшета" никуда не подключаем. Там постоянно есть 4,2. На батерее реального планшета напряжение не пропадает, а только гуляет 3,8-4,2
Вывод "+5V POGO" (на самом деле он подписан как "+5V_USB_(POGO)" ) подключаем на +5V microUSB.
У себя (http://pccar.ru/showpost.php?p=355473&postcount=7)в стационарной установке 7-2012 я подключал +5V_USB_(POGO) как раз на контакт POGO. (http://pccar.ru/attachment.php?attachmentid=43263&d=1459368854)
Вывод "HUB +5V" подаётся на хаб. В хабе отрезаем +5В, идущее к планшету ( отпаиваем провод).
Вывод "-Y-OTG" подключается к 4-му контакту microUSB. Делается это для корректной переинициализации юсб устройств при выключении зажигания. В общем случае нужно сделать кабель, типа такого (http://pccar.ru/showthread.php?t=27457).
Вывод "- GND PLANS" подключается к выводу - microUSB (пятый контакт) И!!! к минусу питания хаба.
5027450275
Вывод "- REM out" (+12V) подключается на управление выхода REM внешнего усилителя звука (http://pccar.ru/attachment.php?attachmentid=47876&d=1501665777), если он есть.
Вывод "+ACC" подключается к контакту зажигания KEY ON. ( или к АСС. или к +15. В общем к напряжению, которое появляется после включения замка зажигания в первую позицию либо при вставлении ключа в замок зажигания).
Вывод "+30" подключается к постоянному +12V машины. Желательно через предохранитель 5-7,5А. На плате блока питания есть физический предохранитель, но внешний по правилам должен тоже быть. ( Поскольку я подключался к фишке штатной магнитолы, то предохранитель у меня стоит по заводу в блоке предохранителей).
Вывод "-GND IN" подключается к минусу машины, желательно в ту же точку, что и магнитола, для избежания возможных помех по звуку (земляная петля (https://www.google.pl/search?q=%D0%B7%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D0%B 0%D1%8F+%D0%BF%D0%B5%D1%82%D0%BB%D1%8F&oq=%D0%B7%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D0%B0%D1%8 F+%D0%BF%D0%B5%D1%82%D0%BB%D1%8F&aqs=chrome..69i57j0l5.1455j0j7&sourceid=chrome&ie=UTF-8))
Итого, я подключаю всего 7 контактов разъёма: 3 - входные, 4 - выходные. Остальные не подключаю за неимением необходимости.
Да, верно.
Прелесть блока в возможности подключать его почти как угодно.
ЗЫ. По мне, было бы удобно использовать нумерацию ног разъёма, но так как они не обозначены, не стал вносить ещё большее непонимание для других читателей.
На самом деле нумерация ног есть, в программе DipTrace при открытии проекта печатной платы. Но как раз это вносит большую запутанность, поэтому так проще и нагляднее.

Ps
Забыл сказать, что в планшет при таком подключении нужно будет прошить ядро, поддерживающее одновременно режим OTG и зарядку, например ядро elemental.

iMag
06.10.2018, 20:58
Спасибо огромное за столь развёпнутый ответ!
По подключениям вовсе нет вопросов, всё исчерпано.
По нумерации тоже нет, всё равно уже разжёвано по максимуму. )
Разве что в самом мануале (который прилагается в блоку и который прикреплён к одному из постов текущей темы) зелёный цвет не совсем уместен, так как на бумажном варианте он получается размытым. Это проблеммно для тех, у кого зрение подсажено, но ещё не носит очки (вроде меня). То же относится и к серому цвету текста таблицы )

oleg707
06.10.2018, 21:23
Спасибо огромное за столь развёпнутый ответ!
По подключениям вовсе нет вопросов, всё исчерпано.
По нумерации тоже нет, всё равно уже разжёвано по максимуму. )
Разве что в самом мануале (который прилагается в блоку и который прикреплён к одному из постов текущей темы) зелёный цвет не совсем уместен, так как на бумажном варианте он получается размытым. Это проблеммно для тех, у кого зрение подсажено, но ещё не носит очки (вроде меня). То же относится и к серому цвету текста таблицы )

Эта мини инструкция по подключению по факту тянется еще с 3 версии БП. Подумаю над цветами.
Забыл сказать, что в планшет при таком подключении нужно будет прошить ядро, поддерживающее одновременно режим OTG и зарядку, например ядро elemental.

Немного не в тему, но натолкнулся на классное описание простым языком про то, что такое диод. (http://easyelectronics.ru/diod-chast-1.html#more-1493)

Диод, часть 2 (http://easyelectronics.ru/diod-chast-2-nemnogo-o-konstrukcii-i-principax.html#more-1506)

skanch
09.10.2018, 08:42
Диод, часть 2 (http://easyelectronics.ru/diod-chast-2-nemnogo-o-konstrukcii-i-principax.html#more-1506)
А в твоём проекте, по какой схеме организована защита на стабилитронах (http://pccar.ru/showpost.php?p=405650&postcount=750)? И почему по два в параллель?

oleg707
09.10.2018, 13:06
А в твоём проекте, по какой схеме организована защита на стабилитронах (http://pccar.ru/showpost.php?p=405650&postcount=750)? И почему по два в параллель?

У меня стабилитрон ставится, как последнее звено защиты.
Смысл в том, что если дс-дс сошел с ума (или пользователь решит поднять немного, на пару-тройку тройку вольт:big: напряжение, и оно превысит 5,6В), то тут стоИт выбор: либо сохраняем планшет живым, либо пропускаем на выход, скажем, 7 вольт.
Для меня выбор очевиден.
Стабилитроны ставятся в параллель для увеличения надёжности.По 2 штуки на дс-дс преобразователь.
Принцип такой: при увеличении напряжения выше 5,6В начинается его стабилилизация, с большим выделением тепла. Как правило один из двух стабилитронов ( практические испытания) уходит в короткое замыкание. Дс-дс при этом уходит в защиту по току, и пытается запуститься, но ему не даёт короткое замыкание стабилитрона.

Это решение спасло уже 2 планшета точно от любителей поднять напряжение, но крутящих сразу на четверть оборота.
При понижении напряжения до приемлемого нужно перепаять стабилитроны. Либо их выпаять, что крайне не рекомендуется.

___________

Кстати, может подскажет кто интеллектуальный ключ на 1 канал с напряжением 3-7 вольт? Или транзистор полевой p-канальный в корпусе dpak (TO252) с минимальным сопротивлением.
Ампера на 2-5.
Нужно, чтобы 5.5 вольт коммутировал с минимальным падением напряжения (5.45) на выходе при токе 2А.

skanch
09.10.2018, 18:48
У тебя "голые" стабилитроны стоят на выходе каждого канала. Как вариант для "отладки на столе", пока тестируется и подбирается напряжение может и подходит, но как вариант полноценной защиты уже установленного блока в недра авто - не лучший вариант. Я тоже экспериментирую с различными защитами от перенапряжения и тока, и "голые" стабы тоже тестировал. Конкретно с модулем на MP1584 происходит следующее: пока напряжение на выходе преобразователя не превышает напряжение стабилизации - всё нормально, как только превысило расчётную величину стаб устраивает короткое замыкание на выходе DC-DC преобразователя и при этом сам начинает греться, да так, что плавится припой. Соответственно напряжения на выходе канала питания нет. Но есть одно "но"... Припой плавится, и стаб просто испустив последний дым с площадок отваливается, тем самым "разблокировав" короткое замыкание на модуле DC-DC и "высокое" напряжение устремилось к нагрузке. Если стаб сгорев всё-таки каким-то чудом удержится на плате, то микросхема от перегрева (порог 150С) переходит в защиту-отключается и это лучший вариант (при этом остыв примерно до 120С пытается включаться снова-процесс повторяется). Но в моих экспериментах стаб сваливался с платы раньше, чем отключалась микросхема. Если в линию питания добавить плавкий предохранитель, то при коротком замыкании перегорев он разомкнёт цепь. Тогда менять нужно будет и стаб, и предохранитель. Если в схему добавить тиристор на ток реально превышающий ток, выдаваемый модулем DC-DC, то менять нужно будет только предохранитель. По такому принципу работает схема ниже.

50281
Источник. (http://lib.qrz.ru/book/export/html/9723)
Ставить этот "предохранитель на тиристоре" нужно после DC-DC преобразователя именно на выходе. Плавкий предохранитель FU1 в цепи защиты должен быть рассчитан на максимальный ток нагрузки самого DC-DC преобразователя.

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

P.S. Идеальный вариант защиты - это микросхемы от MAXIM (https://datasheets.maximintegrated.com/en/ds/MAX14571-MAX14573.pdf). Но это уже не бюджетное решение.

oleg707
09.10.2018, 21:24
У тебя "голые" стабилитроны стоят на выходе каждого канала. Как вариант для "отладки на столе", пока тестируется и подбирается напряжение может и подходит, но как вариант полноценной защиты уже установленного блока в недра авто - не лучший вариант. Я тоже экспериментирую с различными защитами от перенапряжения и тока, и "голые" стабы тоже тестировал. Конкретно с модулем на MP1584 происходит следующее: пока напряжение на выходе преобразователя не превышает напряжение стабилизации - всё нормально, как только превысило расчётную величину стаб устраивает короткое замыкание на выходе DC-DC преобразователя и при этом сам начинает греться, да так, что плавится припой. Соответственно напряжения на выходе канала питания нет. Но есть одно "но"... Припой плавится, и стаб просто испустив последний дым с площадок отваливается, тем самым "разблокировав" короткое замыкание на модуле DC-DC и "высокое" напряжение устремилось к нагрузке. Если стаб сгорев всё-таки каким-то чудом удержится на плате, то микросхема от перегрева (порог 150С) переходит в защиту-отключается и это лучший вариант (при этом остыв примерно до 120С пытается включаться снова-процесс повторяется). Но в моих экспериментах стаб сваливался с платы раньше, чем отключалась микросхема. Если в линию питания добавить плавкий предохранитель, то при коротком замыкании перегорев он разомкнёт цепь. Тогда менять нужно будет и стаб, и предохранитель. Если в схему добавить тиристор на ток реально превышающий ток, выдаваемый модулем DC-DC, то менять нужно будет только предохранитель. По такому принципу работает схема ниже.

50281
Источник. (http://lib.qrz.ru/book/export/html/9723)
Параллельное соединение стабилитронов не совсем правильное решение, поскольку вследствие неизбежного разброса в напряжениях пробоя, даже если они из одной партии, будет пробит только один из них, а именно тот, который имеет меньшее значение этого параметра.

P.S. Идеальный вариант защиты - это микросхемы от MAXIM (https://datasheets.maximintegrated.com/en/ds/MAX14571-MAX14573.pdf). Но это уже не бюджетное решение.
Припой хорошо греется, но не плавится, ты забываешь, что у меня в цепи кроме предохранителя ещё и its724g стоит, который ограничивает максимальный ток на пару дс-дс.
Микросхема в дс-дс тоже имеет защиту от короткого замыкания, а не только защиту по превышению температуры. При к.з. должны идти попытки запуска, но не до плавления припоя же. Может у меня масса припоя большая, и защиты отрабатывают раньше - гадать нет смысла.
Про предохранитель зря ты так. Вполне хорошее и бюджетное решение. К.З. так просто не возникает, соответственно если сгорел предохранитель - и так надо разбираться.

Про пару стабилитронов - решение осознанное, потому как если один не сработал или выжегся, не уйдя в короткое замыкание, второй подстрахует. Стоимость копейки.

Ещё раз повторю, что простейшее копеечное решение установки стабилитрона уже спасло 2 планшета от перенапряжения выше 5.6В, что в тех случаях означало бы смерть материнской платы. Да, в тех двух случаях люди сами хотели поднять напряжение на выходе, но, не рассчитав, крутили подстроечный резистор больше, чем надо. В одном случае было 7,7В по выходу, во втором он сразу крутанул обратно, но было поздно.
В любом случае, если напряжение в норме, то стабилитроны не участвуют в работе, а если превышает 5,6В - это уже аварийная ситуация тогда пусть лучше горит стабилитрон, дс-дс, предохранитель, микросхема, да хоть весь блок питания! Главная задача - защитить планшет. Остальное ремонтируется.

skanch
09.10.2018, 22:00
Спорить и что-то доказывать не вижу смысла. Я привёл тебе конкретные результаты тестов одиночных стабов, причём расписал, как работает подобная защита на модуле MP1584 - ты или не вник в суть написанного мною или просто "оно тебе не надо"...
Smart-ключ its724g стоИт у тебя до модулей и коммутирует входное напряжение от АКБ машины - так что к защите от короткого замыкания на выходе DC-DC преобразователей отношения не имееет и в таком виде использования выступает в роли простого коммутатора входного питания. При КЗ на выходе модуля микросхема MP1584 отключает нагрузку, но не блокирует входные цепи. Поэтому и привёл тебе пример с использованием предохранителя в цепи защиты именно выходного напряжения.

oleg707
10.10.2018, 13:54
Спорить и что-то доказывать не вижу смысла. Я привёл тебе конкретные результаты тестов одиночных стабов, причём расписал, как работает подобная защита на модуле MP1584 - ты или не вник в суть написанного мною или просто "оно тебе не надо"...
я ж тебе написал тесты практических результаты завышения напряжения ( либо сам забывал уменьшить перед включением, либо подстроечные поврежденные). Чтобы выпаять закороченные стабилитроны и не пережарить электролит рядом, я иногда включал БП, стабы подогравались и я паяльным феном уже разогретые отпаивал ( так легче и быстрее).
Может у меня масса припоя большая, и защиты отрабатывают раньше - гадать нет смысла.
Как смогу, сделаю еще раз такой тест " в лоб".

"оно тебе не надо"
Ну как сказать, у некоторых ВООБЩЕ никакой защиты по выходу от перенапряжения нету :spiteful:
Причем перенапряжение подразумевает под собой автоматический выход планшета из строя.
Поэтому моя логика такая, что пускай сгорит хоть весь БП - он прекрасно ремонтопригодный, но мы спасаем планшет.
Про its724g, тут да, скорее про защиту от КЗ ДС-ДС модуля.
При КЗ на выходе модуля микросхема MP1584 отключает нагрузку, но не блокирует входные цепи
Ну да.:big: Я вроде и не утверждаю обратного.
Вообще, если посмотреть на компьютер управления двигателем или другие "мозги" автомобилей, то у всех автопроизводителей питания, которые выходят на запитку датчиков именно так себя и ведут. При замыкании - уходят в защиту (при этом пишут ошибку в память и зажигают индикатор ошибки на приборной панели), а при устранении КЗ - продолжают спокойно выдавать напряжение. Только там внутри стоят нормальные микросхемы, но стоимость нового блока обычно 500-1000 евро. Немножко разные весовые категории, поэтому приходится иногда идти на компромиссы :rolleyes2:

В остальном я с тобой согласен :beer:

oleg707
11.10.2018, 13:10
Предыдущая часть (http://pccar.ru/showpost.php?p=405661&postcount=42)

На плате ардуино установлен регулятор напряжения AMS1117 (http://www.advanced-*******hic.com/pdf/ds1117.pdf), который при появлении +12В начинает выдавать +5В для запитки процессора и платы ардуино. Также эти +5В появляются на выходе ардуино "+5V", откуда идут через R9, R10 на подтяжку для I2C шины (подключение дисплея) и конденсатор С12 ( нужен для длительного поддержания питания процессора при низком напряжении аккумулятора, например при старте автомобиля. Также +5В идут для запитки дополнительного I2C дисплея.
5029150292
При появлении питания на ардуино начинает светиться светодиод питания.

следующая часть (http://pccar.ru/showpost.php?p=405908&postcount=58)

tima10
11.10.2018, 23:00
Уважаемые skanch, oleg707,
подскажите пжл, в авто есть ММС, а также установлен планшет Nexus 7 2012 WiFi,
решил немного привести в порядок проводку подключения планшета, так вот что я
хочу уточнить у Вас, я хочу подключить БП планшета к косичке ММС,где все есть: +12 В, земля, АСС. вопрос в том: можно ли осуществить такую схему подключения БП планшета и хватит ли теперь им обоим напряжения и тока при одновременном запуске при заводке автомобиля?
спасибо.:blush:

oleg707
11.10.2018, 23:31
Уважаемые skanch, oleg707,
подскажите пжл, в авто есть ММС, а также установлен планшет Nexus 7 2012 WiFi,
решил немного привести в порядок проводку подключения планшета, так вот что я
хочу уточнить у Вас, я хочу подключить БП планшета к косичке ММС,где все есть: +12 В, земля, АСС. вопрос в том: можно ли осуществить такую схему подключения БП планшета и хватит ли теперь им обоим напряжения и тока при одновременном запуске при заводке автомобиля?
спасибо.:blush:

Хватит. По асс блок ничего не берет, по + 30 ( постоянный плюс) максимум Ампера 4
В крайнем случае на линии постоянного плюса (+30) ммс поставить предохранитель на 5 ампер больший, чем должен стоять по заводу.
Подключение на столе ещё древней 4 версии
https://m.youtube.com/watch?v=ZXcNYxcIh9U&t=2s

ZXcNYxcIh9U&t=2s

tima10
12.10.2018, 21:46
Хватит. По асс блок ничего не берет, по + 30 ( постоянный плюс) максимум Ампера 4
В крайнем случае на линии постоянного плюса (+30) ммс поставить предохранитель на 5 ампер больший, чем должен стоять по заводу.
Подключение на столе ещё древней 4 версии
https://m.youtube.com/watch?v=ZXcNYxcIh9U&t=2s

ZXcNYxcIh9U&t=2s

спасибо, значит будем делать.:drinks_cheers:

oleg707
13.10.2018, 16:22
Предыдущая часть (http://pccar.ru/showpost.php?p=405831&postcount=54)

При появлении питания на ардуино (https://duino.ru/arduino-nano) начинает светиться светодиод питания.
Примерно через секунду ( ожидание загрузчика) начинает выполняться программа, зашитая в процессор ( наш скетч (http://pccar.ru/showpost.php?p=405682&postcount=43)).
По выполнению некоторых операций ( всё описать не буду, это будет повторением скетча (http://pccar.ru/showpost.php?p=405682&postcount=43)) процессор считывает значения напряжений АКБ ( аккумулятора).
Для этого с делителя напряжения R3-R7 уменьшенное напряжение идёт на порт А1 ардуино.
Также процессор считывает значения напряжений АСС ( напряжение после замка зажигания).
Для этого с делителя напряжения R4-R8 уменьшенное напряжение идёт на порт А0 ардуино.

При входном напряжении питания 12В на АСС и АКБ на портах А0 и А1 должно быть 3,85В.
При входном напряжении питания 14,5В на АСС и АКБ на портах А0 и А1 должно быть 4,60В.

Если при входе 12В на портах А0 и А1 сильно заниженные напряжения (например 0,7В, 0,2В), возможно неисправны конденсаторы С7, С8. Также стоит проверить резисторы делителей напряжения R3, R7, R4, R8.
5030350304

Следующая часть (http://pccar.ru/showpost.php?p=406062&postcount=80)

artolik
15.10.2018, 20:51
Доброго времени всем,пришел сегодня мне кит набор блока питания.

Опыт пайки у меня не большой,а smd компонентов в таком количестве тем более. Взял флюс,припой (толстоватый для smd),заточил на наждаке паяльник на 40 Ватт и приступил к пайке. Начинал с самых мелких компонентов,потом на увеличение. Первая для меня трудность- это маркировка резисторов,на плате они указаны трехзначными,а используются четырехзначные высокоточные,Олег молодец,всегда онлайн и готов подсказать,но я ему об этом написал,когда уже сам разобрался. Если у вас нет опыта пайки,трясутся руки,лучше заказывайте готовый блок. Компоненты очень мелкие,запаса нет и если у вас что нибудь отскочит,то найти деталь будет практически не возможно. Я постелил белый лист бумаги,детали брал и укладывал маленьким пинцетом,потом прижимал деталь зубочисткой и паял.

Без лупы,даже если вы с открытого прицела белке в глаз попадаете,паять я думаю не получится. Процесс весьма увлекательный и фото я делал не постоянно,но они у меня еще есть,но кончился лимит на форуме. Сейчас буду искать фото хостинг.

https://c.radikal.ru/c09/1810/95/6cc31d519255.jpg (https://radikal.ru)

В процессе сборки у меня возникали некоторые вопросы и я их задавал Олегу в вайбер,ответы приходили быстро,спасибо Олег.

https://b.radikal.ru/b05/1810/ed/dc9df4bc90ef.jpg (https://radikal.ru)

https://c.radikal.ru/c02/1810/e5/e5a6ce010c88.jpg (https://radikal.ru)

https://b.radikal.ru/b20/1810/79/6de582cb282f.jpg (https://radikal.ru)

https://b.radikal.ru/b07/1810/41/2fbfd925368e.jpg (https://radikal.ru)

https://b.radikal.ru/b19/1810/c3/433ad66f91c4.jpg (https://radikal.ru)

https://a.radikal.ru/a43/1810/ae/943c23a60ad7.jpg (https://radikal.ru)

https://d.radikal.ru/d26/1810/98/c6f3d70dc296.jpg (https://radikal.ru)

https://d.radikal.ru/d19/1810/08/2faede3592f6.jpg (https://radikal.ru)

https://d.radikal.ru/d15/1810/33/244a324dcbde.jpg (https://radikal.ru)

https://b.radikal.ru/b33/1810/b5/fcef47a8c59b.jpg (https://radikal.ru)

https://c.radikal.ru/c29/1810/bd/baa087ac99fb.jpg (https://radikal.ru)

artolik
15.10.2018, 23:34
Думал у меня будет затык с прошивкой нано,у меня нет мини usb кабеля,но Олег успокоил,прошивка залита. Так что в ближайшее время найду разъем atx и приступлю к калибровке,теперь правда не знаю нужны ли фото,или только текстом все описывать. Конечно лучше взять готовый,настроенный блок питания у автора,но лично мне гораздо интересней собирать самому.

artolik
16.10.2018, 14:37
Сегодня нашел ATX разъем и попробовал включить блок питания,все запустилось,напряжение на батарею нужно немного понизить,думаю до 4,2 вольта. Осталось еще подключить экран и откалибровать блок. Ну и погонять под нагрузкой.

https://b.radikal.ru/b07/1810/37/11118c18072c.jpg (https://radikal.ru)

https://d.radikal.ru/d12/1810/a8/83c8d7660f11.jpg (https://radikal.ru)

artolik
16.10.2018, 14:58
Олег хочу задать вопрос здесь,может кому еще будет интересно,я буду для нагрузки использовать нихромовую проволоку,на какой ток ее лучше настроить и когда подавать нагрузку,сразу или после старта блока питания?

oleg707
16.10.2018, 19:09
Олег хочу задать вопрос здесь,может кому еще будет интересно,я буду для нагрузки использовать нихромовую проволоку,на какой ток ее лучше настроить и когда подавать нагрузку,сразу или после старта блока питания?

1.5-2 ампера на каждый дсдс. нагрузку подавать можно сразу, можно потом. Я и так и так тестирую.
например нa канал батареи я подключаю резистор 2 Ом, ток на 4.1В получается около 2х ампер.
на канал +5 (зарядки) 3 ома 1.5 А

artolik
17.10.2018, 15:55
https://b.radikal.ru/b23/1810/82/0911a1fd2024.jpg (https://radikal.ru)

https://c.radikal.ru/c23/1810/0e/f10796d08a2b.jpg (https://radikal.ru)

Хотел подстроить напряжение на dc dc,который на батарею планшета,дрогнула рука и получил дым со стабилитронов,пришлось выпаивать,сгорел только один. Настройка в этих пределах очень чувствительная,одно не удачное движение и конец стабилитронам,паять обычным паяльником,там не очень удобно,а фена у меня нет. Считаю использование переменных резисторов в авто не очень удачной идеей,тем более когда сдвиг резистора на доли мм,может привести к таким последствиям.

В итоге,после выпайки стабилитронов я настроил dc dc на 4,1 вольт и впаял стабилитроны на место,один который выжил,второй Олег случайно или нарочно положил мне в комплект. Я совсем не гуру в электронике,но думаю в идеале нужно на dc dc вместо переменника ставить нормальный резистор,ну или хотя бы шунтировать переменник для более плавной регулировки в пределах 4-5 вольт. В принципе мне осталось намотать нагрузочные резисторы и погонять блок под нагрузкой и я думаю на этом,по блоку питания будет все. Постараюсь в ближайшее время это сделать. А еще вспомнил,вчера потратил немного времени на перестановку проводов в разъеме ATX,а то по умолчанию там было не совсем логично,в одной косе из трех проводов они все были разного цвета,теперь все красиво.

oleg707
17.10.2018, 16:31
один который выжил,второй Олег случайно или нарочно положил мне в комплект
случайности неслучайны ;)
в идеале нужно на dc dc вместо переменника ставить нормальный резистор
согласен, но на практике одному надо 4.0, другому 5.0В. смд с дсдс выпаять не каждый сможет.
А кто может - запросто выпаяет подстроечный резистор и запаяет туда постоянный 0805 или 0603:derisive:

skanch
17.10.2018, 16:53
Нужно проявлять заботу о "развивающихся регионах" и заранее впаивать многооборотные потенциометры ))).

5033150332

artolik
17.10.2018, 17:28
Ну вот собрал такой колхоз. Нихром поленился к чему нибудь прикрутить,просто повесил все это в воздухе и погонял минут 20. Пирометра у меня нет,но на ощупь dc dc едва теплые,стабилитроны выжили,хотя боялся за б.у. из сгоревшей пары.Напряжения настроил 5,1 вольт на хаб и 4,1 на батарею.

https://b.radikal.ru/b17/1810/a6/61fa68140329.jpg (https://radikal.ru)

Олег я так понимаю 0805 и 0603 это для 4,1 и 5,1 вольт? А какой для какого? Мне наверно нужно как то расковырять подстроечник и выпаять частями,у меня же обычный старый паяльник. Хочу поставить постоянные и забыть. Подскажите еще к каким пятакам паять? Там же их будет три,спасибо. Ошибок мне допускать нельзя,стабилитронов больше в запасе нет.

Многооборотные конечно улучшат ситуацию,но добавят высоты,да и постоянный конечно наверно надежней.

Забыл написать,нагрузка у меня была подключена перед включением блока питания,при этом он стартовал стабильно.

skanch
17.10.2018, 19:29
Многооборотные конечно улучшат ситуацию,но добавят высоты,да и постоянный конечно наверно надежней.
Хм...И сильно высоко получается? Прямо выше электролитов?
Олег я так понимаю 0805 и 0603 это для 4,1 и 5,1 вольт? А какой для какого? Мне наверно нужно как то расковырять подстроечник и выпаять частями,у меня же обычный старый паяльник. Хочу поставить постоянные и забыть. Подскажите еще к каким пятакам паять? Там же их будет три,спасибо. Ошибок мне допускать нельзя,стабилитронов больше в запасе нет.
Я понимаю вашу эйфорию по поводу самостоятельной сборки конструктора, но на форуме достаточно информации по этим модулям (http://pccar.ru/showthread.php?p=397466#post397466)- нужно только поискать...

Ну вот собрал такой колхоз. Нихром поленился к чему нибудь прикрутить,просто повесил все это в воздухе и погонял минут 20. Пирометра у меня нет,но на ощупь dc dc едва теплые,стабилитроны выжили,хотя боялся за б.у. из сгоревшей пары.Напряжения настроил 5,1 вольт на хаб и 4,1 на батарею.
Это тесты модуля (http://pccar.ru/showpost.php?p=392191&postcount=16) под нагрузкой. Если "чуть тёплые" (40-45С) - значит ток нагрузки не превышает 600-800 мА.

mazay66
17.10.2018, 20:24
Хм...И сильно высоко получается? Прямо выше электролитов?
Какое практическая польза от них? Всегда считал, что запаять постоянный резистор нужного номинала намного надежнее и правильнее. Нечего там крутить и регулировать. Настроить с одного преобразователя 4,2-4,4В, а с другого 5,1-5,3В и забыть.

skanch
17.10.2018, 20:42
Какое практическая польза от них? Всегда считал, что запаять постоянный резистор нужного номинала намного надежнее и правильнее. Нечего там крутить и регулировать. Настроить с одного преобразователя 4,2-4,4В, а с другого 5,1-5,3В и забыть.
На данном блоке питания - никакой пользы!

artolik
17.10.2018, 20:58
Спасибо за ссылочку по dc dc,для меня она очень полезная. Извините,что сам не смог найти,я думаю форум для того и существует,чтобы участники помогали друг другу.

Еще вопросик,если использовать стандартные резисторы,то можно добится напряжений 5,66. 5,35. 4,5. 3,7 вольт. Исходя из этого я думаю настроить 4,5 вольт на батарею и 5,35 на хаб. Но не поплохеет ли стабилитронам от 5,35 вольт?

skanch
17.10.2018, 21:50
Спасибо за ссылочку по dc dc,для меня она очень полезная. Извините,что сам не смог найти,я думаю форум для того и существует,чтобы участники помогали друг другу.

Еще вопросик,если использовать стандартные резисторы,то можно добится напряжений 5,66. 5,35. 4,5. 3,7 вольт. Исходя из этого я думаю настроить 4,5 вольт на батарею и 5,35 на хаб. Но не поплохеет ли стабилитронам от 5,35 вольт?
Не плодите отдельных постов - старайтесь писать компактно.
По последнему вопросу: чтобы получить точное напряжение на выходе нужно запастись прецизионными резисторами с разными номиналами и методом подбора получить нужное напряжение (для питания HUB-а от 44К до 47К, для питания планшета от 37К до 39К). Или подстроечником выставить нужное напряжение и аккуратно выпаяв его, померить на нём сопротивление (должно быть в рамках указанных выше значений).
P.S. Как правило купить прецизионные резисторы нужного типоразмера и нужного номинала не всегда есть возможность. В этом случае прецизионный многооборотный подстроечник нужного размера может пригодиться...
PS.PS.И если впаиваете постоянные сопротивления, то стабилитроны тем более не нужны.

artolik
17.10.2018, 23:52
Еще раз спасибо.

oleg707
18.10.2018, 00:33
PS.PS.И если впаиваете постоянные сопротивления, то стабилитроны тем более не нужны.
Так они и не мешают :) я бы не выпаивал просто из за лени:)
Олег я так понимаю 0805 и 0603 это для 4,1 и 5,1 вольт? А какой для какого? Мне наверно нужно как то расковырять подстроечник и выпаять частями,у меня же обычный старый паяльник. Хочу поставить постоянные и забыть. Подскажите еще к каким пятакам паять? Там же их будет три,спасибо. Ошибок мне допускать нельзя,стабилитронов больше в запасе нет.
Улыбнуло )))
0805 и 0603 это типоразмеры смд резисторов (http://www.symmetron.ru/suppliers/resistors1/chip_res.shtml)
Пятаки 2 штуки соединены параллельно. Я на подстроечнике уже очень долго, больше года точно катаюсь, никаких проблем. И это при незакрепленном блоке в бардачке. Можешь для успокоения каплю лака капнуть после настройки напряжений.

По поводу постоянных резисторов (https://duino.ru/nabor-rezistorov) - можно посчитать необходимый номинал, в той же программе разработчика mps, но я не помню номинал другого резистора ( считаем то делитель), запаянного на дс-дс. Посмотреть и посчитать сейчас немного затруднительно, т.к. дс-дс на работе, а до домашнего компа добираюсь пару раз в неделю. В основном все с планшета или на работе с ноутбука, а там русских клавиш нету ((.Но если сильно надо, то можно будет глянуть и рассчитать.

.Или подстроечником выставить нужное напряжение и аккуратно выпаяв его, померить на нём сопротивление (должно быть в рамках указанных выше значений).
Аккуратно подстроечник можно только сдуть феном, ну или инфракрасной паялкой, но у меня не всегда получалось точно - точно измерить, то ли пинцетом задевал, то ли деформация от температуры, хз.
А вторая задача найти такой же ! резистор из стандартного модельного ряда, да ещё желательно высокоточный. Да ещё и у себя в наличии )))

. Нихром поленился к чему нибудь прикрутить,просто повесил все это в воздухе и погонял минут 20. Пирометра у меня нет,но на ощупь dc dc едва теплые,стабилитроны выжили,хотя боялся за б.у. из сгоревшей пары.Напряжения настроил 5,1 вольт на хаб и 4,1 на батарею.
Ток надо измерить кроме напряжения. У меня нагрузочные резисторы горяченные, дотронуться нельзя, и дс-дс горячие, дотронуться можно, но на мгновение. Резисторы раньше были на 10 ватт, керамические, аж потрескались, пришлось взять другие, на 100 Вт, с металлическими ребрами охлаждения. Охлаждение я временно не ставил, поэтому новые греются примерно как старые :rofl:
Ps
Во понаписали!

artolik
18.10.2018, 02:40
Нихром я конечно руками не трогал и так на расстоянии чувствовал жар,спираль висела в воздухе,но до красна не нагревалась,возможно я уж слишком завысил сопротивление и по этому не прогрел dc dc до шестидесяти градусов. Но в любом случае я думаю с ними все нормально. С типоразмерами резисторов я лоханулся (стыдно) ,но хоть вас повеселил. Высокоточных в smd я врядли найду. Видимо оставлю все как есть,капну на них лака для ногтей. Жаль конечно,с обычным (высокоточным) я думаю было бы гораздо гораздей.

oleg707
18.10.2018, 09:14
Жаль конечно,с обычным (высокоточным) я думаю было бы гораздо гораздей.

На самом деле никакой разницы на практике не ощущается:secret:
Что в сравнении с 1% резистором, запаянным вместо подстроечник, что в сравнении с 5%.

artolik
19.10.2018, 13:05
Настроил на батарею 4,17 и на хаб 5,1 вольт.

https://b.radikal.ru/b31/1810/bf/fe1eb0393f71.jpg (https://radikal.ru)

creativ92
20.10.2018, 18:56
Имитация штатной работы датчика холла по совету oleg707

нужно выпаять датчик холла (на примере nexus 7 2013)
http://d.radikal.ru/d10/1810/be/2b5039010921.jpg

запаять резистор 100кОм
http://a.radikal.ru/a07/1810/b1/6e087e56693d.jpg

на провод (красный на фото) будет подаваться масса с умного БП, планшет будет засыпать

oleg707
20.10.2018, 20:43
Имитация штатной работы датчика холла по совету oleg707

нужно выпаять датчик холла (на примере nexus 7 2013)]

запаять резистор 100кОм

на провод (красный на фото) будет подаваться масса с умного БП, планшет будет засыпать

Уже прямо сейчас можно на сигнальный провод через 100 ом ( для перестраховки) можно подать массу и проверить работоспособность. Но я думаю, что это уже проделано .

oleg707
21.10.2018, 15:47
Предыдущая часть (http://pccar.ru/showpost.php?p=405908&postcount=58)

Когда процессор посчитал, что напряжений достаточно и зажигание включено, то начинается включение следующего:

включаем самозапитку ардуино (https://duino.ru/arduino-nano), и, соответственно, процессора
Для этого включаем логическую единицу (+5В) на D9 ардуины. Напряжение идет через диод D6 на управляющую ногу IN4 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90). Теперь при выключении ACC можно поддерживать питание блока. Что при этом происходит, рассмотрено чуть выше.
50333

Далее включаем вывод информации на дисплеи I2C.
Поддерживаются дисплеи:
i2c 1602 (https://duino.ru/lcd-1602-arduino)50334 и SSD1306 (https://duino.ru/OLED-displei-0-96---128h64--belyi.html)50335

Так (http://pccar.ru/showpost.php?p=403557&postcount=29)выглядит индикация на дисплее
для версии скетча m34
5033750338
================
|000:00 110212.10|
|2616 01110 14.50|
================

1 строка

|000:00 110212.10| вывод часов:минут: - ОБЩЕЕ время работы процессора (полное время работы БП без отключения)
|2616 01110 14.50|

|000:00 110212.10| flagAKB - вывод флага AKB
|2616 01110 14.50|

|000:00 110212.10| flagACC - вывод флага AСС
|2616 01110 14.50|

|000:00 110212.10| REM - вывод rem 1-усилитель звука включен, 0 - выключен
|2616 01110 14.50|

|000:00 110212.10| flagREM - вывод флага!!! rem 1-усилитель звука включен, 0,2 - выключен
|2616 01110 14.50|

|000:00 110212.10| вывод напряжения АСС
|2616 01110 14.50|

2 строка

|000:00 110212.10|
|2616 01110 14.50| вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)

|000:00 110212.10|
|2616 01110 14.50| STARTUEM - Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.

|000:00 110212.10|
|2616 01110 14.50| OTG - вывод флага OTG

|000:00 110212.10|
|2616 01110 14.50| HUB - вывод флага HUB

|000:00 110212.10|
|2616 01110 14.50| вывод флага FIVE_Volt_OUT_na_POGO_or_USB ((ПРИЗНАК ЗАРЯДКИ или зарядка на юсб))

|000:00 110212.10|
|2616 01110 14.50| вывод флага flagHALL 1-экран включен, 0 - выключен

|000:00 110212.10|
|2616 01110 14.50| вывод напряжения АКБ


Cледующая часть (http://pccar.ru/showpost.php?p=406319&postcount=108)

Alekssandr
24.10.2018, 22:08
Ваше устройство хорошее! Но вы пугаете своих потенциальных клиентов его функционалом! Сделайте проще!!!

oleg707
25.10.2018, 14:07
Ваше устройство хорошее! Но вы пугаете своих потенциальных клиентов его функционалом! Сделайте проще!!!
так весь функционал никто не заставляет использовать:big:
Можно вообще только батарею или только датчик холла подключать.
Плюс есть инструкция по подключению, если что непонятно или какие вопросы ( даже не по блоку), всегда отвечаю в вайбере или вотсаппе.

PS
Устройство с более простым функционалом как то посадило мне аккумулятор (http://pccar.ru/showthread.php?p=348953#post348953).

mazay66
25.10.2018, 19:38
Устройство с более простым функционалом как то посадило мне аккумулятор (http://pccar.ru/showthread.php?p=348953#post348953).
Более простое - не значит "дубовое". Объективности ради: Между двумя крайностями ещё есть "золотая середина". В данном случае она выглядит в виде использования потенциала, заложенного в Mp1584 - Enable Control. Использование данной функции позволит исключить ситуацию с просадкой АКБ.

skanch
25.10.2018, 19:54
... В данном случае она выглядит в виде использования потенциала, заложенного в Mp1584 - Enable Control. Использование данной функции позволит исключить ситуацию с просадкой АКБ.
Через резистивный делитель с подбором на выключение при 11.5В? Если это имеешь в виду, то как быть с выключением при кручении стартером, когда напряжение на АКБ падает до 7В ?

oleg707
25.10.2018, 22:14
Через резистивный делитель с подбором на выключение при 11.5В? Если это имеешь в виду, то как быть с выключением при кручении стартером, когда напряжение на АКБ падает до 7В ?

Конденсатор.
У меня в БП3 похоже было. Один из таймингов на выключение задавался конденсатором после делителя напряжения.
НО как только хочешь подправить этот тайминг, то надо выпаивать конденсатор и выпаивать другой.
Поэтому сейчас у меня меняется почти все программно при желании или необходимости.

oleg707
25.10.2018, 22:20
Хм, я ж уже писал...
Нужно обрабатывать одновременно разные ситуации, например:
Включили зажигание, напряжение просело до некритического уровня. Выключили зажигание и сел АКБ.
Слушаем музыку при включенном зажигании, и усилитель звука даёт сильную просадки при басе ( сабвуфер), причем напряжение, просев, сразу восстанавливается.
На усилитель нужна своя логика отключения и контроля батареи.
Нужно, чтобы усилитель звука выключался после 40 минут работы при несеашем аккумуляторе и не выключался при заведённом авто.
Некоторые пользователи хотят СВОИ значения напряжений и СВОИ тайминги.
Плюс не забывайте, что аккумулятор это химический источник тока, если его что просадило, то при снятии нагрузки напряжение растет.
Это небольшая часть функционала блока, который лично мне необходим.

Не, ребята, я без процессора этот функционал не реализую НИКАК.

skanch
25.10.2018, 22:33
Конденсатор.
Конденсатор в линии "EN" MP1584 ?

oleg707
25.10.2018, 22:48
Конденсатор в линии "EN" MP1584 ?

А почему бы и нет? Хотя я с аппаратными решениями как то наигрался уже.

skanch
25.10.2018, 23:10
А почему бы и нет? Хотя я с аппаратными решениями как то наигрался уже.
Как-то "криво" это... Если использовать резистивный делитель на напряжение запуска MP1584 выше 11.5В с конденсатором в нижнем плече для "поддержания" просадки во время кручении стартером, то кондёр работать не будет - при пропадании напряжения он моментально разрядится через резистор на "массу". Если ставить ещё и диод в эту цепь, то совсем "масло-масляное"... Хотя, как вариант для "безпроцессорного" управления может и сгодится...

oleg707
26.10.2018, 15:52
Как-то "криво" это... Если использовать резистивный делитель на напряжение запуска MP1584 выше 11.5В с конденсатором в нижнем плече для "поддержания" просадки во время кручении стартером, то кондёр работать не будет - при пропадании напряжения он моментально разрядится через резистор на "массу". Если ставить ещё и диод в эту цепь, то совсем "масло-масляное"... Хотя, как вариант для "безпроцессорного" управления может и сгодится...

Вот вот. Мне сейчас намного проще сложную логику реализовать на процессоре, чем ставить кучу " лишних" деталей.
Другой вопрос написать программу управления на этот процессор, сначала было тяжело, а теперь я смотрю на ранние версии и удивляюсь, как такой ужас можно было писать :big:

mazay66
26.10.2018, 19:22
Через резистивный делитель с подбором на выключение при 11.5В? Если это имеешь в виду, то как быть с выключением при кручении стартером, когда напряжение на АКБ падает до 7В ?
Как-то "криво" это... Если использовать резистивный делитель на напряжение запуска MP1584 выше 11.5В с конденсатором в нижнем плече для "поддержания" просадки во время кручении стартером, то кондёр работать не будет - при пропадании напряжения он моментально разрядится через резистор на "массу". Если ставить ещё и диод в эту цепь, то совсем "масло-масляное"... Хотя, как вариант для "безпроцессорного" управления может и сгодится...

Не буду спорить. Вот с такими параметрами, подобранными опытным путем, отключение происходит при 11-11,2В, включение при напряжении выше 12В. При кручении стартером ничего не выключается. Кондер без проблем справляется.

skanch
26.10.2018, 20:48
При всём уважении - схема не работает должным образом. Скорее всего в микросхеме MP1584 вход "EN" не предусматривает подключение внешнего конденсатора. При ёмкости в 47 мкФ увеличивается время включения после обесточивания до 3-4 секунд. При нагрузке в 600 мА не хватает времени для "кручения стартером"- почти сразу выключается (отключение происходит при 11.0В - это при резисторе "нижнего плеча" в 100К).

mazay66
26.10.2018, 22:22
При встрече, с удовольствием продемонстрирую, работоспособность данного узла на моем БП, установленном в служебном Ларгусе

skanch
26.10.2018, 23:14
При встрече, с удовольствием продемонстрирую, работоспособность данного узла на моем БП, установленном в служебном Ларгусе
Саша, не вижу смысла спорить на эту тему. Если работает и всё устраивает-замечательно. Твоя схема собранная у меня на столе ведёт себя не так, как ты описываешь. Хотя все номиналы и схема подключения повторены точно...

oleg707
27.10.2018, 01:17
Не буду спорить. Вот с такими параметрами, подобранными опытным путем, отключение происходит при 11-11,2В, включение при напряжении выше 12В. При кручении стартером ничего не выключается. Кондер без проблем справляется.

При всем уважении ;)
При напряжении ниже 11,4В начинается сульфатация пластин аккумулятора. Часто необратимая, если упустить и пластины посыпались. И вообще не факту, что тока хватит для заводки при таком разряде.

В любом свинцовом аккумуляторе, оставленном в разряженном состоянии начинается сульфатация. Она может быть более или менее интенсивной, в зависимости от нескольких факторов. Сульфатации способствуют:

повышенная температура;
длительное хранение в разряженном состоянии;
большие разрядные токи;
пониженное разрядное напряжение;

Я понимаю, что авто служебное, но аккумулятор все равно жалко:big:

mazay66
27.10.2018, 11:50
Саша, не вижу смысла спорить на эту тему. Если работает и всё устраивает-замечательно. Твоя схема собранная у меня на столе ведёт себя не так, как ты описываешь. Хотя все номиналы и схема подключения повторены точно... Так я и не спорю на эту тему. Я прочитал даташит на данный преобразователь и подобрал параметры необходимые для работы с моим планшетом. Номиналы резисторов делителя подбирал , что бы при 11в питания, на EN было 1,2В. Сделал один раз, пол года назад, «и забыл». Установил в Ларгус с планшетом. При ежедневном использовании по рабочим дням, все ОК. Никаких отключений планшета, при кручении стартером нет. Откуда им взяться, если ток разряда конденсатора, через многокилоомные резисторы делителя (и входа EN), мизерный. Ниже выдержка из описания микросхемы, подтверждающая возможность использования данной функции в МР1584:
"The MP1584 has a dedicated enable control pin (EN). With high enough input voltage, the chip can be enabled and disabled by EN which has positive logic. Its falling threshold is a precision 1.2V, and its rising threshold is 1.5V (300mV higher). When floating, EN is pulled up to about 3.0V by an internal 1μA current source so it is enabled. To pull it down, 1μA current capability is needed. When EN is pulled down below 1.2V, the chip is put into the lowest shutdown current mode. When EN is higher than zero but lower than its rising threshold, the chip is still in shutdown mode but the shutdown current increases slightly."
При напряжении ниже 11,4В начинается сульфатация пластин аккумулятора. Часто необратимая, если упустить и пластины посыпались. И вообще не факту, что тока хватит для заводки при таком разряде.
Я понимаю, что авто служебное, но аккумулятор все равно жалко:big: Олег, ну какая необратимая сульфатация пластин при 11В на батарее??? Сам то веришь в то, что если произойдет аварийная ситуация, и батарея разрядится один раз до 11В, то произойдет необратимая сульфатация? Да и кто мешает тебе подобрать делитель на другой порог отключения? Я для себя выбрал эти значения резисторов, потому что они у меня были, и потому что не вижу никакого криминала при аварийном отключении питания планшета на 11В.

Саша, Олег, я считаю, что ваши БП для планшетов достигли если не совершенства, то очень высокого уровня. Даже не собираюсь сравнивать их с другими, упрощенными вариантами. Но я не понимаю отрицания других вариантов. Не понимаю, когда вопрос ставят именно так: или мой блок питания или останешься с разряженным АКБ в авто. А именно так и выглядела ситуация, после которой я вступил в переписку:
Ваше устройство хорошее! Но вы пугаете своих потенциальных клиентов его функционалом! Сделайте проще!!!
так весь функционал никто не заставляет использовать:big:Устройство с более простым функционалом как то посадило мне аккумулятор (http://pccar.ru/showthread.php?p=348953#post348953).

skanch
27.10.2018, 12:43
... Но я не понимаю отрицания других вариантов. Не понимаю, когда вопрос ставят именно так: или мой блок питания или останешься с разряженным АКБ в авто. А именно так и выглядела ситуация, после которой я вступил в переписку:
Каждый решает только сам, какой вариант ему использовать! И чем будет больше вариантов у читателей этого форума для анализа и последующего выбора-только лучше. Ты же не делишься своими наработками в этой области... Что касается конкретно по отключению по "разряженному АКБ", то твой вариант для меня не приемлем, поскольку считаю, что при аварийной ситуации (а севший АКБ именно такая ситуация) вся система должна обесточиваться полностью (нагрузка полностью отключается и потребление равно "0"). В твоём варианте отключается только сама микросхема (пусть и с мизерным потреблением в этом состоянии), а напряжение на входе модуля "висит". Ведь мы не можем предположить с полной уверенностью, что посадит АКБ - планшет или короткое замыкание на входе модуля... Конденсатор в линии "EN" также не лучший вариант для меня - время включения модуля увеличивается и иногда это не допустимо.... Да и "велосипед изобретать" уже тоже не хочу - зачем, когда у производителя MAXIM или у того же Microchip есть специальные для этих целей микросхемы - супервизоры...
И прошу не расценивать мои слова, как навязывание исключительно моего варианта решения той или иной задачи - повторю: каждый только сам решает, что ему нужно и несёт персональную ответственность за свой выбор и свои действия.

oleg707
27.10.2018, 15:04
Олег, ну какая необратимая сульфатация пластин при 11В на батарее??? Сам то веришь в то, что если произойдет аварийная ситуация, и батарея разрядится один раз до 11В, то произойдет необратимая сульфатация?

Очень хорошая информация про аккумуляторы (https://electrotransport.ru/ussr/index.php?topic=2103.0) читать вдумчиво, 2 раза.
Правда там 10.8В говорится.
У меня аккумулятор AGM, ему уже года 3, и спецприбор его определяет живым на 65-70% ( значит пора менять формально). Да и завести хочется машину каждый раз.
Если напряжение меньше 11.8 АКБ считается разряженным, и 12.6 -заряженным.

И ещё, я не против твоей точки зрения, и в БП довольно много аппаратных конструкторских решений.
Вижу это так, что моя позиция более широкая. Иначе мои требования к надёжности, безопасности и комфорту использования неосуществимы.

Что касается конкретно по отключению по "разряженному АКБ", то твой вариант для меня не приемлем, поскольку считаю, что при аварийной ситуации (а севший АКБ именно такая ситуация) вся система должна обесточиваться полностью (нагрузка полностью отключается и потребление равно "0").
Полностью согласен, у меня ровно та же логика.



И ещё, люди, мы забываем, что аккумулятор химический источник тока. При разряде под нагрузкой и при отключении этой самой нагрузки напряжение через некоторое время поднимается. Поэтому в своих проектах обязательно учитываем это и делаем гистерезис! ( Не знаю, делает кто либо это кроме меня :blush:).
Пришло ко мне это просто- слушал музыку и в момент басов ( усилитель звука у меня мощный) была сильная просадка напряжения, усилитель выключался блоком, напряжение АКБ восстанавливалось и блок снова включал усилитель.
Пришлось немного времени потратить на начальную коррекцию, и много - на практические тесты и окончательную реализацию.
Зато намного спокойнее в лесу музыку слушать:spiteful:

mazay66
27.10.2018, 15:23
Ты же не делишься своими наработками в этой области...
Нечем делится. Нет никаких наработок. Сейчас даже разводки платы в Sprint Layout найти не могу. Видимо не сохранил.


Что касается конкретно по отключению по "разряженному АКБ", то твой вариант для меня не приемлем, поскольку считаю, что при аварийной ситуации (а севший АКБ именно такая ситуация) вся система должна обесточиваться полностью (нагрузка полностью отключается и потребление равно "0"). В твоём варианте отключается только сама микросхема (пусть и с мизерным потреблением в этом состоянии), а напряжение на входе модуля "висит". Ведь мы не можем предположить с полной уверенностью, что посадит АКБ - планшет или короткое замыкание на входе модуля... Теоретически - согласен, практически…, подскажи, пожалуйста, сколько раз у тебя возникало КЗ на входе модулей. Да и предохранитель по питанию, в случае КЗ должен обесточить цепь. Надеюсь, необходимость наличия предохранителя никто оспаривать не будет? Так что тут каждый пусть сам думает, сколько степеней защиты использовать.
Конденсатор в линии "EN" также не лучший вариант для меня - время включения модуля увеличивается и иногда это не допустимо...
Вот этого я не понимаю. Данная задержка должна быть только один раз – при первом подключении БП (или при отключении АКБ). Неужели единожды наблюдаемая задержка в 3 сек, при первом включении планшета, так дискомфортна? Преобразователь должен питать планшет, как в рабочем состоянии, так и в выключенном. В противном случае функциональность планшета резко снижается, ввиду невозможности использования статистических данных от программ. Все данные, при физическом обесточивании планшета, обнуляются.
И прошу не расценивать мои слова, как навязывание исключительно моего варианта решения той или иной задачи - повторю: каждый только сам решает, что ему нужно и несёт персональную ответственность за свой выбор и свои действия. Безусловно. Повторю, твой вариант БП - хорош. Я тестировал его первую версию и могу это подтвердить. Последний вариант БП от Олега построен на тех же преобразователях и так же дополнен контроллером. Думаю, его БП, также дает пользователю хорошие возможности по управлению планшетом и нагрузкой (не имею ввиду сейчас его версии с использованием преобразователя KIW3312).
А дальше, выбор определяется пользователем, исходя из задач, которые необходимо реализовать с помощью данного БП. Категорически не согласен с тем, что если в БП нет контроллера, то этот БП обязательно высадит весь АКБ и его, поэтому, нельзя использовать.
У меня аккумулятор AGM, ему уже года 3, и спецприбор его определяет живым на 65-70% ( значит пора менять формально). Да и завести хочется машину каждый раз.
Если напряжение меньше 11.8 АКБ считается разряженным, и 12.6 -заряженным.
Уже отвечал. Что мешает собрать делитель таким образом, что бы Uen=1.2V при 11,8V?
И ещё, люди, мы забываем, что аккумулятор химический источник тока. При разряде под нагрузкой и при отключении этой самой нагрузки напряжение через некоторое время поднимается. Поэтому в своих проектах обязательно учитываем это и делаем гистерезис! ( Не знаю, делает кто либо это кроме меня :blush:)
Читай внимательнее:
Вот с такими параметрами, подобранными опытным путем, отключение происходит при 11-11,2В, включение при напряжении выше 12В.

P.S. При всём уважении - схема не работает должным образом. Резистор на плате по входу EN на "землю" перекинул?

skanch
27.10.2018, 18:25
...сколько раз у тебя возникало КЗ на входе модулей.
У меня - ни разу! На всех крайних версиях моих блоков есть защита от "переплюсовки" на входе и естественно в рекомендациях по подключению предохранитель указываю, как защиту от КЗ и защиту именно оборудования в авто. Но делаю ведь БП не для себя и поэтому мне нужно максимально гарантированно защищать АКБ владельцев авто в первую очередь от глубокого разряда и поэтому перестраховка "на все случаи жизни" для меня только в "плюс"...
... Данная задержка должна быть только один раз – при первом подключении БП (или при отключении АКБ). Неужели единожды наблюдаемая задержка в 3 сек, при первом включении планшета, так дискомфортна?
Стараюсь делать достаточно универсальные БП и есть случаи, когда в системах не используется "дежурное" питание планшета или системника, или TV-бокса. И питание при включении должно подаваться без задержки всякий раз, но при этом отслеживание напряжения на АКБ должно происходить постоянно (АСС включён, двигатель не заведён, идёт разрядка АКБ). И в этом случае делитель на "EN" не работает.
... Категорически не согласен с тем, что если в БП нет контроллера, то этот БП обязательно высадит весь АКБ и его, поэтому, нельзя использовать.
У меня есть такие БП, где я не использую контроллер для отслеживания напряжения на АКБ и как таймер для отключения системы- без него они прекрасно работают. Поэтому в этой части с тобою полностью согласен.
...Резистор на плате по входу EN на "землю" перекинул?
Да. Подобрал 100К. Отключается при 11.3В. В "спящем" отрабатывает, как надо - выключается чётко примерно через 4 секунды после снижения напряжения до 11.3В, но при "кручении стартером" - ближе ко второй секунде питание пропадает.

oleg707
27.10.2018, 19:11
Уже отвечал. Что мешает собрать делитель таким образом, что бы Uen=1.2V при 11,8V?

Тоже уже отвечал :)

1 - Разным пользователям нужно разные значения.
1.1 - мне тоже хочется иметь возможность изменения напряжения отключения ( срабатывания), и задержки кстати тоже.
2 - Разные значения для включенного и для вЫключенного зажигания.
3- выход управления усилителем звука (REM) управляется отдельной логикой с отключением при более высоком напряжении, чтобы отключить только звук при частичном разряде АКБ. Плюс как ты реализуешь отключение через 40 минут при просто включенном зажигании и неотключение выхода REM при заведённом автомобиле?
4 - если автомобиль стартует( вроде как севшая формально батарея), то экран не тушим, не запускаем процедуру выключения. Если выключили зажигание, то я хочу СРАЗУ увидеть, что экран потух, пошла процедура выключения.
Ждать лишние 10 секунд мне ну очень не хочется.

Опять я упираюсь в свои расширенные запросы, которые решить можно только с процессорным управлением.:smile1::rolleyes2:

Олег, если скажешь, то я "потру" всё лишнее.

Не надо, тут умные люди обсуждают такие ньюансы, о которых рядовой пользователь и не догадывается :big:

Alex15BV
27.10.2018, 19:36
Как сделал у себя:
1. Контроллер при включении проверяет режим программирования (замкнутый джампер)
2. Если да - то дается по 30 секунд на выставление нижнего и верхнего порога напряжения бортсети
3. Новые значения пишутся в ЕЕПРОМ
4. Если нет - рабочий режим

Как выглядит на практике:
1. подключаем на один выходной канал нагрузку для индикации (кулеры, лампочки, светодиоды, пищалки...)
2. Подключаем регулируемый блок питания
3. Замыкаем джампер и включаем
4. Включается выходной канал - пошел отсчет 30 сек, выставляем на входе нужное напряжение
5. Таймер тикнул, нагрузка отключилась - признак того, что значение записано и пошли следующие 30 сек на второй порог
6. Выставляем нужное напряжение
7. Таймер тикнул - включилась нагрузка на 3 сек (признак того, что второе значение записано)
8. Все выключилось, БП в режиме ожидания

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

oleg707
27.10.2018, 20:24
Как сделал у себя:
1. Контроллер при включении проверяет режим программирования (замкнутый джампер)
2. Если да - то дается по 30 секунд на выставление нижнего и верхнего порога напряжения бортсети
3. Новые значения пишутся в ЕЕПРОМ
4. Если нет - рабочий режим


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

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

Калибровка делается один раз, прошить на свои значения блок проще, чем иметь регулируемый до сотых долей настольный блок питания.

В любом случае, если я изготавливаю блок питания для планшета на заказ, то клиент получает готовый, прошитый, калиброванный блок с настройками как у меня в машине. Если кто хочет их поменять ( 20% людей), то юсб кабель для прошивки у них есть, а регулируемого источника - нет.

mazay66
28.10.2018, 13:33
Да. Подобрал 100К. Отключается при 11.3В. В "спящем" отрабатывает, как надо - выключается чётко примерно через 4 секунды после снижения напряжения до 11.3В, но при "кручении стартером" - ближе ко второй секунде питание пропадает.
Я забыл, что у тебя собственная плата. Я говорил про готовые китайские модули с МР1584. Там два резистора по 100кОм уже впаяны в делителе между плюсом и минусом. Верхнее плечо делителя с платы убирал, и все. Далее по схеме, с номиналами, приложенними в сообщении выше.

skanch
28.10.2018, 14:10
Я забыл, что у тебя собственная плата. Я говорил про готовые китайские модули с МР1584. Там два резистора по 100кОм уже впаяны в делителе между плюсом и минусом. Верхнее плечо делителя с платы убирал, и все. Далее по схеме, с номиналами, приложенними в сообщении выше.
Я на отдельном модуле попробовал...

5038150382

oleg707
28.10.2018, 15:52
Я на отдельном модуле попробовал...

5038150382

я себе не выдержал и заказал набор проводных резисторов (https://duino.ru/nabor-rezistorov) (0,125W) как раз для таких экспериментов :pleasantry:

oleg707
28.10.2018, 21:07
Важное обновление
Выкладываю обновление печатной платы БП5mini+ 2.2
50383 открывать в DipTrace (https://diptrace.com/rus/download/download-diptrace/)
Прошивка полностью совместима с версиями BP5mini, BP5mini2.1, BP5mini+2.2. На всякий случай продублирую тут тоже.
50384
фото выложу немного позже.

oleg707
01.11.2018, 13:54
Предыдущая часть (http://pccar.ru/showpost.php?p=406062&postcount=80)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем питание на батарею планшета
Для этого включаем логическую единицу (+5В) на D6 ардуины. Напряжение идет на управляющую ногу IN2 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90). На выходе OUT2 появляется +12В, которое пошло на входные ножки ДС-ДС преобразователей.
5039850399

При этом ДС-ДС-1 включается, на выходе его появляется заранее настроенное напряжение 4-4,5В, которое идет на выход соответствующий контакт выходного разъема блока питания.
Если напряжения на выходе дс-дс1 (4В) нет, а на входе (+12В) есть, следует проверить (или временно выпаять) стабилитроны ZD3, ZD4 (могут закоротить при самостоятельной подстройке напряжения выше 5,6В)
Также проверить С2, С14.
50400

Поскольку на ДС-ДС-2 подпаян дополнительный управляющий провод (EN2), и там присутствует низкий логический уровень (масса), ДС-ДС-2 НЕ включается.


Cледующая часть (http://pccar.ru/showpost.php?p=406498&postcount=115)

skanch
01.11.2018, 20:23
Олег, оформил бы всё одним постом, а то это как сериал "Санта-Барбара -"уже забыл, что было в предыдущих сериях"...

oleg707
01.11.2018, 20:31
Олег, оформил бы всё одним постом, а то это как сериал "Санта-Барбара -"уже забыл, что было в предыдущих сериях"...

Времени нет. Я комп раз в неделю максимум включаю, в основном с планшета , что не облегчает ситуации:) А сегодня вольная минутка выдалась, и то, когда писал, уже семья звала. Все таки в Беларуси времени было значительно больше.

Для тех, кто забыл и для облегчения навигации специально делаю ссылки на предыдущее описание и на следующее.

avaRi
03.11.2018, 18:20
Отдам даром печатные платы от 5 версии блока !!!!5mini-6_4_на_pccar.zip (http://pccar.ru/attachment.php?attachmentid=48387&d=1508006758)
50408

50409

50410
В наличии 7 штук. 2 блока я собрал для себя, 1 одну плату про запас.
Собранные блоки отлично работают. Я до недавнего времени катал с еще старее те, что на KIW.
7 готов подарить, так как лежат без дела.
Одна плата в одни руки!
С вас оплата почтовых расходов!
Обязательное фото готового блока!
Отписываемся здесь, и на почту 9146635@gmail.com, тема: печатка бп Олег707.

oleg707
03.11.2018, 19:27
Отдам даром печатные платы от 5 версии блока !!!!5mini-6_4_на_pccar.zip (http://pccar.ru/attachment.php?attachmentid=48387&d=1508006758)

В наличии 7 штук. 2 блока я собрал для себя, 1 одну плату про запас.
Собранные блоки отлично работают. Я до недавнего времени катал с еще старее те, что на KIW.
7 готов подарить, так как лежат без дела.
С вас оплата почтовых расходов!
Обязательное фото готового блока!
Отписываемся здесь, и на почту 9146635@gmail.com, тема: печатка бп Олег707.

Несмотря на то, что плата старого поколения, хорошо себя показала. Только не помню на сто процентов, совместимы ли с ней прошивки последних версий, вроде бы должны быть совместимы.
На фото заметил нераспаянную подтяжку i2c шины данных, R16, R17 Обязательно запаять 3.3К ( от 1 до 5КОм).

avaRi
03.11.2018, 19:35
Несмотря на то, что плата старого поколения, хорошо себя показала. Только не помню на сто процентов, совместимы ли с ней прошивки последних версий, вроде бы должны быть совместимы.
На фото заметил нераспаянную подтяжку i2c шины данных, R16, R17 Обязательно запаять 3.3К ( от 1 до 5КОм).
Прошивку залил м36 все отлично.
Подтяжку запаяю, спасибо!

mazay66
03.11.2018, 20:11
Взял бы пару плат. На новогодних выходных будет много времени, чтобы спаять и потестить блок с ардуино. Оценить возможеости "умного" блока от Олега

oleg707
07.11.2018, 22:44
Предыдущая часть (http://pccar.ru/showpost.php?p=406319&postcount=108)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем (+5V (POGO(USB)) на пого пин ( в 7-2012) либо на юсб (+5В) .
Для этого включаем логическую единицу (+5В) на D2 ардуины. Напряжение идет через R16 на подпаянный на плату ДС-ДС-2 дополнительный управляющий провод (EN2). Поскольку напряжение +12В на входе уже есть, на выходе дс-дс появляется настроенное заранее питание 5,0В.

5044850449

Если напряжения на выходе дс-дс2 (5В) нет, а на входе (+12В) есть, следует проверить управляющее напряжение в точке EN2 (+5В), следует проверить (или временно выпаять) стабилитроны ZD1, ZD2 (могут закоротить при самостоятельной подстройке напряжения выше 5,6В)
Также проверить С3, С13.
50450


Cледующая часть (http://pccar.ru/showpost.php?p=406617&postcount=116)

oleg707
18.11.2018, 14:57
Предыдущая часть (http://pccar.ru/showpost.php?p=406498&postcount=115)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем минус на выход OTG (нужно для определения ЮСБ периферии планшетом.)
Для этого включаем логическую единицу (+5В) на D10 ардуины. Напряжение идет через R13 на 3pin твердотельного реле LH1502 (https://www.vishay.com/docs/83806/lh1502ba.pdf). При этом замыкаются нормально разомкнутые контакты S2 и S2', подавая массу на соответствующий контакт OTG выходного разъема блока питания.
Если S2 и S2' не замкнуты, проверить напряжение на на 3pin твердотельного реле LH1502. Должно быть 1,2В.
50469
50470

Cледующая часть (http://pccar.ru/showpost.php?p=406631&postcount=118)

oleg707
18.11.2018, 15:45
По вашим просьбам выкладываю фото собранного БПмини2,2 без настройки, регулировки и т.п. для того, чтобы можно было посмотреть номиналы деталей.
Оригиналы (3,2Мб) сайт не принимает, пришлось немного ужать.
50471
50472

oleg707
20.11.2018, 21:30
Предыдущая часть (http://pccar.ru/showpost.php?p=406617&postcount=116)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем питание +5,0В на хаб. Для этого включаем логический ноль (массу) на ножке D11, затем через резистор R15 низкий уровень напряжения поступает на затвор транзистора хаба, тот открывается и пускает +5В со второго dc-dc ( который идет на зарядку планшета) на соответствующий контакт HUB(+5V) выходного разъема блока питания.
Если на HUB(+5V) нет напряжения (+5В), то проверить напряжение +5В на выходе дс-дс-2 и низкий уровень напряжения на затворе транзистора Q1 (0,5В). Заменить транзистор.
Для теста можно закоротить HUB(+5V) и +5V (POGO(USB) .
50473

Cледующая часть (http://pccar.ru/showpost.php?p=406685&postcount=120)

oleg707
24.11.2018, 22:04
Делюсь возможным решением проблемы
Суть:
При запуске машины, может не включится хаб, соотв. нет звука, нет флешки.
выяснилось что если сначала включить хаб, потом массу на otg, тогда флешка и звуковуха без проблем определяются
Сделал таймер после включения АСС хаб 2100 otg 3100, проблема решилась) usb устройства нормально цепляются
Передергивание питания тоже убрал, изикап мне не нужен, камера в штатной магнитоле будет

Потестирую этот режим на своей машине, если понравится и не будет ухудшения стабильности, сделаю основным в следующих прошивках.

oleg707
25.11.2018, 16:02
Предыдущая часть (http://pccar.ru/showpost.php?p=406631&postcount=118)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем питание на видеорегистратор (либо другой потребитель, подключаемый на +12В). Нагрузку, потребляющую выше 2 ампера подключать не советуется.
Для этого включаем логическую единицу (+5В) на D4 ардуины. Напряжение идет на управляющую ногу IN1 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90). На выходе OUT1 появляется +12В , которое идет на выход REG на соответствующий контакт выходного разъема блока питания.
50488
Далее, через паузу (определенную в программе процессора) после включения ACC включаем питание на включение внешнего усилителя звука REMOUTE
50489
Для этого включаем логическую единицу (+5В) на D7 ардуины. Напряжение идет на управляющую ногу IN3 интеллектуального ключа ITS724G (https://www.infineon.com/dgdl/Infineon-ITS724G-DS-v01_01-en.pdf?fileId=db3a304412b407950112b428d6083e90). На выходе OUT3 появляется +12В , которое идет на выход REM на соответствующий контакт выходного разъема блока питания.
Нагрузку, потребляющую выше 2 ампера подключать не советуется.
Если выход REM не включен, то нужно подать 14В на АСС и АКБ (завести автомобиль). Либо выключить-включить зажигание. Логика режима энергосбережения.
50490
* в первые 15 секунд при холодном пуске держим REM выключенным


Следующая часть (http://pccar.ru/showpost.php?p=406752&postcount=121)

oleg707
01.12.2018, 15:13
Предыдущая часть (http://pccar.ru/showpost.php?p=406685&postcount=120)

Далее, через паузу (определенную в программе процессора) после включения ACC включаем экран.
Для этого включаем логическую единицу (+5В) на D12 ардуины. Напряжение идет через R14 на 1pin твердотельного реле LH1502 (https://www.vishay.com/docs/83806/lh1502ba.pdf). При этом размыкаются нормально замкнутые контакты S1 и S1', убирая массу с соответствующего контакта HALL выходного разъема блока питания.
Если S1 и S1' не разомкнуты, проверить напряжение на 1pin твердотельного реле LH1502 (https://www.vishay.com/docs/83806/lh1502ba.pdf). Должно быть 1,2В.
50503
50504
*в первые 60с после выключения АСС управление на выключение экрана через ДХ не идет, нужно для корректной работы при "холодном старте" планшета.

Начать сначала (http://pccar.ru/showpost.php?p=405633&postcount=39)

Lampcos
02.12.2018, 14:13
Всем, привет.
Как и было условлено при покупке кита данного БП - сам паяю, автор консультирует, результаты поэтапно выкладываются сюда.
Пост будет из 2 частей: сама сборка и первый запуск.
Погнали.
Получил посылку достаточно быстро. Олег отправил буквально через два дня, это вдвойне приятно, так как даже неделю считаю нормальным в сиу что у многих это хобби, а не постоянка, поэтому отправка по субботам - это НОРМАЛЬНО, сам так всегда отправлял, остальное от почты зависит. Ну это отступление. :) .Теперь к существу.
Упаковано ОК. доехало все целым.
Так как особо много не паяю большие партии плат, поэтому стараюсь искать новые варианты флюсов и способов паять. В данный раз решил попробовать паяльный жир, нейтральный. Купил баночку - жестковат оказался, поставил на батарею - не особо помогло.
Купил в другом магазине, там получше и при температуре +23 в комнате уже похож на мед по консистенции, очень удобно оказалось работать зубочисткой.
1. На пятаки под смд нанес жир только на один из выводов, пробежался припоем поставил капельки. Запаял смд резисторы и конденсаторы.
В принципе даже схемы не понадобилось, все номиналы написаны на плате.
5050850509
Видны капельки не запаянных диодов
2. Запаял диоды и микросхему твердотельных реле
50510
Запаял диоды и микросхему ключей
50511
3. Затем запаял контакты на платы преобразователей и ардуинки - муторное дело, так как пояски вокруг отверстий очень тонкие, пришлось использовать ЛТИ-120 и потом отмыл по быстрому изопропиловым спиртом.
4. Впаял электролиты, так как у меня есть требование по высоте - впаял как мне необходимо.
Автором предупрежден, что необходим некоторый воздухообмен для отвода тепла от преобразователей. У меня этот вопрос будет решен принудительной подачей воздуха в пространство, так как кроме БП у меня в этой высоте будет еще несколько источников тепла.
Запаял преобразователи, ардуинку пока не впаивал (на фото она просто вставленав плату БП).
50512
6. Вынул ардуинку, пробежался по плате феном, так для самоуспокоения, что все пропаялось.
Взял плату, взял фейри, теплая вода, зубная щетка. И минут 5 все протирал, вычищая остатки жира. В целом неплохо получилось, потом пополоскал от остатков фейри и .... в духовку на 110 градусов минут на 15. Запаха фейри и жира не было, значит все выполоскалось. :wink2:

Продолжение следует

Lampcos
02.12.2018, 23:08
Продолжение. Первый запуск.
Все подключил, на источнике выставил +12,9В.
На преобразователях выставил переменник на минимальное напряжение.
Включаю...красный диод горит на ардуине, экран просто синий - горит подсветка..и всё. На выходе преобразователей по нолям.
Оказывается надо чтобы еще на ардуинке мигал зеленый диод.
В итоге оказалось почему то, что нужно перезалить прошивку.
Перезалил - зеленый диод заморгал, на преобразователях появилось напряжение минимальное - у меня было по 0,86В.
Подкруткой переменников выставил на планшет 4,25В. на юсб хаб - 5,08В
Но экран синий. Я честно говоря опешил. Оказалось надо было покрутить сзади дисплея подстроечник, тем самым настроив соотношение яркости подсветки и свечения самих цифр. Но ни тут то было, дисплей показал следующее
50515
Оказалось это так дисплей реагирует на прикосновение пальцев. Поэтому кладем дисплей на стол, нажимаем ресет и вуаля
50516
Здесь уже видно напряжение 11,99, это я выставил 12 вольт на источнике.
Таким образом:
1. После запуска при необходимости перезаливаем прошивку
2. Регулируем яркость подсветки.
3. Не трогаем пальцами экран (в моем случае это так, хотя Олег говорит, так не должно быть, но имеем, что имеем)

Теперь к калибровке. Выставляем 12В на источнике, берем пинцет или кусок провода и снова ресетимся. После этого на мговение замыкаем "cal" и видим служебную инфу.
Потом 5 рад замыкаем и размыкаем и на пятом разе оставляет замкнутыми, ждем появления надписи "end kalibr" и радуемся жизни.
Нюанс: желательно, чтобы контакт при замыкании был хорошим, с первого раза у меня не удалось дождаться надписи окончания калибровки, поэтому был взят другой пинцет, отмыт спиртом.
Можно конечно кусок провода, но пинцетом мне было как то удобнее.
В итоге все настроилось, теперь к полевым испытаниям под нагрузкой.
Как пройдут, так отпишусь.

П.С. Олегу ОГРОМНОЕ спасибо за оперативную техподдержку, я бы даже сказал - за дружественную поддержку.

Upgreyd
05.12.2018, 15:23
А может кто-то расписать, как залить прошивку? Скачал я сборку ардуины из этой темы, скопипастил скетч, но при Verify он выдаёт несколько строчек красным (типа ошибки), но в итоге всё компилится. Это нормально, можно заливать?

oleg707
05.12.2018, 18:41
А может кто-то расписать, как залить прошивку? Скачал я сборку ардуины из этой темы, скопипастил скетч, но при Verify он выдаёт несколько строчек красным (типа ошибки), но в итоге всё компилится. Это нормально, можно заливать?

можно, это библиотеки красным пишут. На работу не влияет.
После компиляции (ждём) пройдет загрузка скетча
Wring | ################################################## | 100% 5.48s
И его проверка
Reading | ################################################## | 100% 4.14s
В случае удачной проверки будет сообщение.
avrdude: verifying ...
avrdude: 18872 bytes of flash verified
avrdude done. Thank you.

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

Upgreyd
05.12.2018, 23:59
В общем продолжим обсуждение неполадок здесь. В копилку опыта так сказать.
Проблема в следующем - в момент, когда появляется ACC блок выключается. Т. е. не знаю, выключается ли блок, но планшет выключается и снова включается.
Я думал, что блок выключается ПОСЛЕ пропадания ACC, но на самом деле он уходит в перезагруз, как только после сна ACC появляется. Дебаг в прошивке включён. Все это происходит и с БП на столе, и в машине.
На словах может коряво объяснил, прикладываю видео
https://www.youtube.com/watch?v=7IrOEnRiHZ4&feature=youtu.be

oleg707
06.12.2018, 01:02
В общем продолжим обсуждение неполадок здесь. В копилку опыта так сказать.
Проблема в следующем - в момент, когда появляется ACC блок выключается. Т. е. не знаю, выключается ли блок, но планшет выключается и снова включается.
Я думал, что блок выключается ПОСЛЕ пропадания ACC, но на самом деле он уходит в перезагруз, как только после сна ACC появляется. Дебаг в прошивке включён. Все это происходит и с БП на столе, и в машине.
На словах может коряво объяснил, прикладываю видео
https://www.youtube.com/watch?v=7IrOEnRiHZ4&feature=youtu.be

А можно снять то же самое видео, но с подключенным вольтметром на "батарее планшета" ?
При выключенном зажигании должен постоянно быть включен дс-дс, который постоянно питает батарею. И этот дс-дс НЕ должен выключаться в режиме отладки. Этот дс-дс и в нормальном режиме всегда работать должен, имитируя батарею планшета ( у меня месяцами не выключается).
Прошу сделать это на прошивке m36, для облегчения поиска проблемы.


С сайтом что-то, не работают вложения, залью прошивку на обменник и выложу ссылку.

Upgreyd
06.12.2018, 01:13
Так, проблема локализована и решена) Оказалось виной всему косяк в ОТГ кабеле. Колдовство. При инициализации хаба, планшет уходил в ребут. Так тихо мирно перезагружался. Перепаял кабель, всё решилось, блок работает отлично.

oleg707
07.12.2018, 00:02
Поскольку что-то с форумом и нельзя просмотреть вложения и скачать файлы, дублирую файлы на внешнем обменнике.

прошивка, стабильная m36 (https://mega.nz/#!0xRGmCCJ!zV2DSrQLlwNRopbSSVAeQFECtx00mPXGXuTSQXy ht7Y) Прошивка полностью совместима с версиями BP5mini, BP5mini2.1, BP5mini+2.2
Дополнительная ссылка на прошивки (https://drive.google.com/drive/folders/1CE1Zw7LCBj_QRcN1BK0tEOqIdWEIlcdp) .
печатня плата 87+ (https://mega.nz/#!B1AjUAbK!7v8OCvte4nYh7nlfIJ8AordJqSr9Sn-4seizTDmcZXY) открывать в DipTrace (https://diptrace.com/rus/download/download-diptrace/)

Инструкция по подключению (https://mega.nz/#!pw5QFYIL!1cAs6Z3NnbaMPN3SNGJJwqdBspjy6SwvAhlcTw7 MO0E)

Краткий принцип работы БП5mini (+поиск неисправностей) (https://mega.nz/#F!18YHmYzJ!BY1MDhTRTQjtRRpSniZGcg)

Все эти ссылки идут на обменник, который синхронизируется с моим компьютером, поэтому тут скорее всего самые свежие версии файлов для открытого доступа.

oleg707
08.12.2018, 19:05
Рекомендованный порядок настройки БП после сборки.
Итак, мы спаяли, отмыли, собрали БП (блок питания) .
5054750548
Без прошивки это просто груда железа, поэтому надо для начала прошить.
Поскольку используется ардуино NANO ( именно для облегчения прошивки простым пользователям), то для прошивки понадобится всего лишь mini-USB кабель.
50549
Для начала скачиваем мою сборку среды Arduino IDE (там уже есть все необходимые библиотеки).
Для этого идем по одной из ссылок и скачиваем, потом распаковываем в корень диска C:\
https://mega.nz/#!FlhiWTgZ!fhH_QTRTFIWeh5Uid1rigkZSrDTmov-sHJEXG-538Sc
https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
Получаем такой путь c:\Arduino\arduino-1.6.12\
Кроме того, в системе должны быть установлены драйвера CH340G (давно есть подписанные). Как поставить распишу позже, а пока гугл в помощь.
Запускаем c:\Arduino\arduino-1.6.12\arduino.exe
50550

Следующая часть (http://pccar.ru/showthread.php?p=407012#post407012)

Upgreyd
09.12.2018, 14:49
В общем, небольшой отчет по блоку от Олега, спустя некоторое время эксплуатации "и в хвост и в гриву".
Фото к сожалению не будет, но и на словах все понятно.

Авто - Nissan Almera Classic
планшет - Nexus 7 2013 WIFI.
Питание - блок от oleg707
DAC -Q1 HiFi Mini Computer External Sound Card PCM2704 (Aliexpress) + Изолятор массы Nobsound ADuM4160 USB to USB Isolator Module (Aliexpress)
Усилитель GHXAMP TDA7850 4x50W (Aliexpress)
USB Хаб - D-LINK DUB-H7 (второй ревизии)

Собирать планшет в авто, мне пришло в голову, после того как мне в руки попала магнитола на андроиде JOYING. Мало того, что она устанавливалась в рамку с отвратительными щелями, так и качество было просто отвратным. В интерфейсе отовсюду торчали китайские уши, с уродливой графикой, иконками явно из бесплатных иконпаков 00-х годов. Короче это поделия я продал и вымыл руки с мылом.
Nexus просто создан для Альмеры классик. Он устанавливается в рамку просто идеально, при этом выглядит там современно и по-заводскому.

Когда все компоненты приехали и я все собрал воедино, ожидаемо заводилось это дело с проблемами. Дело в питании, да. Я изначально заказал блок питания у местного форумчанина. Но стабильно он так и не заработал. Я провел несколько месяцев в переписке с автором блока, искал "идеальную массу, идеальный плюс, провода, +12 от замка, от атомной электростанции, ловил лучи из космоса итд". Конечно же пенял на свои кривые руки и на "азиатские +12" (по совету автора блока, конечно же).
Вобщем решил попробовать другой блок, хотелось все же все сделать по-уму.
Я заказал готовый блок у Олега и все завелось почти с полоборота (несчитая глюка с ОТГ кабелем, о котором я написал немного выше. Но это, конечно, к БП отношения не имеет).
Блок показал себя мега стабильным. И в холод (я тут эксперементировал, на пару дней засовывал всю сборку в морозилку, в -18,) вс] завелось отлично.
В общем, на мой взгляд это самая удачная реализация блока для нексуса на сегодняшний день.
Огромный плюс, возможность настройки таймингов. Я немного подкручивал время до инициализации хаба, что бы убрать щелчек при включении усилителя. Все отлично получилось. Олегу респектище огромный.

oleg707
09.12.2018, 15:09
Предыдущая часть (http://pccar.ru/showpost.php?p=406984&postcount=130)


И проверяем наличие ком портов.
В моем случае мы имеем 1, 49, 48, 47.
ПОСЛЕ этого подключаем БП (Arduino NANO) к кабелю mini-USB и втыкаем его в юсб компьютера (ноутбука).
В ардуино должен засветиться светодиод питания. Рядом может мигать еще один светодиод.
Опять проверяем доступные порты:
50552
В моем случае мы имеем 1, 49, 48, 47, 36.
То есть появился 36 порт, его и выбираем. Если порт не появилсяи светодиод питания светится, проверяем драйвера CH340G.
Далее выбираем плату и тип процессора.
Инструменты - плата: Arduinino NANO.
Процессор: ATmega328.
Должны получить примерно такое:
50553

Следующая часть (http://pccar.ru/showpost.php?p=407176&postcount=136)

oleg707
11.12.2018, 18:24
В общем, небольшой отчет по блоку от Олега, спустя некоторое время эксплуатации "и в хвост и в гриву".
Фото к сожалению не будет, но и на словах все понятно.

Авто - Nissan Almera Classic
планшет - Nexus 7 2013 WIFI.
Питание - блок от oleg707
DAC -Q1 HiFi Mini Computer External Sound Card PCM2704 (Aliexpress) + Изолятор массы Nobsound ADuM4160 USB to USB Isolator Module (Aliexpress)
Усилитель GHXAMP TDA7850 4x50W (Aliexpress)
USB Хаб - D-LINK DUB-H7 (второй ревизии)

Собирать планшет в авто, мне пришло в голову, после того как мне в руки попала магнитола на андроиде JOYING. Мало того, что она устанавливалась в рамку с отвратительными щелями, так и качество было просто отвратным. В интерфейсе отовсюду торчали китайские уши, с уродливой графикой, иконками явно из бесплатных иконпаков 00-х годов. Короче это поделия я продал и вымыл руки с мылом.
Nexus просто создан для Альмеры классик. Он устанавливается в рамку просто идеально, при этом выглядит там современно и по-заводскому.

Когда все компоненты приехали и я все собрал воедино, ожидаемо заводилось это дело с проблемами. Дело в питании, да. Я изначально заказал блок питания у местного форумчанина. Но стабильно он так и не заработал. Я провел несколько месяцев в переписке с автором блока, искал "идеальную массу, идеальный плюс, провода, +12 от замка, от атомной электростанции, ловил лучи из космоса итд". Конечно же пенял на свои кривые руки и на "азиатские +12" (по совету автора блока, конечно же).
Вобщем решил попробовать другой блок, хотелось все же все сделать по-уму.
Я заказал готовый блок у Олега и все завелось почти с полоборота (несчитая глюка с ОТГ кабелем, о котором я написал немного выше. Но это, конечно, к БП отношения не имеет).
Блок показал себя мега стабильным. И в холод (я тут эксперементировал, на пару дней засовывал всю сборку в морозилку, в -18,) вс] завелось отлично.
В общем, на мой взгляд это самая удачная реализация блока для нексуса на сегодняшний день.
Огромный плюс, возможность настройки таймингов. Я немного подкручивал время до инициализации хаба, что бы убрать щелчек при включении усилителя. Все отлично получилось. Олегу респектище огромный.

Спасибо :yes4:
Напомню, что все значения пользователя можно записать в энергонезависимую память и считывать оттуда, полезно при обновлении прошивки.

volgomax
14.12.2018, 22:47
Добрый вечер друзья. Я не программист, по этому возник глупый вопрос, при проверке - компилировании скетча много "красного". Так должно быть?

oleg707
15.12.2018, 00:05
Добрый вечер друзья. Я не программист, по этому возник глупый вопрос, при проверке - компилировании скетча много "красного". Так должно быть?

Да, это совместимость компонентов библиотек, на работу не влияет.
Я чуть позже довыложу мануал по прошивке и настройке, времени нет.

oleg707
16.12.2018, 15:11
Предыдущая часть (http://pccar.ru/showpost.php?p=407012&postcount=132)

Теперь скачиваем прошивку, например из этого поста (http://pccar.ru/showpost.php?p=406918&postcount=129) или m36.zip (https://mega.nz/#!0xRGmCCJ!zV2DSrQLlwNRopbSSVAeQFECtx00mPXGXuTSQXy ht7Y) и сохраняем в C:\Arduino, то есть получили файл c:\Arduino\m36.zip, который нужно распаковать.
После распаковки получили файлы в папке c:\Arduino\m36\m36.ino
Теперь переходим снова в Arduino IDE, там выбираем файл-открыть и выбираем наш файл m36.ino, жмем открыть.
Открывается новое окно с программой внутри.
50572
При необходимости изменяем значения переменных на нужные нам.
По умолчанию прописаны те, которые стоят у меня в машине. (//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И )
После этого жмем стрелку загрузки скетча.
После компиляции (ждём) пройдет загрузка скетча
Writing | ################################################## | 100% 5.48s
И его проверка
Reading | ################################################## | 100% 4.14s
В случае удачной проверки будет сообщение.
avrdude: verifying ...
avrdude: 18872 bytes of flash verified
avrdude done. Thank you.
50573
В процессе прошивки наблюдаем перемигивание светодиодов Rx и Tx.
ВСЁ. Ардуино Nano прошита.

Следующая часть (http://pccar.ru/showpost.php?p=407294&postcount=138)

oleg707
17.12.2018, 23:14
Ссылка на хорошую статью простым языком про дс-дс преобразователи
Разработка buck-преобразователя на STM32F334: принцип работы, расчеты, макетирование (https://habr.com/post/432778/)

oleg707
20.12.2018, 23:00
Предыдущая часть (http://pccar.ru/showpost.php?p=407176&postcount=136)


После прошивки ардуино пора приступать к настройке напряжений.
Отключаем mini-USB кабель.
Тонкой подходящей отверткой выкручиваем подстроечные резситоры на ДС-ДС модулей на минимальное напряжение.
Если ошибетесь, то сгорят защитные стабилитроны на выходе с дсдс на блоке питания.
В случае MP1584EN выглядит так:
50580
Теперь подключаем экран по шине I2C. Для этого подключаем провода -,+5V, SCL, SDA
Поддерживаются дисплеи:
i2c 1602 (https://ru.aliexpress.com/af/i2c-1602-16x2.html?SearchText=i2c+1602+16x2&d=y&initiative_id=SB_20181220105903&origin=n&catId=0&isViewCP=y&jump=afs)50581 и SSD1306 (https://ru.aliexpress.com/af/ssd1306-i2c-128x64.html?SearchText=ssd1306+i2c+128x64&d=y&initiative_id=SB_20181220105829&origin=n&catId=0&isViewCP=y&jump=afs)(ssd1306 i2c 128x64)50582


Теперь подключаем к настольному лабораторному источнику питания МИНУС, ПЛЮС АКБ, И ПЛЮС АСС.
И подаем туда питание 12-14В.
50583

Увидели версию прошивки и общую готовность к работе БП.
Теперь настраиваем напряжения на выходах ДС-ДС.
Для этого подключаемся от настольного лабораторного источника питания: МИНУС, ПЛЮС АКБ, И ПЛЮС АСС.
И подаем но БП питание 12-14В.
Минусовой провод вольтметра подключаем на минус БП, плюсовой - на +4V (выход батареи планшета).
У нас там уже было выставлено минимальное напряжение, поэтому вольтметр показывает около 0,9В.
ОЧЕНЬ ПЛАВНО крутим подстроечный резистор на ДС-ДС, на котором не припаян дополнительный проводок регулировки против часовой стрелки, одновременно наблюдая за показаниями вольтметра.
Выставляем нужное нам значение напряжения (4,0-4,3В).
Теперь аналогично настраиваем второй дс-дс.
Минусовой провод вольтметра подключаем на минус БП, плюсовой - на +5V (+5V_USB_(POGO)).
ОЧЕНЬ ПЛАВНО крутим подстроечный резистор на ДС-ДС, на котором припаян дополнительный проводок регулировки против часовой стрелки, одновременно наблюдая за показаниями вольтметра.
Выставляем нужное нам значение напряжения (5,0-5,2В).


После настройки нам нужно откалибровать БП.
Для настройки а главное, калибровки, необходимо иметь максимально точный вольтметр.
Для его поверки самостоятельно достаточно купить один раз источник образцового напряжения.
Ссылки - обзоры 1 (https://mysku.ru/blog/aliexpress/56453.html) 2 (https://mysku.ru/blog/ebay/51518.html) 3 (https://mysku.ru/blog/china-stores/64388.html) 4 (https://mysku.ru/blog/aliexpress/49553.html)
Я имею такой, на базе AD 584:
50584
Также необходимо иметь лабораторный блок питания с возможностью точной регулировки (https://ru.aliexpress.com/item/RD-DPS5015-Constant-Voltage-current-Step-down-Programmable-digital-Power-Supply-buck-Voltage-converter-color-LCD/32702714880.html?spm=a2g0v.search0104.3.1.6caf49fd yEHCb2&ws_ab_test=searchweb0_0,searchweb201602_4_10065_10 068_3)(до сотых вольт).
Выставляем РОВНО 12,00В, измеряя нашим поверенным вольтметром прямо на плате BP5mini.
50585
Теперь нам понадобится что-нибудь металлическое ( тонкий пинцет, кусочек припоя).
Поскольку калибровка возможна только в первые 60с работы блока жмем ресет ( либо выключаем питание на несколько секунд).
Замыкаем на мгновение между собой точки, помеченные как "cal".
На экране увидим техническую информацию ( значения АЦП каналов БАТ и АСС 790 789 счетчик 001 значения напряжений вычисленные уже с помощью коррекции, а также на второй строчке коррекцию, которую на данный момент использует БП С108 108) ( С127 127)
50586
После того 5 раз подряд замыкаем контакты "cal" и оставляем перемычку замкнутой.
Ждем пока не появится надпись, можно посмотреть новые значения калибровки, записанные в энергонезависимую память процессора
50587
Все. Теперь остались только тесты под нагрузкой. С каждого из ДС-ДС можно вытянуь без охлаждения до 2А.
После успешно пройденных тестов на подстроечные резисторы на ДС-ДС можно капнуть капельку лака, для более надежной фиксации.

Начало (http://pccar.ru/showpost.php?p=406984&postcount=130)

oleg707
20.12.2018, 23:21
Фух, осилил :sm467::sm490:

oleg707
05.01.2019, 02:17
Итак, представляю две версии прошивки для блока питания. m37 и m38

m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.

m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.

то есть по простому если у вас есть дисплей 1602http://pccar.ru/attachment.php?attachmentid=50581&d=1545332544 то шьем m38. Если дисплей http://pccar.ru/attachment.php?attachmentid=50582&d=1545332560 , то он потребляет слишком много памяти, а без её запаса код может работать нестабильно.

Прошивки выложил тут (https://drive.google.com/drive/folders/1CE1Zw7LCBj_QRcN1BK0tEOqIdWEIlcdp?usp=sharing)

oleg707
07.01.2019, 01:39
дублирую на всякий случай прошивку m38 в текстовом виде. Откатался почти 2 недели - стабильно себя ведет.
1250 строк, 130000 символов. Я в шоке, кто мне там ATtiny советовал? :big:
const byte ver = 38;// ( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 3.01.19.2117

// для 5mini, 5mini2.1, 5mini+2.2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
// 0 - 0 - берём значения из скетча, игнорируя память
// 1 - сохраняем в EEPROM
// 2 - берем значения из памяти eeprom игнорируя скетч
byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long LONG_koefficient_delitelia_ACC =0;
unsigned long LONG_koefficient_delitelia_AKB =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру
{
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long LONG_koefficient_delitelia_ACC ;
unsigned long LONG_koefficient_delitelia_AKB ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
const byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
/*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
*///13
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024
int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX
static int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX
float Uacc_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
float Uakb_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего


//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

static byte PINrawACC = A0; // замер для 5й версии
static byte PINrawAKB = A1; // замер для 5й версии
static byte PINkalibrovki = A2; // замер для 5й версии

//static byte PINrawACC = A7; // замер для 7й версии
//static byte PINrawAKB = A8; // замер для 7й версии
//static byte PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
static byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
static byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС
byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
/*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
*///13
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}

void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{

// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO // управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
// if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
//if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
// if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.

}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки при первой подаче питания. выполняются 1 раз.
{
Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать
if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча.
RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM
OBRABOTKA_KALIBROWKI();
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; // настройки порта D
DDRB = 0b00111110; // настройки порта B
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//vykluchic_vse();
/* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
*/
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки
/*//13
display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
*///13
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}

void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/10000) + '0'; //0 знач
text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/100)%10) + '0';// второе значение __0
text[3] = ((num/10)%10) + '0'; // третее значение ___
text[4] = (num%10) + '0'; // 4е значение ___
}

void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void OBRABOTKA_KALIBROWKI()
{//void OBRABOTKA_KALIBROWKI()

// проверка на прописанную в памяти калибровку
if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение.
{
if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295)
{
sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]);
sprintf(strokaII, "NE PROPISANA !!!") ;
INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине
displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
delay (1000); // задержка чтобы успеть прочитать
}
}
if (LONG_koefficient_delitelia_ACC == 4294967295)
{
LONG_koefficient_delitelia_ACC = 15364;
}
if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}

}//void OBRABOTKA_KALIBROWKI()


void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()
kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ


//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM



if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
LONG_koefficient_delitelia_ACC,
LONG_koefficient_delitelia_AKB,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);

LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;

}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока


// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharII(kalibrovkaNOW, &strokaI[8]); // вывод счетчика РЕЖИМА калибровки

sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);


FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

if (razreszenie_raboty_I_dva_C_sziny == 1) {displayDataToDISPLAY();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

/*void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}
// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

}//void analogReadU
*/
void READ_SREDNIEJE_U()
{ //void READ_SREDNIEJE_U
Uacc = analogRead(PINrawACC);
Uakb = analogRead(PINrawAKB);

Uacc_TMP = (Uacc_TMP + Uacc );
Uakb_TMP = (Uakb_TMP + Uakb );
cykly_usrednenij_U ++;

if (cykly_usrednenij_U == ilosc_usrednenij)
{
U_acc_real = Uacc_TMP*(LONG_koefficient_delitelia_ACC+1)/1000000.0/ilosc_usrednenij;
U_akb_real = Uakb_TMP*(LONG_koefficient_delitelia_AKB+1)/1000000.0/ilosc_usrednenij;

if (kalibrovkaACC<255 && kalibrovkaAKB<255) //если калибровка старого типа, вычисляем напряжение по старому, если мы не в режиме калибровки.
{
U_acc_real = (Uacc_TMP * (1410.0+kalibrovkaACC+0.05)/100000.0/ilosc_usrednenij);
U_akb_real = (Uakb_TMP * (1410.0+kalibrovkaAKB+0.05)/100000.0/ilosc_usrednenij );
}
cykly_usrednenij_U = 0;
Uacc_TMP = 0; // обнуляем для начала нового отсчета
Uakb_TMP = 0;
}

} //void READ_SREDNIEJE_U

void OBRABOTKA_REJIMA_OTLADKI()
{//OBRABOTKA_REJIMA_OTLADKI
if (OTLADKA >= 1)
{ //if (OTLADKA >= 1)
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - если напряжение ACC > 6В то считаем ACC=14,5В АКБ считаем всегда AKB=14,5В
// 3 - напряжение ACC всегда считаем ACC=14,5В напряжение АКБ всегда считаем AKB=14,5В
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (U_akb_real > 6) {U_akb_real = 14.50;} // принимаем напряжение аккумалятора автомобиля за 14,50В (если реальное напряжение AKB > 6В)
if (OTLADKA >= 2 )
{
U_akb_real = 14.50;
if (OTLADKA >= 3 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 2 )
}




// принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
}//if (OTLADKA >= 1) //конец режима отладки.
}//OBRABOTKA_REJIMA_OTLADKI

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
vykluchic_vse(); // вызвали функцию выключения всех выходов и напряжений с блока питания.
delay (500); // для зарядки конденсаторов после снятия нагрузки
//тут позже можно опционально добавить усреднение Uacc Uakb
//вычисляем новое значение калибровки
brac_nastrojki_iz_EEPROM =2; // включили режим считывания настроек из энергонезависимой памяти
RABOTA_z_EEPROM (); // считали значения пользователя из энергонезависимой памяти.
LONG_koefficient_delitelia_ACC = 12000000/Uacc;
LONG_koefficient_delitelia_AKB = 12000000/Uakb;
kalibrovkaNOW ++;
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW >= 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,255);
EEPROM.update(1,255);

brac_nastrojki_iz_EEPROM = 1; // включили режим записи настроек в энергонезависимую память
RABOTA_z_EEPROM (); // вписали значения пользователя с калибровкой в энергонезависимую память.

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //

delay (60000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
} // конец как только включили зажигание ( при любом напряжении батареи)


if (flagACC ==1 )
{// если flagACC == 1
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------

if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if (razreszenie_raboty_I_dva_C_sziny == 0) //Не даём заснуть при активном режиме
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------

if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop


READ_SREDNIEJE_U(); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(ilosc_usrednenij)раз.

if ( (millis() < 120000) )
{
if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0) // после 120с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ
{
if ( (millis() < 120000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();}
}
}

OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ

// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)



/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}

/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[6];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

if (kalibrovkaNOW <= 5) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами а преходим в функцию выключения всех выходов.
{
UPRAVLENIE_PINAMI();
}
else {vykluchic_vse(); }

}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _

______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напряжение батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик постоянно обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.
m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)

- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

oleg707
20.01.2019, 17:56
забыл дописать.
Кто хочет подключать такой дисплей http://pccar.ru/attachment.php?attachmentid=50582&d=1545332560,
то его поддержка с версии м38 прекращена ( м37 еще поддерживает).
Отказался потому как картинка, которая на него формируется, потребляет около 30% динамической памяти процессора, а я уперся в верхний потолок.

i2c 1602 дисплеи http://pccar.ru/attachment.php?attachmentid=50581&d=1545332544 поддерживаются и дальше. Я использую это для настройки и отладки, а в машине блок катается без дисплея.
Пора изучать STM:spiteful:

artolik
27.01.2019, 18:21
Здравствуйте уважаемые. Может кому нужна модель корпуса для этой платы,который можно напечатать на 3D принтере. Поделюсь моделькой https://yadi.sk/d/bdjHUv7ST030mQ

skanch
27.01.2019, 18:43
Здравствуйте уважаемые. Может кому нужна модель корпуса для этой платы,который можно напечатать на 3D принтере. Поделюсь моделькой https://yadi.sk/d/bdjHUv7ST030mQ
Фото готовой "коробки" можно увидеть? А то Solidworks не у всех есть...

artolik
27.01.2019, 19:16
https://d.radikal.ru/d09/1901/8d/fd4ad2fd3c5d.png (https://radikal.ru)

artolik
27.01.2019, 19:19
https://a.radikal.ru/a36/1901/39/f09e3e546249.png (https://radikal.ru)

skanch
27.01.2019, 19:30
А "напечатанный" есть?

artolik
27.01.2019, 20:00
К сожалению он уже установлен,под панелью и фото не делал,прошу поверить на слово,все подходит четко.

skanch
27.01.2019, 20:01
К сожалению он уже установлен,под панелью и фото не делал,прошу поверить на слово,все подходит четко.
Я не сомневаюсь, что всё получилось отлично...!

oleg707
27.01.2019, 20:05
Здравствуйте уважаемые. Может кому нужна модель корпуса для этой платы,который можно напечатать на 3D принтере. Поделюсь моделькой https://yadi.sk/d/bdjHUv7ST030mQ

А что стоит по деньгам если распечатать и плюс стоимость доставки? Примерно?

artolik
27.01.2019, 20:35
Олег,я свой принтер продал,мне печатал товарищ,да и сейчас услуги 3d печати на каждом углу,главное модельку иметь. Обычно моделирование стоит дороже печати.

oleg707
27.01.2019, 22:07
Олег,я свой принтер продал,мне печатал товарищ,да и сейчас услуги 3d печати на каждом углу,главное модельку иметь. Обычно моделирование стоит дороже печати.

Тогда или подтолкнуть, или отговорить от покупки 3d принтера. И если покупать, то какую модель?

artolik
29.01.2019, 14:07
Я свои два принтера собирал сам,первый был клон ультимейкер 2,второй H-bot на рельсах. Оба продал,не осилил моделирование.

oleg707
30.01.2019, 19:06
Я свои два принтера собирал сам,первый был клон ультимейкер 2,второй H-bot на рельсах. Оба продал,не осилил моделирование.

В итоге можешь что нибудь посоветовать, чтобы дёшево и сердито, и минимум доработок?

artolik
31.01.2019, 14:14
Готовый брать не советую.

oleg707
03.02.2019, 02:20
Люди, накидайте мне варианты использования хаба в вашем сценарии использования.
Я пока 4 порта нормально представляю чем занять, остальные - уже натягиваю сову на глобус.
Многие писали, что им нужен 8-и портовый хаб.
Вход - юсб порт планшета.

Выходы:
1 - изикап ( управляемый по питанию выход)
2 - звуковая карта
3 - процессор блока питания ( его юсб или ch340 - уарт) - для обновления прошивки блока питания.
4 - внешняя влешка ( юсб винчестер)
5 - порт для подключения кнопок руля
6 - мультимедиа клавиатура\ мышка
7 - ???

И да, знающие люди, есть ли лучший вариант чипа для хаба, чем GL850G (https://www.google.com/search?biw=1986&bih=763&tbm=isch&sa=1&ei=dhZWXMkN6IGvBLTblLAE&q=GL850G+dlink&oq=GL850G+dlink&gs_l=img.3...15553.23672..24059...3.0..1.93.746.9. .....1....1..gws-wiz-img.......0j0i30j0i24.X8GRET0wAvk), на котором собран всеми любимый хаб D-Link 7-Port USB 2.0 HUB Model No. DUB-H7 (https://ifixit-guide-pdfs.s3.amazonaws.com/pdf/ifixit/guide_31436_en.pdf)

oleg707
03.02.2019, 14:06
И да, может подскажете микросхемы логики, чтобы порты процессора развязать с внешним миром. Например для подключения энкодера. Не хочется прямо с проца вести линии наружу, одно неверное замыкание на +12 и порт выгорел. Защиту мудрить типа резистор + стабилитрон на каждый внешний порт не хочу, много мелких деталей.
Микросхемы типа 74HC...
Или может что ещё интересное есть?
Процессор - просматриваю на СТМ, потенциально там даже кан шина есть.

oleg707
06.02.2019, 00:30
Итого, поскольку ни подсказок, ни советов нету, буду разрабатывать сам.

Если хотите, можете подкинуть идей - пожеланий.
Делаю для себя новый тип блока питания, с встроенным хабом, звуковой картой PCM2704 ( с неё же можно вывести озвук по PCM и по оптике), поддержкой аналоговых кнопок руля ( может и по кан шине, не решил еще). Основной процессор STM32VCT6. Вспомогательный ( для совместимости) AT32u4 (AT32u4)( ардуино леонардо). Хаб юсб 2,0 ( все равно на большинстве планшетов выше нету) на GL850G, тем более оно у меня есть. Изикап - порт с управляемым подключением, внешним. Внутри похоже, не будет места.
Силовая часть - еще не решил.
Стоит ли делать усиленные порты питания хаба - тоже.
Прототип (http://pccar.ru/showpost.php?p=400675&postcount=31)дождался своего часа на моё внимание :yes2:

oleg707
06.02.2019, 00:43
Здравствуйте уважаемые. Может кому нужна модель корпуса для этой платы,который можно напечатать на 3D принтере. Поделюсь моделькой https://yadi.sk/d/bdjHUv7ST030mQ

можно перевыложить файл? у меня поврежденный архив качает

urikz
06.02.2019, 09:09
Итого, поскольку ни подсказок, ни советов нету, буду разрабатывать сам.

Если хотите, можете подкинуть идей - пожеланий.
Делаю для себя новый тип блока питания, с встроенным хабом, звуковой картой PCM2704 ( с неё же можно вывести озвук по PCM и по оптике), поддержкой аналоговых кнопок руля ( может и по кан шине, не решил еще). Основной процессор STM32VCT6. Вспомогательный ( для совместимости) AT32u4 (AT32u4)( ардуино леонардо). Хаб юсб 2,0 ( все равно на большинстве планшетов выше нету) на GL850G, тем более оно у меня есть. Изикап - порт с управляемым подключением, внешним. Внутри похоже, не будет места.
Силовая часть - еще не решил.
Стоит ли делать усиленные порты питания хаба - тоже.
Прототип (http://pccar.ru/showpost.php?p=400675&postcount=31)дождался своего часа на моё внимание :yes2:

Стоит ли делать усиленные порты питания хаба - стоит! Хотя-бы парочку!
И все это в плату мах-10х10 см чтоб за 2уе 10шт-эх мечты мои:rolleyes2:
Ждем короче...:blush:

oleg707
06.02.2019, 10:11
Стоит ли делать усиленные порты питания хаба - стоит! Хотя-бы парочку!
И все это в плату мах-10х10 см чтоб за 2уе 10шт-эх мечты мои:rolleyes2:
Ждем короче...:blush:

Где заказываешь за 2уе 10шт ?

urikz
06.02.2019, 15:33
Где заказываешь за 2уе 10шт ?
https://jlcpcb.com/ прототипы.. Я думал вы там делали предидущие платы судя по кодам на них...Ну доставка отдельно само собой идет от скорости и цифра.P/S/ пардон- пересмотрел ваши фото бп 2,1 -кода нет...тогда поиском по названию сайта много инфы как заказывать и тд.Я делал ваши платы 2,1 на мини 360 разводка там- отлично изготовили!!!

oleg707
06.02.2019, 22:48
https://jlcpcb.com/ прототипы.. Я думал вы там делали предидущие платы судя по кодам на них...Ну доставка отдельно само собой идет от скорости и цифра.P/S/ пардон- пересмотрел ваши фото бп 2,1 -кода нет...тогда поиском по названию сайта много инфы как заказывать и тд.Я делал ваши платы 2,1 на мини 360 разводка там- отлично изготовили!!!

Я в Китае на Али заказывал. На каком то из этих сайтов меня продинамили на 20$,
На АлиЭкспресс хоть спор открыть можно.
Попробую, пожалуй, ещё раз на jlcpcb.com

urikz
07.02.2019, 09:40
Я заказывал с доставкой сингапуром в Казахстан 5 плат(меньше нельзя и больше мне ненадо ) бп 2.1-пришло 6 плат за Merchandise Total: $2.00 Shipping Charge: $8.80 10,8 уе итог .Доп. изготовленная плата у них почти всегда бывает положена в посылку по отзывам о них от других покупателей.Код заказа над предохранителемhttp://i.piccy.info/i9/cb26d65eb818fca73dfbcae075334b77/1549518132/101555/1300155/1549517704304.jpg

oleg707
16.02.2019, 03:55
Появилось немного времени, подправил описание подключения блока к планшету. Надеюсь, будет полезно.
Свежая версия ( синхронизация с моим компьютером) ТУТ (https://mega.nz/#!t1RhRKrQ!OoYUqeV1ggEdNnKSz4LrNMwSrowYE7qecsI53n8 9MpY).

aleko2000
23.02.2019, 19:09
Вчера получил посылочку с БПmini; сегодня подключил планшет к блоку питания (пока что правда на столе и без узла hub-otg) - все работает отлично. Олегу респект!
*Посылка до Красноярска дошла довольно быстро - 16 дней.

oleg707
27.02.2019, 00:45
Вчера получил посылочку с БПmini; сегодня подключил планшет к блоку питания (пока что правда на столе и без узла hub-otg) - все работает отлично. Олегу респект!
*Посылка до Красноярска дошла довольно быстро - 16 дней.

:)
Удачи в установке.


Похоже случайно переименовал файл с описанием подключения - на всякий ссылка еще раз. https://mega.nz/#!pw5QFYIL!1cAs6Z3NnbaMPN3SNGJJwqdBspjy6SwvAhlcTw7 MO0E

holopovvv
02.03.2019, 10:45
Приветствую! Не могу загрузить ни одну прошивку в ардуину, происходит всегда одно и то же.
http://images.vfl.ru/ii/1551509107/5aa1558f/25603512.jpg

oleg707
02.03.2019, 11:52
Приветствую! Не могу загрузить ни одну прошивку в ардуину, происходит всегда одно и то же.
вопрос не по теме. Что за указатель скорости внизу справа? как сделать?

Ардуино IDE какая? Сборка, что я выкладывал? http://pccar.ru/showpost.php?p=406984&postcount=130
Попробуйте в корень диска С скопировать папку с ардуино IDE, и исключить русские буквы и пробелы из путей к файлам. на 5 компах норм шьется и компилируется.

holopovvv
02.03.2019, 12:20
Сборка ваша, исключать русские буквы пробовал, всё так же. Раньше то прошивал. Попробую заново скачать сборку. Прога называется DU meter.

holopovvv
02.03.2019, 12:38
Перекачал сборку и всё пошло. Планшет перестал засыпать, экран гаснет только по датчику холла, но система активна. Не знаете в чём может быть дело?

oleg707
02.03.2019, 13:02
Перекачал сборку и всё пошло. Планшет перестал засыпать, экран гаснет только по датчику холла, но система активна. Не знаете в чём может быть дело?

есть приложения мониторинга, на 4PDA видел, сейчас не припомню. Поставить и смотреть, что из софта не дает заснуть.

holopovvv
02.03.2019, 16:17
есть приложения мониторинга, на 4PDA видел, сейчас не припомню. Поставить и смотреть, что из софта не дает заснуть.

Всё, сам наладился, непонятно что ему надо было.

oleg707
02.03.2019, 16:53
Всё, сам наладился, непонятно что ему надо было.

:big: Главное спросить

holopovvv
02.03.2019, 17:57
:big: Главное спросить

Я месяца два назад заметил что он не уходит в сон, по трафику, за месяц примерно 10 гигабайт насасывал, а я всего лишь слушаю онлайн радио пару часов в день. Ну а сегодня я его снял с машины, и дома пытал весь день, ни в какую не хотел, потом контакт пого припаял на пого на планшете, ни чё не изменилось, перекинул обратно на usb, и, заработало. Как то так.

oleg707
03.03.2019, 00:36
Люди, посоветуйте вырианты синфазного дросселя для дополнительной фильтрации помех до 40000 Гц, желательно на Алиэкспресс и незадорого.

Upgreyd
03.03.2019, 15:56
Коллеги, есть вопрос:
CARPC на 13-ом нексусе, питание от Олега. USB звук подключен в ЮСБ фильтр земли. Все замечательно работает, но есть проблема. Когда бортовая сеть нагружена, включен обогрев сидений, свет, то при включении центрального замка (кнопочка которая закрывает все двери изнутри) звук может отвалиться (не всегда, но бывает).
Т. е. как я понимаю, есть кратковременная просадка по питанию. Есть ли какое решение, которое поможет от этого избавиться?

oleg707
03.03.2019, 16:40
Коллеги, есть вопрос:
CARPC на 13-ом нексусе, питание от Олега. USB звук подключен в ЮСБ фильтр земли. Все замечательно работает, но есть проблема. Когда бортовая сеть нагружена, включен обогрев сидений, свет, то при включении центрального замка (кнопочка которая закрывает все двери изнутри) звук может отвалиться (не всегда, но бывает).
Т. е. как я понимаю, есть кратковременная просадка по питанию. Есть ли какое решение, которое поможет от этого избавиться?

там скорее не просадка, а помеха. Укоротить ,если длинные, провода по ЮСБ, повесить керамических конденсаторов по питанию самой юсб карточки. Вообще такие вещи надо осциллографом смотреть. Может и через сам юсб кабель помеха пролезать.

Upgreyd
03.03.2019, 18:26
Да, кстати, очень вероятно проблема в проводе. От фильтра к хабу стоит штатный, который в комплекте шел. Закажу качественный, попробую. Спасибо.

Upgreyd
10.03.2019, 20:09
А может кто-то поделиться ссылкой на готовый фильтр по питанию с конденсатором? На али полно таких, но смущает, что в описании AC-DC, как оно в бортовой сети авто работает? Как подключить?

oleg707
10.03.2019, 20:50
А может кто-то поделиться ссылкой на готовый фильтр по питанию с конденсатором? На али полно таких, но смущает, что в описании AC-DC, как оно в бортовой сети авто работает? Как подключить?

Это (https://ru.aliexpress.com/item/100-OC9080-501-300R-5A/32905976570.html?spm=a2g0v.search0604.3.2.3d8c1696 waraiF&transAbTest=ae803_4&ws_ab_test=searchweb0_0%2Csearchweb201602_3_10065_ 10068_319_317_10696_10084_453_10083_454_10618_1030 4_10307_10820_10821_10301_537_536_10902_10843_1005 9_10884_10887_321_322_10103%2Csearchweb201603_70%2 CppcSwitch_0&algo_pvid=40a345c9-23ac-4ac7-8160-e66c41eb703b&algo_expid=40a345c9-23ac-4ac7-8160-e66c41eb703b-0), например, не устраивает?

Upgreyd
23.03.2019, 20:30
там скорее не просадка, а помеха. Укоротить ,если длинные, провода по ЮСБ, повесить керамических конденсаторов по питанию самой юсб карточки. Вообще такие вещи надо осциллографом смотреть. Может и через сам юсб кабель помеха пролезать.
Отписываюсь по результатам:
Замена проводов на качественные и максимально короткие, которые нашел, решило проблему полностью. Спасибо за совет!

oleg707
30.03.2019, 16:25
обновление не критическое. 99% изменений не заметят.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.


const byte ver = 39;// ( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 3.01.19.2117

// для 5mini, 5mini2.1, 5mini+2.2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
// 0 - 0 - берём значения из скетча, игнорируя память
// 1 - сохраняем в EEPROM
// 2 - берем значения из памяти eeprom игнорируя скетч
byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long LONG_koefficient_delitelia_ACC =0;
unsigned long LONG_koefficient_delitelia_AKB =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру
{
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long LONG_koefficient_delitelia_ACC ;
unsigned long LONG_koefficient_delitelia_AKB ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
const byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
/*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
*///13
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024
int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX
static int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX
float Uacc_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
float Uakb_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего


//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

static byte PINrawACC = A0; // замер для 5й версии
static byte PINrawAKB = A1; // замер для 5й версии
static byte PINkalibrovki = A2; // замер для 5й версии

//static byte PINrawACC = A7; // замер для 7й версии
//static byte PINrawAKB = A8; // замер для 7й версии
//static byte PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
static byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
static byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС
byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
/*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
*///13
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}

void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{

// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO // управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
// if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
//if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
// if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.

}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки при первой подаче питания. выполняются 1 раз.
{
Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать
if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча.
RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM
OBRABOTKA_KALIBROWKI();
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; // настройки порта D
DDRB = 0b00111110; // настройки порта B
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//vykluchic_vse();
/* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
*/
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки
/*//13
display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
*///13
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}

void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/10000) + '0'; //0 знач
text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/100)%10) + '0';// второе значение __0
text[3] = ((num/10)%10) + '0'; // третее значение ___
text[4] = (num%10) + '0'; // 4е значение ___
}

void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void OBRABOTKA_KALIBROWKI()
{//void OBRABOTKA_KALIBROWKI()

// проверка на прописанную в памяти калибровку
if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение.
{
if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295)
{
sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]);
sprintf(strokaII, "NE PROPISANA !!!") ;
INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине
displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
delay (1000); // задержка чтобы успеть прочитать
}
}
if (LONG_koefficient_delitelia_ACC == 4294967295)
{
LONG_koefficient_delitelia_ACC = 15364;
}
if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}

}//void OBRABOTKA_KALIBROWKI()


void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()
kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ


//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM



if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
LONG_koefficient_delitelia_ACC,
LONG_koefficient_delitelia_AKB,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);

LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;

}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока


// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharII(kalibrovkaNOW, &strokaI[8]); // вывод счетчика РЕЖИМА калибровки

sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);


FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

if (razreszenie_raboty_I_dva_C_sziny == 1) {displayDataToDISPLAY();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

/*void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}
// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

}//void analogReadU
*/
void READ_SREDNIEJE_U()
{ //void READ_SREDNIEJE_U
Uacc = analogRead(PINrawACC);
Uakb = analogRead(PINrawAKB);

Uacc_TMP = (Uacc_TMP + Uacc );
Uakb_TMP = (Uakb_TMP + Uakb );
cykly_usrednenij_U ++;

if (cykly_usrednenij_U == ilosc_usrednenij)
{
U_acc_real = Uacc_TMP*(LONG_koefficient_delitelia_ACC+1)/1000000.0/ilosc_usrednenij;
U_akb_real = Uakb_TMP*(LONG_koefficient_delitelia_AKB+1)/1000000.0/ilosc_usrednenij;

if (kalibrovkaACC<255 && kalibrovkaAKB<255) //если калибровка старого типа, вычисляем напряжение по старому, если мы не в режиме калибровки.
{
U_acc_real = (Uacc_TMP * (1410.0+kalibrovkaACC+0.05)/100000.0/ilosc_usrednenij);
U_akb_real = (Uakb_TMP * (1410.0+kalibrovkaAKB+0.05)/100000.0/ilosc_usrednenij );
}
cykly_usrednenij_U = 0;
Uacc_TMP = 0; // обнуляем для начала нового отсчета
Uakb_TMP = 0;
}

} //void READ_SREDNIEJE_U

void OBRABOTKA_REJIMA_OTLADKI()
{//OBRABOTKA_REJIMA_OTLADKI
if (OTLADKA >= 1)
{ //if (OTLADKA >= 1)
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - если напряжение ACC > 6В то считаем ACC=14,5В АКБ считаем всегда AKB=14,5В
// 3 - напряжение ACC всегда считаем ACC=14,5В напряжение АКБ всегда считаем AKB=14,5В
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (U_akb_real > 6) {U_akb_real = 14.50;} // принимаем напряжение аккумалятора автомобиля за 14,50В (если реальное напряжение AKB > 6В)
if (OTLADKA >= 2 )
{
U_akb_real = 14.50;
if (OTLADKA >= 3 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 2 )
}




// принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
}//if (OTLADKA >= 1) //конец режима отладки.
}//OBRABOTKA_REJIMA_OTLADKI

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
vykluchic_vse(); // вызвали функцию выключения всех выходов и напряжений с блока питания.
delay (500); // для зарядки конденсаторов после снятия нагрузки
//тут позже можно опционально добавить усреднение Uacc Uakb
//вычисляем новое значение калибровки
brac_nastrojki_iz_EEPROM =2; // включили режим считывания настроек из энергонезависимой памяти
RABOTA_z_EEPROM (); // считали значения пользователя из энергонезависимой памяти.
LONG_koefficient_delitelia_ACC = 12000000/Uacc;
LONG_koefficient_delitelia_AKB = 12000000/Uakb;
kalibrovkaNOW ++;
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW >= 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,255);
EEPROM.update(1,255);

brac_nastrojki_iz_EEPROM = 1; // включили режим записи настроек в энергонезависимую память
RABOTA_z_EEPROM (); // вписали значения пользователя с калибровкой в энергонезависимую память.

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //

delay (60000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
} // конец как только включили зажигание ( при любом напряжении батареи)


if (flagACC ==1 )
{// если flagACC == 1
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------

if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if (razreszenie_raboty_I_dva_C_sziny == 0) //Не даём заснуть при активном режиме
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------

if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop


READ_SREDNIEJE_U(); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(ilosc_usrednenij)раз.

if ( (millis() < 120000) )
{
if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0) // после 120с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ
{
if ( (millis() < 120000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();}
}
}

OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ

// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)



/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}

/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[6];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

if (kalibrovkaNOW <= 5) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами а преходим в функцию выключения всех выходов.
{UPRAVLENIE_PINAMI();
}else {vykluchic_vse(); }

}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _

______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напряжение батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик постоянно обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.
m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.

собственное потребление блока по 12 вольтам, без планшета (для БП5mini)

- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

oleg707
03.04.2019, 00:11
Знаю, что некоторые используют дополнительные каналы +12В (REG) для подключения вентилятора.
Может добавить в блок питания датчик температуры?
Прошивку чуть дописать и будет БП знать свою температуру. Потом с этим значением что угодно можно делать.
Как вам?

urikz
03.04.2019, 10:27
Может добавить в блок питания датчик температуры? Да!!! Думаю это лишним не будет, если есть такая возможность...

oleg707
04.04.2019, 00:20
Может добавить в блок питания датчик температуры? Да!!! Думаю это лишним не будет, если есть такая возможность...

Возможность то есть, необходимости не было :)
Заказал комплект терморезисторов, посмотрю, как придут, которые из них более подходящие.

maksim
08.04.2019, 11:56
Уважаемый Олег, подскажите, для питания одноплатника (OrangePi, NanoPi и так далее) можно ваш БП использовать?
Еще, задавал вам где то вопросы касаемо приобретения БП для тестов, даже получал ответы, но найти не могу... можете в личку написать?

oleg707
10.04.2019, 00:37
Уважаемый Олег, подскажите, для питания одноплатника (OrangePi, NanoPi и так далее) можно ваш БП использовать?
Еще, задавал вам где то вопросы касаемо приобретения БП для тестов, даже получал ответы, но найти не могу... можете в личку написать?

Напиши в личку, или в Вайбер- Вотсапп. По поводу запитки - можно питать все, что не превышает в среднем 2 Ампера на канал.
Можно вместо dc-dc mp1584 ставить более мощные дс-дс, я даже разработал плату на 5 ампер, потому как 2 слойка, но никак не доберусь её спаять и протестировать, времени совсем нету.

А тут ещё 3д принтер прикупил, вникаю. Так что не знаю, хватит ли сил на следующее поколение БП. Толкает только то, что машину надо менять, поэтому хочу новый блок.

oleg707
21.04.2019, 20:19
Поскольку времени совсем нет, просто выложу обновленную (2.3) версию БП.
Фото потом сделаю. Из кардинальных отличий - добавлен интеллектуальный ключ для управления вторым DC-DC. Это позволило не припаивать дополнительный проводок на дсдс для управления вторым каналом, что упростило сборку.
ПРОШИВКА полностью совместима с версиями 2,2, 2,1, 2,0.

Блок прошел обкатку и работает так же хорошо, как и его предшествнники.
Так же возможно изменение своих настроек (напряжений, таймингов, логки поведения) при необходимости.

oleg707
27.04.2019, 16:35
Новая версия описания подключения блока питания (https://mega.nz/#F!goYR1azC!Ns_5CE4KBOb3QHjm6qyU5Q). Нечаянно стер старую версию, поэтому даю ссылку сразу на папку.

murano
05.05.2019, 21:18
Есть несколько вопросов по программе. Включение планшета происходит по кнопке. Переменная HALL_as_power_Switch = 1 В исходном тексте в процедуре obrabotka_ACC_OFF() стоит строка if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;} С переменной HALL_as_power_Switch выключение экрана не происходит. Работает только если ее заменить на переменную vremia_uderjanija_najatoj_knopki_POWER
Но после выключения зажигания если долго не включать зажигание по приходу в авто экран почему то иногда бывает уже включен. Иногда он выключен но с зажиганием сразу включается и через некоторое время выключается. В первом случае он выключается тоже после включения зажигания.

oleg707
05.05.2019, 22:31
Есть несколько вопросов по программе. Включение планшета происходит по кнопке. Переменная HALL_as_power_Switch = 1 В исходном тексте в процедуре obrabotka_ACC_OFF() стоит строка if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;} С переменной HALL_as_power_Switch выключение экрана не происходит. Работает только если ее заменить на переменную vremia_uderjanija_najatoj_knopki_POWER
Но после выключения зажигания если долго не включать зажигание по приходу в авто экран почему то иногда бывает уже включен. Иногда он выключен но с зажиганием сразу включается и через некоторое время выключается. В первом случае он выключается тоже после включения зажигания.

Какая версия прошивки?
Предлагаю разделить это на 2 этапа.
1 - посмотрю код, погоняю на железном эмуляторе планшета ( в машине у меня подключение по холлу, поэтому вживую не смогу протестировать,)
2 - если отключить управление кнопкой с планшета, и приделать для тестов физическую кнопку будет ли такое

Но после выключения зажигания если долго не включать зажигание по приходу в авто экран почему то иногда бывает уже включен. Иногда он выключен но с зажиганием сразу включается и через некоторое время выключается. В первом случае он выключается тоже после включения зажигания. поведение?

oleg707
06.05.2019, 00:13
посмотрел код, да вы правы, в функции выключения кнопкой питания кнопка "нажималась" на 1мс ( по факту немного больше, цикл плюс вычисления все таки,но сути не меняет) .
Поправил:

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) { SLEEP = 0;}
}//if (HALL_as_power_Switch == 1)


По факту вы правильно исправили. Поэтому попрошу проверить, отключив управление кнопкой с планшета, и приделав для тестов физическую кнопку.

Исправленную прошивку выкладываю в текстовом виде и в сообщении ниже, чтобы не потералась

const byte ver = 40;// ( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 3.01.19.2117

// для 5mini, 5mini2.1, 5mini+2.2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
// 0 - 0 - берём значения из скетча, игнорируя память
// 1 - сохраняем в EEPROM
// 2 - берем значения из памяти eeprom игнорируя скетч
byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long LONG_koefficient_delitelia_ACC =0;
unsigned long LONG_koefficient_delitelia_AKB =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру
{
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long LONG_koefficient_delitelia_ACC ;
unsigned long LONG_koefficient_delitelia_AKB ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
const byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
/*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
*///13
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024
int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX
static int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX
float Uacc_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
float Uakb_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего


//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)

//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа

//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

static byte PINrawACC = A0; // замер для 5й версии
static byte PINrawAKB = A1; // замер для 5й версии
static byte PINkalibrovki = A2; // замер для 5й версии

//static byte PINrawACC = A7; // замер для 7й версии
//static byte PINrawAKB = A8; // замер для 7й версии
//static byte PINkalibrovki = A3; // замер для 7й версии

//пины состояния ITS
static byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
static byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/

/*логические переменные, используемые в коде*/

byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС
byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
/*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
*///13
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}

void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{

// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги

/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO // управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)


// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD

digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)


// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
// if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
//if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
// if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.

}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки при первой подаче питания. выполняются 1 раз.
{
Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать
if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча.
RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM
OBRABOTKA_KALIBROWKI();
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; // настройки порта D
DDRB = 0b00111110; // настройки порта B
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//vykluchic_vse();
/* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
*/
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);

//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);


//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки
/*//13
display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
*///13
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}

void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/10000) + '0'; //0 знач
text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/100)%10) + '0';// второе значение __0
text[3] = ((num/10)%10) + '0'; // третее значение ___
text[4] = (num%10) + '0'; // 4е значение ___
}

void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void OBRABOTKA_KALIBROWKI()
{//void OBRABOTKA_KALIBROWKI()

// проверка на прописанную в памяти калибровку
if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение.
{
if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295)
{
sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]);
sprintf(strokaII, "NE PROPISANA !!!") ;
INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине
displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
delay (1000); // задержка чтобы успеть прочитать
}
}
if (LONG_koefficient_delitelia_ACC == 4294967295)
{
LONG_koefficient_delitelia_ACC = 15364;
}
if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}

}//void OBRABOTKA_KALIBROWKI()


void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()
kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ


//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM



if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
LONG_koefficient_delitelia_ACC,
LONG_koefficient_delitelia_AKB,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_U SB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);

LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;

}//void RABOTA_z_EEPROM ()

void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока


// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharII(kalibrovkaNOW, &strokaI[8]); // вывод счетчика РЕЖИМА калибровки

sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);


FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

if (razreszenie_raboty_I_dva_C_sziny == 1) {displayDataToDISPLAY();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

/*void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}
// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

}//void analogReadU
*/
void READ_SREDNIEJE_U()
{ //void READ_SREDNIEJE_U
Uacc = analogRead(PINrawACC);
Uakb = analogRead(PINrawAKB);

Uacc_TMP = (Uacc_TMP + Uacc );
Uakb_TMP = (Uakb_TMP + Uakb );
cykly_usrednenij_U ++;

if (cykly_usrednenij_U == ilosc_usrednenij)
{
U_acc_real = Uacc_TMP*(LONG_koefficient_delitelia_ACC+1)/1000000.0/ilosc_usrednenij;
U_akb_real = Uakb_TMP*(LONG_koefficient_delitelia_AKB+1)/1000000.0/ilosc_usrednenij;

if (kalibrovkaACC<255 && kalibrovkaAKB<255) //если калибровка старого типа, вычисляем напряжение по старому, если мы не в режиме калибровки.
{
U_acc_real = (Uacc_TMP * (1410.0+kalibrovkaACC+0.05)/100000.0/ilosc_usrednenij);
U_akb_real = (Uakb_TMP * (1410.0+kalibrovkaAKB+0.05)/100000.0/ilosc_usrednenij );
}
cykly_usrednenij_U = 0;
Uacc_TMP = 0; // обнуляем для начала нового отсчета
Uakb_TMP = 0;
}

} //void READ_SREDNIEJE_U

void OBRABOTKA_REJIMA_OTLADKI()
{//OBRABOTKA_REJIMA_OTLADKI
if (OTLADKA >= 1)
{ //if (OTLADKA >= 1)
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - если напряжение ACC > 6В то считаем ACC=14,5В АКБ считаем всегда AKB=14,5В
// 3 - напряжение ACC всегда считаем ACC=14,5В напряжение АКБ всегда считаем AKB=14,5В
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (U_akb_real > 6) {U_akb_real = 14.50;} // принимаем напряжение аккумалятора автомобиля за 14,50В (если реальное напряжение AKB > 6В)
if (OTLADKA >= 2 )
{
U_akb_real = 14.50;
if (OTLADKA >= 3 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 2 )
}




// принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
}//if (OTLADKA >= 1) //конец режима отладки.
}//OBRABOTKA_REJIMA_OTLADKI

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
vykluchic_vse(); // вызвали функцию выключения всех выходов и напряжений с блока питания.
delay (500); // для зарядки конденсаторов после снятия нагрузки
//тут позже можно опционально добавить усреднение Uacc Uakb
//вычисляем новое значение калибровки
brac_nastrojki_iz_EEPROM =2; // включили режим считывания настроек из энергонезависимой памяти
RABOTA_z_EEPROM (); // считали значения пользователя из энергонезависимой памяти.
LONG_koefficient_delitelia_ACC = 12000000/Uacc;
LONG_koefficient_delitelia_AKB = 12000000/Uakb;
kalibrovkaNOW ++;
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW >= 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,255);
EEPROM.update(1,255);

brac_nastrojki_iz_EEPROM = 1; // включили режим записи настроек в энергонезависимую память
RABOTA_z_EEPROM (); // вписали значения пользователя с калибровкой в энергонезависимую память.

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //

delay (60000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
} // конец как только включили зажигание ( при любом напряжении батареи)


if (flagACC ==1 )
{// если flagACC == 1
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*"нажимаем" кнопку питания*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------

if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) { SLEEP = 0;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_POGO_or_USB = 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !

}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if (razreszenie_raboty_I_dva_C_sziny == 0) //Не даём заснуть при активном режиме
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------

if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop


READ_SREDNIEJE_U(); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(ilosc_usrednenij)раз.

if ( (millis() < 120000) )
{
if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0) // после 120с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ
{
if ( (millis() < 120000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();}
}
}

OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ

// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)



/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}

/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[6];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

if (kalibrovkaNOW <= 5) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами а преходим в функцию выключения всех выходов.
{UPRAVLENIE_PINAMI();
}else {vykluchic_vse(); }

}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _

______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напряжение батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик постоянно обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.
m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.

собственное потребление блока по 12 вольтам, без планшета (для БП5mini)

- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

oleg707
06.05.2019, 00:23
m40 - исправление некорректного поведения "кнопки" при выключении зажигания (когда выходы на датчик холла используются в режиме имитации кнопки питания)

51149

murano
06.05.2019, 21:27
Подозреваю проблема кроется в циклическом выполнении процедур void obrabotka_ACC_OFF() и void obrabotka_ACC_ON()
После того, как добавил переменную bool screen_on = false, в которой хранится состояние экрана (on - off), и сделал изменения в указанных выше процедурах, обозначенная ранее ситуация исчезла:
void obrabotka_ACC_ON()

...
if (HALL_as_power_Switch == 1 && screen_on == false) {
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) {
SLEEP = 0;
screen_on = true;
}
}
...

void obrabotka_ACC_OFF()

...
if (HALL_as_power_Switch == 1 && screen_on == true) {
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) {
SLEEP = 0;
screen_on = false;
}
}
...
Откатал сегодня день, проблем пока не было.

oleg707
06.05.2019, 22:28
Подозреваю проблема кроется в циклическом выполнении процедур void obrabotka_ACC_OFF() и void obrabotka_ACC_ON()
После того, как добавил переменную bool screen_on = false, в которой хранится состояние экрана (on - off), и сделал изменения в указанных выше процедурах, обозначенная ранее ситуация исчезла:
void obrabotka_ACC_ON()

...
if (HALL_as_power_Switch == 1 && screen_on == false) {
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) {
SLEEP = 0;
screen_on = true;
}
}
...

void obrabotka_ACC_OFF()

...
if (HALL_as_power_Switch == 1 && screen_on == true) {
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) {
SLEEP = 0;
screen_on = false;
}
}
...
Откатал сегодня день, проблем пока не было.

вообще странно, поскольку оно то крутится в цикле, но
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) { SLEEP = 0;}
по циклу мы сначала даем команду на включение лог. нуля, "нажимая" кнопку, а потом через время (vremia_uderjanija_najatoj_knopki_POWER) начинаем подавать 1, "размыкая" кнопку.
В цикле мы продолжаем давать 1 на порт процессора, это держит твердотельное реле открытым всё время.

Я прогнал m40 прошивку на стенде, при включении зажигания коротко замыкает кнопку и дальше просто ожидает, и вЫключении зажигания коротко замыкает кнопку и дальше просто ожидает.
Понаблюдаем.

dima_dima_dima
20.05.2019, 01:20
Наконец то нашлось время рассказать о своей поделке, заодно и немного оживлю тему.
Достаточно давно получил от Олега посылку с платами и детальками, которых у меняя не было (частично деталюшки были, так как прошлую версию, еще на КИВ делал полностью сам) не так давно собрал все воедино, вот, предлагаю посмотртеть что получилось в итоге.
Кстати о предыдущей версии, она успешно откатала в машине почти год, жутко донимая меня писком на грани слышимости, пищал сам КИВ одним из каналов (по этому он был со временем облеплен виброизоляцией и писк почти перестал меня доставать) а потом планшет начал ребутаться, и в определенный момент не включился- так я и ездил, подзабив, хотя по факту оказалось что от нагревов и охлаждений лопнула одна из ножек, которые у КИС\КИВ очень хрупкие и которые обязательно надо менять.
Так вот, в сборке и настройке нового блока питания никаких проблем не было, все заработало с первого раза, на этом я не буду заострять внимание, а остановлюсь на моем решении в плане хардвары планшета и собственно самого , может кому то пригодится.
Со временем доберусь до компа на котором лежат все печатки и закину все в ту же самую папку, вдруг кто захочет повторить то, как все сделано у меня.
Ссылка на гуглпапку:
Nexus 7 Power Supply (https://drive.google.com/drive/folders/1U69i7t5SrcyMAG1K79F0nQ6k4y-tBabI?usp=sharing)
Там же лежат фото первой версии, если вдруг будет интересно.
Как видно из фото я сделал следущее:
1) Убрал редонатор нижнего динамика и на это место ввытравил плату, этуу плату уже соединил МГТФ со всеми нужными мне точками планшета, после чего уже без риска оторвать что либо или перегреть паялся именно к этой плате.
2) Вытравил платку с разъемом DB25(?) и соединил с платой внутри планшета
3) Вытравил платку с инжектором питания и навесил на разъем
4) Вытравил плату расширений для блока питания, там у меня размещены и RCA с выхода наушников, и пины на хардварныые кнопки плашета, и отгшный выход юсб, вход +12в Земля и Зажигание и соответственно сам хвост на планшет. Плата эта через стоечки прикручена к БП
Так же сделал подставку на которой разместил все сразу и БП бутерброд и звуковую карту и хаб.
Надеюсь по фото все будет понятно, так как рассказывать особо не умею, но если будут какие то вопросы с удовольствием на них отвечу)

oleg707
20.05.2019, 23:19
Наконец то нашлось время рассказать о своей поделке
......

Зачет :yes2:

заодно и немного оживлю тему
Тема вообще живая (по крайней мере с моей стороны, эксперементирую тут с внедрением датчика температуры на эксперементальном же железе ( полностью совместимо) :rolleyes2:
На новшества времени мало, а старое просто каждый день работает в машине, потому ничего нового и не пишется:secret:


Кстати, если есть желающие, могу скинуть тестовую прошивку, для добавления датчика температуры нужно припаять резистор 100К от +5 ардуины до A3 и припаять стандартный датчик температуры ( NTC 100K на 25 градусов, B = 3950 ) один пин на A3, другой на массу.
Формула вычисления там не совсем простая, благо легко ищется.

float tr = 1023.0 / (NTC_TMP/ilosc_usrednenij) - 1;
tr = SERIAL_RT / tr;

NTC_real = tr / THERMISTOR_R; // (R/Ro)
NTC_real = log(NTC_real); // ln(R/Ro)
NTC_real /= B; // 1/B * ln(R/Ro)
NTC_real += 1.0 / (NOMINAL_T + 273.15); // + (1/To)
NTC_real = 1.0 / NTC_real; // Invert
NTC_real -= 273.15; // переводим в цельсии из кельвинов

Кроме этого критических изменений в прошивке нет, поэтому и не выкладываю:blush:

Ivan636
21.05.2019, 11:23
очень понравилась реализация, еще бы прикрепили печатные платки вообще бы цены не было.

dima_dima_dima
21.05.2019, 13:15
очень понравилась реализация, еще бы прикрепили печатные платки вообще бы цены не было.
Постараюсь добраться до компуктера где все лежит на выходных, скину туда же в гуглпапку, как скину отпишусь)

oleg707
22.05.2019, 21:53
Кому нужен был датчик температуры, можете протестировать промежуточный вариант кода.

Для добавления датчика температуры нужно припаять резистор 100К от +5В ардуины до пина A3 и припаять стандартный датчик температуры ( NTC 100K на 25 градусов, B = 3950 ), один пин на A3, другой на массу.
http://robotclass.ru/wp-content/uploads/2017/05/ardu-thermistor_%D1%81%D1%85%D0%B5%D0%BC%D0%B0.png
Примерно так, только на пин А3
Чтобы вычислить значение температуры используем упрощенную формулу Стейнхарта — Харта:
http://robotclass.ru/wp-content/uploads/2017/05/temperature_bequastion.png

const byte ver = 43;// ( чем больше цифра, тем новее)
const byte TipBlokaPitania = 255; // 133 - BP5.PRO; 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 21.05.19.1758

// для BP5.PRO, 5mini, 5mini2.1, 5mini+2.2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing


//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И


static byte vkluczic_wywod_dannyh_w_COM_port = 0; // 1- для включения вывода в ком порт для отладки, 0- для вЫключения вывода в ком порт для отладки
//if (vkluczic_wywod_dannyh_w_COM_port == 1){// если включена опция вывода в ком порт для отладки
// тут будем выполнять команды ( как правило вывода в COM порт)
//}


const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В

byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
// 0 - 0 - берём значения из скетча, игнорируя память
// 1 - сохраняем в EEPROM
// 2 - берем значения из памяти eeprom игнорируя скетч
static byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, тогда поставить 0.
static byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
static byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
static byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________

/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!

unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)

unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.

//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд

unsigned long LONG_koefficient_delitelia_ACC =0;
unsigned long LONG_koefficient_delitelia_AKB =0;
unsigned long zaderzka_pered_VKL_izikapa =1000;
unsigned long zaderzka_pered_VYKL_izikapa =5000;
unsigned long rezerv12 =0;
unsigned long rezerv13 =0;
unsigned long rezerv14 =0;
unsigned long rezerv15 =0;
unsigned long rezerv16 =0;
unsigned long rezerv17 =0;
unsigned long rezerv18 =0;
unsigned long rezerv19 =0;
unsigned long rezerv20 =0;
float rezerv5 =00.00;
float rezerv6 =00.00;
float rezerv7 =00.00;
//конец настроек таймингов.________________________________________ __________________________________________________


// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И

// настройки датчика температуры http://robotclass.ru/tutorials/arduino-thermistor-100k/
const long B = 3950; // B-коэффициент
#define SERIAL_RT 100000 // сопротивление последовательного резистора подтяжки, 100 кОм
#define THERMISTOR_R 100000 // номинальное сопротивления термистора, 100 кОм
#define NOMINAL_T 25 // номинальная температура (при которой TR = 100 кОм)
// конец настроек датчика температуры

const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром

struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру
{
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long LONG_koefficient_delitelia_ACC ;
unsigned long LONG_koefficient_delitelia_AKB ;
unsigned long zaderzka_pered_VKL_izikapa ;
unsigned long zaderzka_pered_VYKL_izikapa ;
unsigned long rezerv12 ;
unsigned long rezerv13 ;
unsigned long rezerv14 ;
unsigned long rezerv15 ;
unsigned long rezerv16 ;
unsigned long rezerv17 ;
unsigned long rezerv18 ;
unsigned long rezerv19 ;
unsigned long rezerv20 ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};

//************************************************** ************************************************** ***********************************************
// Массив режимов работы светодиода
const byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//************************************************** ************************************************** ***********************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея 1602
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
/*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
*///13
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
float NTC_real = 7.0; // реальная температура блока, вычесленная через датчик на порту A3 http://arduino-diy.com/arduino-thermistor или http://robotclass.ru/tutorials/arduino-thermistor-100k/

int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024
int NTC = 0; // данные с делителя датчика температуры (порт A3) //13
int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX
const int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX
float Uacc_TMP = 0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
float Uakb_TMP = 0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
unsigned long NTC_TMP=0; // для хранения временного значения замеров (int) температуры, нужно для вычисления среднего


//PORTB
const byte DRLED_pin = 8; //PB0 номер пина, управляющего выходом +12 LED
const byte SAMOZAPITKA_Pin = 9; //PB1 номер пина самозапитки блока
const byte OTG_Pin = 10; //PB2 номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; //PB3 номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; //PB4 номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла) (опционально управление кнопкой питания)
const byte LED_Pin = 13; //PB5 номер пина встроенного светодиода индикации


//PORTD
const byte FIVE_Volt_OUT_na_USB_or_POGO_Pin = 2; //PD2 номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REGISTRATOR_Pin = 4; //PD4 номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte PlanshBAT_Pin = 6; //PD6 номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REM_Pin = 7; //PD7 номер пина, управляющего выходом +12 REM

//PORTC
const byte PINrawACC = A0; //PC0 ADC0 вход напряжения с делителя ACC
const byte PINrawAKB = A1; //PC1 ADC1 вход напряжения с делителя AKB
const byte PINkalibrovki = A2; //PC2 ADC2 для калибровки БП
const byte NTC_pin_raw = A3; //PC3 ADC3 вход с делителя NTC датчика температуры
//A4 подключено на I2C PC4
//A5 подключено на I2C PC5

// несортированные порты
//A6 не подключено (в воздухе)
//A7 не подключено (в воздухе)
const byte EasyCAP_pin = 5; // номер пина, управляющего выходом питания +5 на изикап
const byte REAR_GEAR_in_pin = 3; // номер пина для ВХОДА напряжения с делителя задней передачи.


//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean DRLED = 0; // управление +12В на выходе "LED" БП.
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит


uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean FIVE_Volt_OUT_na_USB_or_POGO = 0; //byte FIVE_Volt_OUT_na_USB_or_POGOpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM


// uint8_t PORTCregistr = 0; // 8-битная переменная PORTCregistr
// не нужно, все линии на порту С - входы
boolean EasyCAP = 0; // управление дсдс изикапа 0 - выкл. 1- вкл

/*логические переменные, используемые в коде*/

byte flagACC = 0; //признак включенного зажигания
byte flagAKB = 0; // признак заряженной батареи
byte flagREM = 0; // признак включенного выхода на усилитель звука (REM) 0 1 2
byte flagREAR_GEAR = 0; // признак включенной ли задней передачи. 0 выключена, 1 включена
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС
byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.







static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseTime_rear = millis(); // вспомогательный таймер для распознавание признака задней передачи
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого выключается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
/*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
*///13
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
if (TipBlokaPitania == 255)
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_USB_or_POGO = 0; //byte FIVE_Volt_OUT_na_USB_or_POGOpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
}
if (TipBlokaPitania == 133)
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG

PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_USB_or_POGO = 0; //byte FIVE_Volt_OUT_na_USB_or_POGOpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM

EasyCAP =0; //дсдс изикапа
DRLED = 0; // выход +12В LED
}

UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}

void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{
if (TipBlokaPitania == 255)
{
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)
digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_USB_or_POGO_Pin, FIVE_Volt_OUT_na_USB_or_POGO); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)

}
if (TipBlokaPitania == 133)
{
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, HUB); // управление питанием хаба
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)
digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_USB_or_POGO_Pin, FIVE_Volt_OUT_na_USB_or_POGO); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)
digitalWrite(EasyCAP_pin, EasyCAP); //управление выходом (+12) для питания дсдс изикапа
digitalWrite(DRLED_pin, DRLED); // управление +12В на выходе "LED" БП.



}

}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~



void setup() //настройки при первой подаче питания. выполняются 1 раз.
{
if (vkluczic_wywod_dannyh_w_COM_port==1){// если включена опция вывода в ком порт для отладки
Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать
}

if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча.
RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM
OBRABOTKA_KALIBROWKI();
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//правильная но сложная настройка портов атмеги.
// DDRD = 0b11010100; // настройки порта D
// DDRB = 0b00111110; // настройки порта B
//правильная но сложная настройка портов атмеги.

//простая для восприятия и смены платформы настройка портов ардуино.
//PORTB
pinMode(SAMOZAPITKA_Pin, OUTPUT);
pinMode(LED_Pin, OUTPUT);
pinMode(OTG_Pin, OUTPUT);
pinMode(HUB_Pin, OUTPUT);
pinMode(SLEEP_Pin, OUTPUT);

//PORTD
pinMode(PlanshBAT_Pin, OUTPUT);
pinMode(REGISTRATOR_Pin, OUTPUT);
pinMode(FIVE_Volt_OUT_na_USB_or_POGO_Pin, OUTPUT);
pinMode(REM_Pin, OUTPUT);

// несортированные порты
pinMode (PINrawACC, INPUT);
pinMode (PINrawAKB, INPUT);
pinMode (PINkalibrovki, INPUT); // пин калибровки
pinMode (NTC_pin_raw, INPUT);

// активируем у процессора внутренние резисторы подтяжки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки

// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

void display_BUFER_to_real_DISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void display_BUFER_to_real_DISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

if (vkluczic_wywod_dannyh_w_COM_port==1){// если включена опция вывода в ком порт для отладки
Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
}
lcd.setCursor(0, 0);
lcd.print(strokaI);

lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);



//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки
/*//13
display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
*///13
//Вывод строк окончен.__________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ____________________________________

}//void display_BUFER_to_real_DISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___

}

void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___

}


void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}

void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}

void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/10000) + '0'; //0 знач
text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/100)%10) + '0';// второе значение __0
text[3] = ((num/10)%10) + '0'; // третее значение ___
text[4] = (num%10) + '0'; // 4е значение ___
}

void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{

int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}

void OBRABOTKA_KALIBROWKI()
{//void OBRABOTKA_KALIBROWKI()

// проверка на прописанную в памяти калибровку
if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение.
{
if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295)
{
sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]);
sprintf(strokaII, "NE PROPISANA !!!") ;
INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине
display_BUFER_to_real_DISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
delay (1500); // задержка чтобы успеть прочитать
}
}
if (LONG_koefficient_delitelia_ACC == 4294967295)
{
LONG_koefficient_delitelia_ACC = 15364;
}
if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}

}//void OBRABOTKA_KALIBROWKI()


void RABOTA_z_EEPROM ()

{//void RABOTA_z_EEPROM ()
kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ


//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM



if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
LONG_koefficient_delitelia_ACC,
LONG_koefficient_delitelia_AKB,
zaderzka_pered_VKL_izikapa,
zaderzka_pered_VYKL_izikapa,
rezerv12,
rezerv13,
rezerv14,
rezerv15,
rezerv16,
rezerv17,
rezerv18,
rezerv19,
rezerv20,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v _eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)

if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya ;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_AC C;
FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_USB_or_PO GO_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_USB_or_PO GO_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_ vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_ knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl _ACC;
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;
zaderzka_pered_VKL_izikapa = znachenija_polzovatelia.zaderzka_pered_VKL_izikapa ;
zaderzka_pered_VYKL_izikapa = znachenija_polzovatelia.zaderzka_pered_VYKL_izikap a;
rezerv12 = znachenija_polzovatelia.rezerv12;
rezerv13 = znachenija_polzovatelia.rezerv13;
rezerv14 = znachenija_polzovatelia.rezerv14;
rezerv15 = znachenija_polzovatelia.rezerv15;
rezerv16 = znachenija_polzovatelia.rezerv16;
rezerv17 = znachenija_polzovatelia.rezerv17;
rezerv18 = znachenija_polzovatelia.rezerv18;
rezerv19 = znachenija_polzovatelia.rezerv19;
rezerv20 = znachenija_polzovatelia.rezerv20;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);

LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia _ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia _AKB;

}//void RABOTA_z_EEPROM ()

void print_in_DISPLAY_BUFER() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИ РУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ___________________________________________ _________________

H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты

if (flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
// в 256 строке выключение подсветки LCD дисплея



//пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_______________________________________________ __________________________________________________ __________________________________________________ __________________
sprintf(strokaI," ") ;
/* IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00


// закомментирован вывод часов:минут работы БП
*/
if (NTC_real>=0){strokaI[0]= 't';} // выводим + температуры
if (NTC_real<0) {strokaI[0]= '-';} //выводим минус температуры
FloatToCharIIIII (abs(NTC_real), &strokaI[1]); // выводим саму температуру 27.77 модуль температуры abs(NTC_real)
if (flagREAR_GEAR==1){strokaI[0]= 'r';} // tckb dblbv drk.xtybt pflytq
if (EasyCAP==1){strokaI[0]= 'R';}
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

//обработка 2й строки____________________________________________ __________________________________________________ __________________________________________________ ______________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)


// _______________________________Первые 30с после вкл ACC выводим версию блока.____________________________________________ __________________________________________________ __________________________________________________ ____
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока


// __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ _____________________________



//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_USB_or_POGO + '0';// вывод флага FIVE_Volt_OUT_na_USB_or_POGO (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки __________________________________________________ __________________________________________________ __________________________________________________ ________________________

if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharII(kalibrovkaNOW, &strokaI[8]); // вывод счетчика РЕЖИМА калибровки

sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);


FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ

}

//Вывод строк.____________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ __________________________________

if (razreszenie_raboty_I_dva_C_sziny == 1) {display_BUFER_to_real_DISPLAY();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>




/* так выглядит индикация на дисплее

================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ


*/
}

/******************************************конец индикации светодиодом и вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/


//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================

/*void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);

if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}
// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;

}//void analogReadU
*/
void vyczislienie_i_OBRABOTKA_realnoj_tiemperatury()
{//vyczislienie_i_OBRABOTKA_realnoj_tiemperatury http://arduino-diy.com/arduino-thermistor или http://robotclass.ru/tutorials/arduino-thermistor-100k/
//ТУТ СЧИТАЕМ
float tr = 1023.0 / (NTC_TMP/ilosc_usrednenij) - 1;
tr = SERIAL_RT / tr;

NTC_real = tr / THERMISTOR_R; // (R/Ro)
NTC_real = log(NTC_real); // ln(R/Ro)
NTC_real /= B; // 1/B * ln(R/Ro)
NTC_real += 1.0 / (NOMINAL_T + 273.15); // + (1/To)
NTC_real = 1.0 / NTC_real; // Invert
NTC_real -= 273.15; // переводим в цельсии из кельвинов
//ПОСЧИТАЛИ NTC_real = -99,99...99,99 (например)
if (NTC_real <= -99.99){NTC_real= (-99.99);} // вводим логические ограничения
if (NTC_real > 99.99) {NTC_real= 99.99;} // вводим логические ограничения

//тут делаем с данными температуры, что нам надо
if (NTC_real>= 20.52)
{
// например, тут команда на включение вентилятора, подключенного на выходы +12В
}
// закончили делать с данными температуры, что нам надо

}//vyczislienie_i_OBRABOTKA_realnoj_tiemperatury

void READ_SREDNIEJE_U_i_T()
{ //void READ_SREDNIEJE_U_i_T
Uacc = analogRead(PINrawACC);
Uakb = analogRead(PINrawAKB);
NTC = analogRead(NTC_pin_raw);
//NTC = 1020; // для тестов
//NTC = 10; // для тестов


Uacc_TMP = (Uacc_TMP + Uacc );
Uakb_TMP = (Uakb_TMP + Uakb );
NTC_TMP = (NTC_TMP + NTC );

cykly_usrednenij_U ++;


if (cykly_usrednenij_U == ilosc_usrednenij)
{
U_acc_real = Uacc_TMP*(LONG_koefficient_delitelia_ACC+1)/1000000.0/ilosc_usrednenij;
U_akb_real = Uakb_TMP*(LONG_koefficient_delitelia_AKB+1)/1000000.0/ilosc_usrednenij;
vyczislienie_i_OBRABOTKA_realnoj_tiemperatury(); // ВЫЧИСЛЕНИЕ РЕАЛЬНОЙ ТЕМПЕРАТУРЫ, вынесено в отдельную функцию, чтобы не захламлять код.

if (kalibrovkaACC<255 && kalibrovkaAKB<255) //если калибровка старого типа, вычисляем напряжение по старому, если мы не в режиме калибровки.
{
U_acc_real = (Uacc_TMP * (1410.0+kalibrovkaACC+0.05)/100000.0/ilosc_usrednenij);
U_akb_real = (Uakb_TMP * (1410.0+kalibrovkaAKB+0.05)/100000.0/ilosc_usrednenij );
}

cykly_usrednenij_U = 0;
Uacc_TMP = 0; // обнуляем для начала нового отсчета
Uakb_TMP = 0;
NTC_TMP = 0;
}



if (vkluczic_wywod_dannyh_w_COM_port==1){// если включена опция вывода в ком порт для отладки
Serial.println("_______________");
Serial.print("NTC = ");Serial.println(NTC);
Serial.print("NTC_real = ");Serial.println(NTC_real);
Serial.println("_______________");
}



} //void READ_SREDNIEJE_U_i_T


void ODRABOTKA_DRLED()
{//void ODRABOTKA_DRLED()
// обработка включения выхода DRLED
DRLED = REM; // включаем выход синхронно с REM. Потом можно дописать другую логику.
}//void ODRABOTKA_DRLED()


void ODRABOTKA_EasyCAP()
{//ODRABOTKA_EasyCAP()

byte temp_R= (digitalRead (REAR_GEAR_in_pin)); // читаем состояние задней передачи
//digitalRead (!REAR_GEAR_in_pin); // инверсно читаем состояние задней передачи

// обработка ВКЛЮЧЕНИЯ задней передачи
if (temp_R==1 && flagREAR_GEAR ==0 && flagACC ==1) // если включенa задняя передача И вЫключен изикап И зажигание включено
{
flagREAR_GEAR = 1;
pauseTime_rear = millis();
}

if (flagREAR_GEAR == 1)
{
if (millis() - pauseTime_rear >= zaderzka_pered_VKL_izikapa ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
EasyCAP = 1; //digitalWrite(5, 1); /*включаем питание на дсдс изикапа 0 - выкл. 1- вкл
}
}

// обработка ВЫКЛЮЧЕНИЯ задней передачи
if ( (temp_R==0 && flagREAR_GEAR ==1 && flagACC ==1) || (flagACC == 0) ) // если (вЫключенa задняя передача И включен изикап И зажигание включено) ИЛИ (выключено зажигание)
{
flagREAR_GEAR =0;
pauseTime_rear = millis();
}

if (flagREAR_GEAR == 0)
{
if (millis() - pauseTime_rear >= zaderzka_pered_VKL_izikapa ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
EasyCAP = 0; //digitalWrite(5, 0); /*включаем питание на дсдс изикапа 0 - выкл. 1- вкл
}
}


}//ODRABOTKA_EasyCAP()

void OBRABOTKA_REJIMA_OTLADKI()
{//OBRABOTKA_REJIMA_OTLADKI
if (OTLADKA >= 1)
{ //if (OTLADKA >= 1)
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - если напряжение ACC > 6В то считаем ACC=14,5В АКБ считаем всегда AKB=14,5В
// 3 - напряжение ACC всегда считаем ACC=14,5В напряжение АКБ всегда считаем AKB=14,5В
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (U_akb_real > 6) {U_akb_real = 14.50;} // принимаем напряжение аккумалятора автомобиля за 14,50В (если реальное напряжение AKB > 6В)
if (OTLADKA >= 2 )
{
U_akb_real = 14.50;
if (OTLADKA >= 3 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 3 )
}




// принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
}//if (OTLADKA >= 1) //конец режима отладки.
}//OBRABOTKA_REJIMA_OTLADKI

void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
vykluchic_vse(); // вызвали функцию выключения всех выходов и напряжений с блока питания.
delay (500); // для зарядки конденсаторов после снятия нагрузки
//тут позже можно опционально добавить усреднение Uacc Uakb
//вычисляем новое значение калибровки
brac_nastrojki_iz_EEPROM =2; // включили режим считывания настроек из энергонезависимой памяти
RABOTA_z_EEPROM (); // считали значения пользователя из энергонезависимой памяти.
LONG_koefficient_delitelia_ACC = 12000000/Uacc;
LONG_koefficient_delitelia_AKB = 12000000/Uakb;
kalibrovkaNOW ++;
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW >= 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,255);
EEPROM.update(1,255);

brac_nastrojki_iz_EEPROM = 1; // включили режим записи настроек в энергонезависимую память
RABOTA_z_EEPROM (); // вписали значения пользователя с калибровкой в энергонезависимую память.

sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);

FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
display_BUFER_to_real_DISPLAY(); //

delay (60000);


}

}//void rejim_kalibrovki()




void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обр аботка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/

if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~коне ц отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()


void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------


// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
}

if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
} // конец как только включили зажигание ( при любом напряжении батареи)


if (flagACC ==1 )
{// если flagACC == 1
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}

if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_USB_or_POGO = 1; //digitalWrite(FIVE_Volt_OUT_na_USB_or_POGOpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}

if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}

if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}

if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}

if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}

if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)

if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*"нажимаем" кнопку питания*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj _knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)


}// если flagACC == 1

STATUS_REM(); //зашли в функцию обработки статуса выхода REM


}//END void obrabotka_ACC_ON()

void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------

if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//

if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/

if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}

if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+vremia_uderjanija_najato j_knopki_POWER) ) { SLEEP = 0;}
}//if (HALL_as_power_Switch == 1)


if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/

}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vykl_ACC+t imeAfterACC)) )
{
FIVE_Volt_OUT_na_USB_or_POGO = 0;//digitalWrite(FIVE_Volt_OUT_na_USB_or_POGOpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}

if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}


if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея
}


if ( ((millis() - pauseTimeACC) >= (I_dva_C_szina_OFF_time + timeAfterACC )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
}

if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}


if (razreszenie_raboty_I_dva_C_sziny == 0) //Не даём заснуть при активном режиме
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.


}// if (flagACC==0)

} //END obrabotka_ACC_OFF()


void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------

if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/

if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}

if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_USB_or_POGO = 0; //digitalWrite(FIVE_Volt_OUT_na_USB_or_POGOpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}

if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}

if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

} //END obrabotka_AKB()

void loop()
{while (1){//для ускорения void loop


READ_SREDNIEJE_U_i_T(); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(ilosc_usrednenij)раз.

if ( (millis() < 120000) )
{
if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0) // после 120с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ
{
if ( (millis() < 120000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();}
}
}

OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора

if (TipBlokaPitania==133) // на BP5.PRO считываем состояние задней передачи и управляем изикапом
{
ODRABOTKA_EasyCAP();
ODRABOTKA_DRLED();
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ

// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)



/******************************************индикаци я светодиодом и задержка вывода на дисплей******************************************* ************************************************** ************************************************** *********************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}

if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
print_in_DISPLAY_BUFER(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}

/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[6];} // режим калибровки

}
/* ***********************данные для справки******************************************* *********************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//************************************************** ************************************************** ******


if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}

if (kalibrovkaNOW <= 5) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами а преходим в функцию выключения всех выходов.
{UPRAVLENIE_PINAMI();
}else {vykluchic_vse(); }

}} /*конец цикла void loop() и конец while (1)*/
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
//================================================== ================================================== ================================================== ================================================== ================================================== =================
/* _

______Сделано_____________________________________ _____________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напряжение батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик постоянно обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)

m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. __________________________________________________ ______________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.
m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
- Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
- В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.
m40 - исправление некорректного поведения "кнопки" при выключении зажигания (когда выходы на датчик холла используются в режиме имитации кнопки питания)
m41-42 - добавление ячеек памяти в еепром.
- добавление нового типа БП BP5.PRO ( тестовая плата), возможность использовать одну прошивку на разных платах БП. Это деаёт мне возможность поддерживать прошивку даже при устаревании "железа"
- считывание показаний с терморезистора и их пересчет в температуру. на BP5.PRO встроено. На младших версиях - можно допаять.
- на BP5.PRO считываем состояние задней передачи и управляем изикапом
- на BP5.PRO - обработка включения выхода DRLED
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)

- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает


ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .

M174
24.05.2019, 10:42
Наконец то нашлось время рассказать о своей поделке, заодно и немного оживлю тему.

Отлично получилось! ) Идея вынести разъем наружу очень понравилась!

skanch
24.05.2019, 11:18
Идея может и хорошая,но чревата "отвалами" USB. Причём Nexus возглавляет этот список.

oleg707
27.05.2019, 03:12
Теория - попросили написать. Упрощённо и кратко.
Берём абстрактный планшет с абстрактным контроллером батареи.
Задача - впихнуть вместо батареи DC DC.
В общем случае мы ищем токовый шунт и блокировочные транзисторы по минусу и коротим их куском провода (перемычкой).
Также меняем датчик температуры (терморезистор) на обычный резистор.
Перемычкой мы выравниваем потенциалы и контроллер не видит заряда-разряда.
В крайнем случае для особо умных контроллеров подымаем напряжение до 4.5В, чтобы разряд программно не опускался.
Если отключить батарею, а питание подать на материнскую плату, прицепив туда же контроллер без перемычки, то контроллер скорее всего не запустится, поскольку блокировочный транзистор закрыт и не пропускает ток.
Поэтому паяем перемычку, выкидываем батарею и вместо нее припаиваем уже настроенный дс-дс преобразователь.
Причем я бы паял провода от ДС ДС к контроллеру со стороны подключения к материнской плате, потому как перемычка все равно может иметь сопротивление, влияющее на замер отдаваемого тока "батареей" (дс-дс).

skanch
27.05.2019, 08:38
Теория - попросили написать. Упрощённо и кратко.
Берём абстрактный планшет с абстрактным контроллером батареи.
Задача - впихнуть вместо батареи DC DC.
В общем случае мы ищем токовый шунт и блокировочные транзисторы по минусу и коротим их куском провода (перемычкой).
Также меняем датчик температуры (терморезистор) на обычный резистор.
Перемычкой мы выравниваем потенциалы и контроллер не видит заряда-разряда.
В крайнем случае для особо умных контроллеров подымаем напряжение до 4.5В, чтобы разряд программно не опускался.
Если отключить батарею, а питание подать на материнскую плату, прицепив туда же контроллер без перемычки, то контроллер скорее всего не запустится, поскольку блокировочный транзистор закрыт и не пропускает ток.
Поэтому паяем перемычку, выкидываем батарею и вместо нее припаиваем уже настроенный дс-дс преобразователь.
Причем я бы паял провода от ДС ДС к контроллеру со стороны подключения к материнской плате, потому как перемычка все равно может иметь сопротивление, влияющее на замер отдаваемого тока "батареей" (дс-дс).
Сам-то понял, что написал? Если решил обобщить информацию по подключению "всех" планшетов, то сделай это правильно, а не как всегда "упрощённо и кратко". Если информация рассчитана на пользователей, как ты их называешь из "развивающихся регионов (http://pccar.ru/showpost.php?p=405611&postcount=38)", то кроме дополнительной путаницы в подготовке планшета ты им ничего не предоставил. Твоя "теория, которую просили написать" в очередной раз вызывает по меньшей мере улыбку.

dima_dima_dima
27.05.2019, 13:05
Добавил файлы плат, правда там творческий беспорядок, так как причесывать все было некогда, все там же в гуглопапке.
Nexus 7 Power Supply (https://drive.google.com/drive/folders/1U69i7t5SrcyMAG1K79F0nQ6k4y-tBabI?usp=sharing)
Идея может и хорошая,но чревата "отвалами" USB. Причём Nexus возглавляет этот список.
Не знаю, не замечал каких то проблем после того как поменял отвалившийся кив на следующую версию БП. Может просто повезло)

skanch
27.05.2019, 14:56
...Не знаю, не замечал каких то проблем после того как поменял отвалившийся кив на следующую версию БП. Может просто повезло)
Чтобы не быть голословным - это (https://www.drive2.ru/l/531138884080239129/) один из многочисленных случаев "отвалов" USB соединений, если USB выводится простыми проводами без дополнительного экранирования. Особо актуально для планшетов Nexus.

oleg707
27.05.2019, 22:17
Сам-то понял, что написал? Если решил обобщить информацию по подключению "всех" планшетов, то сделай это правильно, а не как всегда "упрощённо и кратко". Если информация рассчитана на пользователей, как ты их называешь из "развивающихся регионов (http://pccar.ru/showpost.php?p=405611&postcount=38)", то кроме дополнительной путаницы в подготовке планшета ты им ничего не предоставил. Твоя "теория, которую просили написать" в очередной раз вызывает по меньшей мере улыбку.

Это как раз упрощённо и кратко. И писалось для людей, которые вообще не понимают, что и как делает контроллер, НЕ входя в ньюансы. Информация на почитать для общего понимания потому как мне приходится периодически разжёвывать одно и то же. Людям, которые паяют первый раз в жизни.
Если ты не поленился найти про "развивающиеся регионы", то напоминаю, что я из Беларуси, в которой *опа похлеще, чем в России.
Поэтому информацию я даю бесплатно, и делюсь всеми своими схемами и наработками. Включая исходники. Кто может - повторяет. И таких очень много, как оказалось.
Вот это всё приносит мне радость.

M174
28.05.2019, 00:13
Чтобы не быть голословным - это (https://www.drive2.ru/l/531138884080239129/) один из многочисленных случаев "отвалов" USB соединений, если USB выводится простыми проводами без дополнительного экранирования. Особо актуально для планшетов Nexus.
Переходник отличный! Давно видел ваше решение на драйве... Вот только что делать тем, у кого места для него нет от слова совсем? ( я спрашиваю, потому что в ближайшее время мне предстоит процесс внедрения 2013 LTE

skanch
28.05.2019, 00:36
Переходник отличный! Давно видел ваше решение на драйве... Вот только что делать тем, у кого места для него нет от слова совсем? ( я спрашиваю, потому что в ближайшее время мне предстоит процесс внедрения 2013 LTE
Как вариант (http://pccar.ru/showpost.php?p=406152&postcount=40)... Ещё один момент: паять провода нужно до резисторов на линиях D+ и D- со стороны USB разъёма. "Пятаки" на мат-плате не лучшее решение от слова совсем...

http://pccar.ru/attachment.php?attachmentid=40240&d=1434748365

alex676kz
02.06.2019, 06:50
Всем привет. А возможно реализовать плей , пауза в прошивке через usb ??? На базе этого БП

oleg707
02.06.2019, 15:28
Всем привет. А возможно реализовать плей , пауза в прошивке через usb ??? На базе этого БП

без глубокой доработки - нет. В БП нету usb HID, блок не подключен к юсб планшета, чтбы можно было скрестить его с serial manager.
Сама идея хорошая, подумаю над её внедрением.
Можете попробовать сделать ТАК (https://youtu.be/dV1Yh0CO1Gw).
dV1Yh0CO1Gw

alex676kz
04.06.2019, 07:20
без глубокой доработки - нет. В БП нету usb HID, блок не подключен к юсб планшета, чтбы можно было скрестить его с serial manager.
Сама идея хорошая, подумаю над её внедрением.
Можете попробовать сделать ТАК (https://youtu.be/dV1Yh0CO1Gw).
dV1Yh0CO1Gw
Это не очень хорошо ))). У меня планшет samsung note 2014. Я не нашёл ни какой инфы про otg пин. Чтоб работал otg и зарядка. Есть ещё идея реализовать плей пауза через гарнитуру(пин микрофона). Тока не знаю как добавить в вашу прошивку так как не силён в c+. Работаю чисто с железом.

skanch
04.06.2019, 08:47
Это не очень хорошо ))). У меня планшет samsung note 2014. Я не нашёл ни какой инфы про otg пин. Чтоб работал otg и зарядка. Есть ещё идея реализовать плей пауза через гарнитуру(пин микрофона). Тока не знаю как добавить в вашу прошивку так как не силён в c+. Работаю чисто с железом.
Можно использовать готовый вариант с очень широким функционалом - нужно просто повторить и получите не только "плей-пауза"
http://pccar.ru/showpost.php?p=408005&postcount=845
http://pccar.ru/showpost.php?p=410060&postcount=878

Это видео работы

HInXotX8_SA

Vitaly123
05.06.2019, 06:17
Ещё бы кто-нибудь расписал бы этот джойстик под андроид проект поподробнее цены бы ему не было.

alex676kz
05.06.2019, 07:55
Можно использовать готовый вариант с очень широким функционалом - нужно просто повторить и получите не только "плей-пауза"
http://pccar.ru/showpost.php?p=408005&postcount=845
http://pccar.ru/showpost.php?p=410060&postcount=878

Это видео работы

HInXotX8_SA
Всё это интересно ))) но мне городить ещё какую нибудь дополнительную приблуду ненужно. Хочу чтоб всё в одном было. В вашем скетче можно реализовать управление через пин микрофона по этой схеме ???
51256 только чтоб программировать выход D .
А на счёт вашего видео есть готовое решение [URL="https://m.ru.aliexpress.com/item/32920979327.html"[/URL]

skanch
05.06.2019, 08:41
...Хочу чтоб всё в одном было.
Вы самостоятельно делаете блок "всё в одном"? И есть уже наработки в этом направлении? Или Вы собрались питать samsung note 2014 от MP1584?
В вашем скетче можно реализовать управление через пин микрофона по этой схеме ???
Уверен, что oleg707 сможет сделать в скетче управление коммутацией микрофона, если подскажите, какой мультиплексор Вы для этого используете.

А на счёт вашего видео есть готовое решение...
Это разные по функционалу устройства. Но каждый выбирает под себя...

alex676kz
05.06.2019, 23:42
Вы самостоятельно делаете блок "всё в одном"? И есть уже наработки в этом направлении? Или Вы собрались питать samsung note 2014 от MP1584?

Уверен, что oleg707 сможет сделать в скетче управление коммутацией микрофона, если подскажите, какой мультиплексор Вы для этого используете.

Это разные по функционалу устройства. Но каждый выбирает под себя...
У меня уже готово и стоит работает )))) Питание реализовано на XL4005 . Всё управляется через задержки на транзисторах. Установллен SSD на 320Гб. в сон уважу через магнитный датчик . Хотелось бы улучшить управление ))) Мне нужно чтоб при просыпании планшета после запуска подовало с ардуины на пин микрофона сигнал на плей через 7 сек. что успел подключится SSD.

skanch
06.06.2019, 00:20
У меня уже готово и стоит работает )))) Питание реализовано на XL4005 .
Китайский модуль или собственная плата?

mazay66
06.06.2019, 09:10
Ещё бы кто-нибудь расписал бы этот джойстик под андроид проект поподробнее цены бы ему не было.

Распишу, когда закончу проект. Вместе с БП и планшетом

Мне нужно чтоб при просыпании планшета после запуска подовало с ардуины на пин микрофона сигнал на плей через 7 сек. что успел подключится SSD.
Чем Таскер не подходит? По событию "пробуждение экрана", с нужной временной задержкой, выполнить команду плей.

А на счёт вашего видео есть готовое решение [URL="https://m.ru.aliexpress.com/item/32920979327.html"[/URL] Эээ... для вашей задачи, наверное, ДА. Если речь только об управлении плеером.

oleg707
06.06.2019, 14:46
Мне нужно чтоб при просыпании планшета после запуска подовало с ардуины на пин микрофона сигнал на плей через 7 сек. что успел подключится SSD.
а почему не управлять планшетом по usb HID ?

Чем Таскер не подходит? По событию "пробуждение экрана", с нужной временной задержкой, выполнить команду плей.
+1 за таскер

alex676kz
06.06.2019, 20:02
Китайский модуль или собственная плата?
Китайский модуль. После него стоит 2 фильтра с компьютерного блока питания . После каждого фильтра стоят ёмкости по 4700 на 16. Звук беру с наушников . Только если на полную громкость магнитоллы слышно чуть чуть помехи. Если надо фото могу сделать . Печатки не травил как не было времени и желания. Сам телемастер

alex676kz
06.06.2019, 20:05
а почему не управлять планшетом по usb HID ?


+1 за таскер
Если я б знал как сделать програмнно ))) Я работаю по железу . Доампы шью и править могу . Опять читать учить ((( Спасибо за идею.:wink2:

oleg707
07.06.2019, 00:12
Если я б знал как сделать програмнно ))) Я работаю по железу . Доампы шью и править могу . Опять читать учить ((( Спасибо за идею.:wink2:

так ардуино на 32u4 процессоре (https://duino.ru/arduino-pro-micro.html) - можно к хабу прицепить, задать логику срабатывания и кидать команды. Если правильно помню в arduino IDE файл- примеры - юсб.
У меня сейчас возможности заняться этим нету, а обещать не хочется ( обещанного 3 года ждут).

По поводу таскера я выкладывал видео, как сделать автоплей и паузу при подключении\снятии зарядки планшета.

M174
13.06.2019, 17:44
Как вариант (http://pccar.ru/showpost.php?p=406152&postcount=40)... Ещё один момент: паять провода нужно до резисторов на линиях D+ и D- со стороны USB разъёма. "Пятаки" на мат-плате не лучшее решение от слова совсем...

http://pccar.ru/attachment.php?attachmentid=40240&d=1434748365
У 2013 LTE немного по другому всё... тут непонятно куда паять D+ и D- (((
Земля понятно что на ногу разъема, 5В мне не надо на хаб - будут с БП Олега...

skanch
13.06.2019, 21:04
У 2013 LTE немного по другому всё... тут непонятно куда паять D+ и D- (((
Земля понятно что на ногу разъема...
D+ и D- тоже паять прямо на ноги разъёма. Со стороны контакта линии +5V следующий контакт D-, потом D+, OTG и далее GND. В такой последовательности. Паять витую пару из кабеля USB 3.0 с внутренней кросс-жилой, с оставленной внешней фольгой-экраном. Сигнальные на соответствующие контакты разъёма, а кросс-жилу на корпус разъёма. Естественно перед этим все "затянуть" в термоусадку, что бы не закоротить что-нибудь на мат-плате.

M174
13.06.2019, 21:20
D+ и D- тоже паять прямо на ноги разъёма. Со стороны контакта линии +5V следующий контакт D-, потом D+, OTG и далее GND. В такой последовательности. Паять витую пару из кабеля USB 3.0 с внутренней кросс-жилой, с оставленной внешней фольгой-экраном. Сигнальные на соответствующие контакты разъёма, а кросс-жилу на корпус разъёма. Естественно перед этим все "затянуть" в термоусадку, что бы не закоротить что-нибудь на мат-плате.
Понял! Спасибо ) Просто думал что можно где-то в другом месте взять, а судя по картинкам из интернета, все прямо на ноги разъема припаиваются. Думаю будет не лишним после пайки, ещё всё залить компаундом каким нибудь...

skanch
13.06.2019, 21:33
Понял! Спасибо ) Просто думал что можно где-то в другом месте взять, а судя по картинкам из интернета, все прямо на ноги разъема припаиваются. Думаю будет не лишним после пайки, ещё всё залить компаундом каким нибудь...

Вот картинка, но настоятельно рекомендую "витую пару" "упаковать" в экран... И не делать дополнительных разъёмов на линии USB.

51280

Источник. (https://www.drive2.ru/l/527373331633014894/)

M174
13.06.2019, 22:41
Вот картинка, но настоятельно рекомендую "витую пару" "упаковать" в экран... И не делать дополнительных разъёмов на линии USB.

51280

Источник. (https://www.drive2.ru/l/527373331633014894/)
Еще раз спасибо! Разъемов не будет - прямая распайка в хабе )

oleg707
04.07.2019, 21:50
работаю над проектом к следующей машине. Как доделаю, обкатаю, оттестирую - как обычно выложу в открытый доступ.
Работы еще много, так что пожелайте мне удачи :blush:
https://youtu.be/9ouu2UaT2ao
9ouu2UaT2ao

mazay66
04.07.2019, 23:04
Если звуковую карту разместил на плате, то почему изикап подключаешь через разъём? Я не говорю, что его надо распаивать, как звуковую, но может быть, можно разместить как ардуино или модули питания? Ну и портов для внешней периферии почти не остается. Маловато, конечно. А так ничего, хорошая задумка - "все в одном"

oleg707
05.07.2019, 01:59
Если звуковую карту разместил на плате, то почему изикап подключаешь через разъём? Я не говорю, что его надо распаивать, как звуковую, но может быть, можно разместить как ардуино или модули питания?

По поводу размещения изикапа - причина банальна - место, точнее его полное отсутствие. Задача была вписаться в плату 10*10.
Я это вижу так: короткий юсб удлиннитель, воткнутый в управляемый процессором ЮСБ порт, туда уже изикап.
Сам изикап крепится сзади или в том же корпусе. На плате не захотел его размещать ( я на БП7 (http://pccar.ru/attachment.php?attachmentid=49425&d=1521973834)так делал), просто сжирается место.
Плюс я сильно ограничен жесткой спецификацией разводки дифф пар ЮСБ ( типа земляные полигоны над дорожками, непересечение и там еще целая куча правил - как пример (http://www.pcbtech.ru/razvodka-differentsialnykh-signalov-kak-izbezhat-oshibok) ). Поэтому пока так. Если будет возможность оптимизировать - обязательно учту пожелание :yes2:
Также не обязательно, что в этом порте будет изикап. Может что другое, перестроить - пару строк кода поменять в прошивке. Для теста подключал туда 2ТБ юсб винчестер - нормально себя чувствует.
На БП подключается +12В с задних фонарей, проц обрабатывает, и через секунду даёт питание +5 на изик. Тот включается и погнал картинку планшету ( с подключенной камеры, естественно ).
Такой алгоритм - гистерезис - больше нужен для коробок -автоматов, в ручных - защита от возможного дребезга контактов.

Ну и портов для внешней периферии почти не остается. Маловато, конечно. А так ничего, хорошая задумка - "все в одном"
Смотри, на хабе портов 4 штуки.
1 - звуковая карта ( точнее гальванический изолятор, но там дальше все равно карта)
2 - изикап, управляемый порт.
3, 4 - свободные. Я пока не знаю что туда впихнуть.
Если вдруг нам надо ЕЩЕ порты - покупаем хаб ( без внешнего питания), и втыкаем в порт 3 или 4 блока питания.
Флешки, ардуины и прочая малопотребляющая периферия через доп. хабы будет нормально работать.
На питание только этих 2х портов выделен отдельный DCDC ( то есть 2 ампера долговременой нагруски он потянет, или 3 в пике). По спецификации (https://ru.wikipedia.org/wiki/USB#%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0% BF%D0%B8%D1%82%D0%B0%D0%BD%D0%B8%D0%B5) 0,5 А на порт - с запасом.
Таким решением я экономлю место на плате, снижаю себестоимость.
На питание изикапа - тоже отдельный DCDC.
Кому надо еще порты - смотри пункт выше :big:

Я тут не хотел оптический и цифровой выходы звука разводить:smile1:, но на вырост решил, что пусть будет:yes2:

oleg707
13.07.2019, 13:53
ребят, вопрос. Уже задавался, но внятного ответа нет.
Для нового БП мне нужен кабель отг. То есть полноценно разведенный 5-и проводной кабель с микро юсб.
Паять не сильно хочется ( хотя могу :smile1:)
Есть ли готовые заводские решения?
Или нужно покупать кабель ЮСБ 3,0, потрошить его и припаивать к нему что то типа такого?
https://cdn2.sellbe.com/p27/s-27598/product/428/276327.jpg

Есть еще интересная инфа, но на каждое устройство нужно подбирать своё.
Можно ли заряжать активное устройство в режиме OTG? (http://rones.su/techno/usb-otg.html)
Да, такой режим предусмотрен разработчиками, но далеко не каждое портативное устройство этот режим поддерживает.
Режим зарядки при работе с периферией называется ACA (Accessory Charger Adapter). Для перехода в этот режим требуется особый OTG-кабель — в штекере
USB-mini/micro контакты 4 и 5 (ID и GND) должны быть замкнуты через резистор RID_A=124 кОм.
Источник информации: «Battery Charging v1.2 Spec and Adopters Agreement (BC1.2)»

Опять же, меня интересует юсб тип С плюс зарядка. Для телефона вместо планшета в машине.

skanch
13.07.2019, 15:40
.. полноценно разведенный 5-и проводной кабель с микро юсб.

51363

Здесь (https://ru.aliexpress.com/item/33039395121.html?spm=a2g0o.productlist.0.0.5358566 6rgU8jZ&algo_pvid=c920aba0-ac3a-4605-9456-75be8b0c5315&algo_expid=c920aba0-ac3a-4605-9456-75be8b0c5315-22&btsid=c22f3612-a9e8-493b-a80f-b9f18e1f00c8&ws_ab_test=searchweb0_0%2Csearchweb201602_2%2Csear chweb201603_60)...

oleg707
13.07.2019, 18:17
51363

Здесь (https://ru.aliexpress.com/item/33039395121.html?spm=a2g0o.productlist.0.0.5358566 6rgU8jZ&algo_pvid=c920aba0-ac3a-4605-9456-75be8b0c5315&algo_expid=c920aba0-ac3a-4605-9456-75be8b0c5315-22&btsid=c22f3612-a9e8-493b-a80f-b9f18e1f00c8&ws_ab_test=searchweb0_0%2Csearchweb201602_2%2Csear chweb201603_60)...

хм, похоже то, что надо. Попробую заказать, спасибо.

M174
14.07.2019, 18:02
работаю над проектом к следующей машине. Как доделаю, обкатаю, оттестирую - как обычно выложу в открытый доступ.
Работы еще много, так что пожелайте мне удачи :blush:
https://youtu.be/9ouu2UaT2ao
9ouu2UaT2ao
Прикольный девайс! А я твой блок питания вынес из-за планшета, провода до планшета примерно 30см ))) Проехал 2700км по жаре... Всё работает как часы! :pleasantry:

oleg707
18.07.2019, 00:08
Экспериментирую тут с изикапом.
Логика работы такая:
при включении задней передачи через секунду включаем питание +12В на дсдс mini360 (https://duino.ru/Step-Down-mini.html), который подаёт +5В на питание изикапа. При выключении задней - через 4 секунды питание снимается с дсдс и пропадает +5В из системы.
Логика подходит также для коробок-автоматов.
Так вот, при подключении питания самой камеры на заднюю передачу, при выключении задней 4 секунды висит черный экран, поскольку камера отключена и не даёт видеосигнала, а изикап еще в системе.
Варинта разрешения тут я вижу три:
1 - уменьшить время задержки перед выключением. Черный экран будет, например, секунду; 0,5c и т.д.
2 - запитывать камеру не от задней передачи, а от плюса после включения зажигания. Камера работает постоянно, пока заведена машина. Это решение мне не нравится постоянно запитанной камерой.
3 - запитывать камеру не от задней передачи, а от блока питания. В этом случае при выключении заднего хода картинка будет еще выводится с работающей камеры в течение 4 секунд.
В третьем случае есть две точки, откуда можно брать запитку +12 на камеру.
Одна - есть дополнительный канал на 12В. Но его жалко, я хотел в будущем на него подключить дневные ходовые огни ( светодиоды).
Вторая - это вход +12В запитки дсдс. Поскольку все равно камера и изикап включаются и выключаются одновременно, экономим один выход. Недостатки - этот контакт не выведен на разъем блока питания, нужно паять. Но поскольку подпаиваться нужно к большой толстой ноге дсдс, то именно это решение мне нравится больше других.

Как ВЫ думаете? Может предложите свою логику?
https://youtu.be/3VvyrEeXnJU
3VvyrEeXnJU

CrossFire1312
18.07.2019, 07:09
Экспериментирую тут с изикапом.
Логика работы такая:
при включении задней передачи через секунду включаем питание +12В на дсдс mini360, который подаёт +5В на питание изикапа. При выключении задней - через 4 секунды питание снимается с дсдс и пропадает +5В из системы.


Зачем 4 секунды? Включил заднюю - включается камера от лампы З/Х, вместе с ней по этому-же сигналу запитывается Изикап. При отключении - сразу же наоборот. Без организации всяких задержек. У меня так. При чем, при переводе АКПП в D (прохождении R) - камера не успевает включаться. А так - включение камеры происходит менее чем через 0,5 сек. после включения задней передачи, автоматически (без установки этого таймера). Отключение - сразу, без всяких задержек. У меня так и нет проблем. Правда питание на изикап приходит через коммутатор питания (что-то типа Skanch"евского, собственного изготовления), который управляется так же от лампы З/Х.

oleg707
18.07.2019, 14:37
:yes2:Зачем 4 секунды? Включил заднюю - включается камера от лампы З/Х, вместе с ней по этому-же сигналу запитывается Изикап. При отключении - сразу же наоборот. Без организации всяких задержек. У меня так. При чем, при переводе АКПП в D (прохождении R) - камера не успевает включаться. А так - включение камеры происходит менее чем через 0,5 сек. после включения задней передачи, автоматически (без установки этого таймера). Отключение - сразу, без всяких задержек. У меня так и нет проблем. Правда питание на изикап приходит через коммутатор питания (что-то типа Skanch"евского, собственного изготовления), который управляется так же от лампы З/Х.

Вообще логика настраиваемая, можно выставить 0.1с, можно хоть 20. Там 2 цифры поменять, минута работы.
Хочется сделать, как сделано на новых машинах. Там включение около 0.5с, а выключение либо через задержку, либо когда тронешься ( по сигналу скорости).
Ну и плюс таким решением убирается потенциальная проблема дребезга либо плохого контакта, может меньше полосок на камере у кого будет.
И да, не в всех машин общий минус на лампочке заднего хода. Иногда встречается с общим плюсом, и это как раз мой случай:big:.
В общем поставлю задержку на выключение секунду, а там в реальных условиях поэкспериментировать можно будет.

mazay66
18.07.2019, 23:36
От всех задержек давно отказался, включая АКПП. Сначала делал задержку на включение 0,5-1сек. Потом выяснилось, как сказано выше, что и без задержки камера не успевает включиться. Задержка только мешает и раздражает. Задержка на выключение...??? Ради чего? Чтобы посмотреть на черный экран? Точно не надо. Возможно смысл тут в другом. Например, при частом чередовании включения задней и первой передачи. Что бы совершить маневр и для этого надо несколько раз включать заднюю передачу. В этом случае, приложение и изик продолжают работать, а не "рубятся" при каждом выключении задней передачи. И это правильно. Думаю, задержка выключения может быть полезна. Надо попробовать. Спасибо за идею.

oleg707
19.07.2019, 00:13
От всех задержек давно отказался, включая АКПП. Сначала делал задержку на включение 0,5-1сек. Потом выяснилось, как сказано выше, что и без задержки камера не успевает включиться. Задержка только мешает и раздражает. Задержка на выключение...??? Ради чего? Чтобы посмотреть на черный экран? Точно не надо. Возможно смысл тут в другом. Например, при частом чередовании включения задней и первой передачи. Что бы совершить маневр и для этого надо несколько раз включать заднюю передачу. В этом случае, приложение и изик продолжают работать, а не "рубятся" при каждом выключении задней передачи. И это правильно. Думаю, задержка выключения может быть полезна. Надо попробовать. Спасибо за идею.

Чтобы посмотреть на черный экран? Точно не надо.
Да, абсолютно согласен. Поэтому я вижу решение такое:
Поскольку у меня все равно управляет процессор, то задержки вкл-выкл он и организует. Управляем интеллектуальным ключём ( its724).
С того уже идёт +12в на дс-дс, включающий изикап. Так вот оттуда берём питание +12в на камеру. После дс-дс берём +5в и питаем изикап.
Это решение даёт избавление от дребезга контактов и картинку после физического выключения заднего хода.
Опять же в моем случае имеем порт юсб со своим дс-дс, на 1.5 Ампера. Я на нем юсб винчестер гонял - 30мб/с длительная скорость, надоело тестировать. То есть если кому не надо КЗХ, юсб порт в хабе не теряется.

Немного сумбурно, но, надеюсь, суть передал.
PS
Думал про твою идею изикап припаивать, а не через разъем. И что-то не могу на плате нормального места под это дела придумать. По правилам разводки и расположения компонентов положение неудобное получается. В общем, буду думать, может просто на кабель припаять проще будет. Пока на практике не попробуешь - теоретизировать можно долго:big:

CrossFire1312
19.07.2019, 08:16
Хочется сделать, как сделано на новых машинах. Там включение около 0.5с, а выключение либо через задержку, либо когда тронешься ( по сигналу скорости).
Ну и плюс таким решением убирается потенциальная проблема дребезга либо плохого контакта, может меньше полосок на камере у кого будет. .

И у нас с применением Изикапа и без организации таймерных задержек включение около 0.5 сек. И вот никакого дребезга нет. И полос тоже. Полосы от китайских кабелей, идущих в комплекте с камерами. Микрофонный кабель однозначно предпочтительней всего... Про дребезг - эл ключ дополнен кондерами, да и программно это решаемо. Как пример реализации, если в течении 5 мсек управляющий сигнал пропал и не возобновился - то это не дребезг, а отключение.
А я сделал так - после отключения заднего хода - включается передняя камера на 10 сек. При включении поворотов - включается соответствующая камера бокового обзора в зеркалах. Естественно при З/Х и повороте - приоритет у правой камеры (для вида: правые колеса - бордюр при парковке). Далее приоритет задняя камера, боковая левая, передняя. Так же есть возможность включения камер в ручном режиме.

Только вот проблема - не хочется видеть боковые камеры при перестроении. Как из ОБД вытащить скорость и загнать в Ардуину? Пока принудительно выключаю эту функцию переключателем, так как раздражает на ходу. Хочется запретить включение боковых камер с 3 км/час. Кто поможет?

Alex15BV
19.07.2019, 12:19
Только вот проблема - не хочется видеть боковые камеры при перестроении. Как из ОБД вытащить скорость и загнать в Ардуину? Пока принудительно выключаю эту функцию переключателем, так как раздражает на ходу. Хочется запретить включение боковых камер с 3 км/час. Кто поможет?

А почему OBD? Нельзя ли проще: с датчика скорости импульсы взять?

oleg707
19.07.2019, 17:34
А почему OBD? Нельзя ли проще: с датчика скорости импульсы взять?

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

Alex15BV
19.07.2019, 22:35
дада, мне кажется так намного оптимальнее. через делитель напряжения. Но только в случае цифрового датчика ( таких сейчас большинство). На индуктивном напряжение растет от скорости. Брать можно от щитка приборов ( вообще зависит от машины)

Поскольку говорим о программном слежении - всё равно, что отслеживать: цифровые импульсы, аналоговое напряжение... Разница в коде только.
Можно хоть с датчика АБС попробовать сигнал.

oleg707
19.07.2019, 23:02
Поскольку говорим о программном слежении - всё равно, что отслеживать: цифровые импульсы, аналоговое напряжение... Разница в коде только.
Можно хоть с датчика АБС попробовать сигнал.

Не, тут ты не прав.
Если цифровые импульсы изменяют только частоту, оставаясь по амплитуде одинаковыми ( 5, 12в) , то аналоговые датчики скорости автомобиля при увеличении скорости изменяют не только частоту, но и напряжение по амплитуде! Не помню как там по скоростным, а по датчикам коленвала до 100 вольт может доходить ;)
И проблема есть в том, чтобы скинуть напряжение до уровня питания ардуины, чтобы не спалить проц. Поэтому надо городить схему согласования. :be:
В отличие от цифрового датчика, где достаточно 2х резисторов:rolleyes2:

А по поводу датчиков АБС вообще отдельная история. Дело в том, что они есть тоже аналоговые и цифровые. Про аналоговые все повторяет написанное выше.
А вот с цифровыми веселее.
Дело в том, что провода 2. И блок АБС определяет гребёнку ( физическую или магнитную) по изменению тока полупроводника (датчика холла).
Чтобы считать без ошибок сигнал, нужно ставить в разрыв датчика резистор, на котором будет происходить падение напряжения, и обрабатывать уже этот сигнал. Про усилитель я уже молчу,.

Так что проще взять сигнал прямоугольный формы с датчика скорости, с выхода блока АБС, или из других мест.
Если в машине сигнал скорости не идёт по цифровой шине:spiteful:

Alex15BV
20.07.2019, 04:45
:big: Во-первых: схему согласования никто и не отменял - мне кажется, что процент сигналов, которые можно напрямую в проц гнать, мал по сравнению с теми, что нужно формировать как-то.
Во-вторых (насколько я знаю): входные цепи АЦП от верхней границы измеряемого напряжения и рассчитывают - чтобы весь диапазон с запасом влезал в преобразователь?
Делитель можно же и от 100 Вольт посчитать... Дальше - полёт фантазии: пульсации железом сглаживать, прерывания по фронтам сигнала использовать, пачки импульсов суммировать...
Или как ты написал: просто рубить порог (например 30В) и подавать лог. 1 при всём, что выше (это у нас там этим занимается, компаратор?) - нам же нужно было "превышение скорости" насколько я помню... :blush:
Тем более, что к OBD тоже напрямую не подключиться - к-лайн адаптер же нужен? Ну минимум Л9637 с обвязкой...

skanch
20.07.2019, 11:16
...Хочется запретить включение боковых камер с 3 км/час. Кто поможет?
"Берем с тахометра сигнал и направляем его на вход МК через диод и резистор." Источник (https://www.drive2.com/b/1947098/).

T_r_D
20.07.2019, 11:36
Супрессор ещё поставить надо (стабилитрон).
Это чтоб не спалить контроллер.

oleg707
20.07.2019, 14:03
у меня кстати была идея запилить вход сигнала скорости для активного изменения громкости в зависимости от скорости, но поскольку звуковой процессор для регулировки звука я не ставлю, то посчитал это излишеством.

А так алгоритм включения КЗХ можно от скорости прописать:
если была задняя передача и была выключена 10 сек назад либо меньше - для скорости меньше 3 км ч продолжаем держать камеру включеной.
включение - при наличии сигнала от концевика задней.