PCCar.ru - Ваш автомобильный компьютер

PCCar.ru - Ваш автомобильный компьютер (http://pccar.ru/index.php)
-   Питание (http://pccar.ru/forumdisplay.php?f=173)
-   -   Блок питания для NEXUS7-2012,2013 или любого планшета -печатка, прошивка, инструкция (http://pccar.ru/showthread.php?t=27466)

oleg707 19.07.2019 00:13

Цитата:

Сообщение от mazay66 (Сообщение 410785)
От всех задержек давно отказался, включая АКПП. Сначала делал задержку на включение 0,5-1сек. Потом выяснилось, как сказано выше, что и без задержки камера не успевает включиться. Задержка только мешает и раздражает. Задержка на выключение...??? Ради чего? Чтобы посмотреть на черный экран? Точно не надо. Возможно смысл тут в другом. Например, при частом чередовании включения задней и первой передачи. Что бы совершить маневр и для этого надо несколько раз включать заднюю передачу. В этом случае, приложение и изик продолжают работать, а не "рубятся" при каждом выключении задней передачи. И это правильно. Думаю, задержка выключения может быть полезна. Надо попробовать. Спасибо за идею.

Чтобы посмотреть на черный экран? Точно не надо.
Да, абсолютно согласен. Поэтому я вижу решение такое:
Поскольку у меня все равно управляет процессор, то задержки вкл-выкл он и организует. Управляем интеллектуальным ключём ( its724).
С того уже идёт +12в на дс-дс, включающий изикап. Так вот оттуда берём питание +12в на камеру. После дс-дс берём +5в и питаем изикап.
Это решение даёт избавление от дребезга контактов и картинку после физического выключения заднего хода.
Опять же в моем случае имеем порт юсб со своим дс-дс, на 1.5 Ампера. Я на нем юсб винчестер гонял - 30мб/с длительная скорость, надоело тестировать. То есть если кому не надо КЗХ, юсб порт в хабе не теряется.

Немного сумбурно, но, надеюсь, суть передал.
PS
Думал про твою идею изикап припаивать, а не через разъем. И что-то не могу на плате нормального места под это дела придумать. По правилам разводки и расположения компонентов положение неудобное получается. В общем, буду думать, может просто на кабель припаять проще будет. Пока на практике не попробуешь - теоретизировать можно долго:big:

CrossFire1312 19.07.2019 08:16

Цитата:

Сообщение от oleg707 (Сообщение 410783)
Хочется сделать, как сделано на новых машинах. Там включение около 0.5с, а выключение либо через задержку, либо когда тронешься ( по сигналу скорости).
Ну и плюс таким решением убирается потенциальная проблема дребезга либо плохого контакта, может меньше полосок на камере у кого будет. .

И у нас с применением Изикапа и без организации таймерных задержек включение около 0.5 сек. И вот никакого дребезга нет. И полос тоже. Полосы от китайских кабелей, идущих в комплекте с камерами. Микрофонный кабель однозначно предпочтительней всего... Про дребезг - эл ключ дополнен кондерами, да и программно это решаемо. Как пример реализации, если в течении 5 мсек управляющий сигнал пропал и не возобновился - то это не дребезг, а отключение.
А я сделал так - после отключения заднего хода - включается передняя камера на 10 сек. При включении поворотов - включается соответствующая камера бокового обзора в зеркалах. Естественно при З/Х и повороте - приоритет у правой камеры (для вида: правые колеса - бордюр при парковке). Далее приоритет задняя камера, боковая левая, передняя. Так же есть возможность включения камер в ручном режиме.

Только вот проблема - не хочется видеть боковые камеры при перестроении. Как из ОБД вытащить скорость и загнать в Ардуину? Пока принудительно выключаю эту функцию переключателем, так как раздражает на ходу. Хочется запретить включение боковых камер с 3 км/час. Кто поможет?

Alex15BV 19.07.2019 12:19

Цитата:

Сообщение от CrossFire1312 (Сообщение 410787)
Только вот проблема - не хочется видеть боковые камеры при перестроении. Как из ОБД вытащить скорость и загнать в Ардуину? Пока принудительно выключаю эту функцию переключателем, так как раздражает на ходу. Хочется запретить включение боковых камер с 3 км/час. Кто поможет?

А почему OBD? Нельзя ли проще: с датчика скорости импульсы взять?

oleg707 19.07.2019 17:34

Цитата:

Сообщение от Alex15BV (Сообщение 410790)
А почему OBD? Нельзя ли проще: с датчика скорости импульсы взять?

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

Alex15BV 19.07.2019 22:35

Цитата:

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

Поскольку говорим о программном слежении - всё равно, что отслеживать: цифровые импульсы, аналоговое напряжение... Разница в коде только.
Можно хоть с датчика АБС попробовать сигнал.

oleg707 19.07.2019 23:02

Цитата:

Сообщение от Alex15BV (Сообщение 410795)
Поскольку говорим о программном слежении - всё равно, что отслеживать: цифровые импульсы, аналоговое напряжение... Разница в коде только.
Можно хоть с датчика АБС попробовать сигнал.

Не, тут ты не прав.
Если цифровые импульсы изменяют только частоту, оставаясь по амплитуде одинаковыми ( 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

Цитата:

Сообщение от CrossFire1312 (Сообщение 410787)
...Хочется запретить включение боковых камер с 3 км/час. Кто поможет?

"Берем с тахометра сигнал и направляем его на вход МК через диод и резистор." Источник.

T_r_D 20.07.2019 11:36

Супрессор ещё поставить надо (стабилитрон).
Это чтоб не спалить контроллер.

oleg707 20.07.2019 14:03

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

А так алгоритм включения КЗХ можно от скорости прописать:
если была задняя передача и была выключена 10 сек назад либо меньше - для скорости меньше 3 км ч продолжаем держать камеру включеной.
включение - при наличии сигнала от концевика задней.

oleg707 21.07.2019 15:59

Обновление прошивки
 
m41-43 - добавление ячеек памяти в еепром.
- добавление нового типа БП BP5.PLUS ( тестовая плата), возможность использовать одну прошивку на разных платах БП. Это деаёт мне возможность поддерживать прошивку даже при устаревании "железа"
- считывание показаний с терморезистора и их пересчет в температуру. на BP5.PLUS встроено. На младших версиях - можно допаять.
- на BP5.PLUS считываем состояние задней передачи и управляем изикапом ( и питанием +12В камеры, если необходимо, брать на входе дсдс изикапа)
m43-46 - на BP5.PLUS - обработка включения выхода DRLED
- на BP5.PLUS и BP5 изменена индикация на дисплее 1602. Теперь вместо 01101 выводятся буквы. Не обрабатывается и выводится некоторая информация после тушения подсветки1602 дисплея


PHP код:

const byte ver 45;// ( чем больше цифра, тем новее)
const byte TipBlokaPitania 255// 133 - BP5.PLUS; 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 31.05.19.2019

// для BP5.PLUS, 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 дисплея) 0,25с

//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем  
//соответствующий пин блока питания (время независимо друг от друга)
 
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 =1000;                       // задержка перед вЫключением изикапа после вЫключения ЗАДНЕЙ_ПЕРЕДАЧИ
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 msms1 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_A014561611121314POSITIVE);  // для 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 и ставим флаг, чтобы они работали. 
              

               
razreszenie_raboty_I_dva_C_sziny  1// разрешаем работу шины I2C 
               
lcd.begin(162); //инициализация дисплея 1602 для newE библиотеки
  /*//13              display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // display 2 or adres 0x3D для 1306 дисплея
               display2.clearDisplay();        // для 1306 дисплея
               display2.setTextColor(WHITE);   // для 1306 дисплея
               *///13
               // !  ТУТ надо будет включать питание на звуковой проц  !  - для БП7
              
              
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
  if (
TipBlokaPitania == 255// 255 - BP5mini, BP5mini2.1, BP5mini+2.2
    
{
 
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//// 133 - BP5.PLUS
    
{
 
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_PinLED);                   //управление встроенным светодиодом
      
digitalWrite(SAMOZAPITKA_PinSAMOZAPITKA);   // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
      
digitalWrite(OTG_PinOTG);                   // управление OTG    
      
digitalWrite(HUB_Pin, !HUB);                  // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
      
digitalWrite(SLEEP_Pin, !SLEEP);               // управление микросхемой, которая даёт массу на пин сна ( датчик холла)
      
digitalWrite(PlanshBAT_PinPlanshBAT);        //управление питанием БАТАРЕЕЙ планшета (+4,0)
      
digitalWrite(REGISTRATOR_PinREGISTRATOR);    //управление питанием видеорегистратора (+12)
      
digitalWrite(FIVE_Volt_OUT_na_USB_or_POGO_PinFIVE_Volt_OUT_na_USB_or_POGO);   //управление вторым преобразователем DC-DC (+5В)
      
digitalWrite(REM_PinREM);                    //управление выходом REM (+12)
 
    
}
 if (
TipBlokaPitania == 133)
    {
      
digitalWrite(LED_PinLED);                   //управление встроенным светодиодом
      
digitalWrite(SAMOZAPITKA_PinSAMOZAPITKA);   // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
      
digitalWrite(OTG_PinOTG);                   // управление OTG    
      
digitalWrite(HUB_PinHUB);                   // управление питанием хаба
      
digitalWrite(SLEEP_Pin, !SLEEP);               // управление микросхемой, которая даёт массу на пин сна ( датчик холла)
      
digitalWrite(PlanshBAT_PinPlanshBAT);        //управление питанием БАТАРЕЕЙ планшета (+4,0)
      
digitalWrite(REGISTRATOR_PinREGISTRATOR);    //управление питанием видеорегистратора (+12)
      
digitalWrite(FIVE_Volt_OUT_na_USB_or_POGO_PinFIVE_Volt_OUT_na_USB_or_POGO);   //управление вторым преобразователем DC-DC (+5В)
      
digitalWrite(REM_PinREM);                    //управление выходом REM (+12)
      
digitalWrite(EasyCAP_pinEasyCAP);            //управление выходом (+12) для  питания дсдс изикапа 
      
digitalWrite(DRLED_pinDRLED);                // управление +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=0RABOTA_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_PinOUTPUT);  
  
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_PinOUTPUT);   
  
pinMode(REM_Pin,                          OUTPUT);    
      
// несортированные порты
  
pinMode  (PINrawACC,     INPUT);  
  
pinMode  (PINrawAKB,     INPUT);  
  
pinMode  (PINkalibrovkiINPUT);   // пин калибровки
  
pinMode  (NTC_pin_raw,   INPUT);  
   
// активируем у процессора внутренние резисторы подтяжки 
 
digitalWrite(PINkalibrovki1); // подтяжка +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(00);
    
lcd.print(strokaI);
  
    
lcd.setCursor(01); //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 numchar *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 numchar *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 numchar *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 numchar *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 numchar *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 numchar *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_eepromznachenija_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_eepromznachenija_polzovatelia); 
 
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<|| 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_ACC;
FIVE_Volt_OUT_na_USB_or_POGO_timer_pri_vkl_ACC  znachenija_polzovatelia.FIVE_Volt_OUT_na_USB_or_POGO_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_POGO_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_izikapa;
  
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_eepromznachenija_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_BP_PLUS()
{
//_____________________________________________ФОРМИРУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ____________________________________________________________

 
= (millis()/3600000);
 
= ((millis()-(H*3600000))/60000); 
 if (
flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
 //пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_____________________________________________________________________________________________________________________________________________________________________
 
sprintf(strokaI,"                ") ; 

//              Задняя_передача?  температура  стартуем?  УСИЛИТЕЛЬ(REM)  флаг_AСС  Напряжение_АСС

                
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';}        // если видим включение задней
                
if (EasyCAP==1){strokaI[0]=  'R';}              // если включили изикап
                
if (STARTUEM == 1) {strokaI[5]=  'S';} else {strokaI[5]=  's';}  // Стартует ли авто ( крутим ли стартером) s- не крутим, S - крутим.
                
if (REM == 1) {strokaI[7]=  'Y';} else {strokaI[7]=  'y';}       //вывод  rem 8 символ R-усилитель звука включен, r - выключен
                
if (HUB == 1) {strokaI[8]=  'H';} else {strokaI[8]=  'h';}       // вывод флага HUB                 
                
if (flagACC == 1) {strokaI[10]=  'A';} else {strokaI[10]=  'a';} // вывод флага AСС
                
FloatToCharIIIII (U_acc_real,  &strokaI[11]);                    // вывод напряжения АСС 
                //для отладки   strokaI[9]= flagREM + '0';// вывод  флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен

//______________конец обработки 1й строки ______________________________________________________________________________________________________________________________________________________________________________

//обработка 2й строки______________________________________________________________________________________________________________________________________________________________________________

//    версия_прошивки/время_работы     
                //TIMER = (  pauseTimeAKB  + timeUntilALLOff - millis()  )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)
                
if (    ( millis()-pauseTimeACC  30000 )&& flagACC == 1   ){  sprintf(strokaII,"m__+            ") ; IntToCharII(ver, &strokaII[1]);}   //Первые 30с после вкл ACC выводим версию блока.
                    
else { 
                          
sprintf(strokaII,"                ");   
                         } 
                         
                if (
flagACC == 0// после выключения зажиганя выводим полное время работы блока 
                
{
                
IntToCharIII(H, &strokaII[0]);  // вывод часов 000 
                
strokaII[3] =  ':';             // вывод двоеточия 
                
IntToCharII(M, &strokaII[4]);   // вывод минут 00 
                



//              OTG   HUB   POGO   HALL   Питание_планшета_по_USB   флаг_AKB   напряжение_АКБ
                        
                
if (OTG == 1) {strokaII[6]=  'O';} else {strokaII[6]=  'o';}                          // вывод флага OTG 
                
if (FIVE_Volt_OUT_na_USB_or_POGO == 1) {strokaII[7]=  'U';} else {strokaII[7]=  'u';} // вывод флага FIVE_Volt_OUT_na_USB_or_POGO (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб)
                
if (SLEEP == 1) {strokaII[8]=  'd';} else {strokaII[8]=  'D';}                        // вывод флага flagHALL 8 символ (инверсно)  1-экран включен, 0 - выключен                            
                
if (flagAKB == 1) {strokaII[10]=  'B';} else {strokaII[10]=  'b';}                    // вывод флага AKB
                
FloatToCharIIIII (U_akb_real,  &strokaII[11]);                                        // вывод напряжения АКБ
//______________конец обработки 2й строки ______________________________________________________________________________________________________________________________________________________________________________



if (kalibrovkaNOW >= && 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();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>> 
  
}

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

 
= (millis()/3600000);
 
= ((millis()-(H*3600000))/60000); 
 if (
flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
 //пример: sprintf( strokaII,"SETUP volume on ");

//обработка 1й строки_________AKB ACC REM_____________________________________________________________________________________________________________________________________________________________________
 
sprintf(strokaI,"                ") ; 

//          ___   стартуем?   УСИЛИТЕЛЬ(REM)  флаг_AСС  Напряжение_АСС



                
if (STARTUEM == 1) {strokaI[6]=  'S';} else {strokaI[6]=  's';}  // Стартует ли авто ( крутим ли стартером) s- не крутим, S - крутим.
                
if (REM == 1) {strokaI[8]=  'Y';} else {strokaI[8]=  'y';}       //вывод  rem 8 символ R-усилитель звука включен, r - выключен
                
if (flagACC == 1) {strokaI[10]=  'A';} else {strokaI[10]=  'a';} // вывод флага AСС
                
FloatToCharIIIII (U_acc_real,  &strokaI[11]);                    // вывод напряжения АСС 
                //для отладки   strokaI[9]= flagREM + '0';// вывод  флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен

//______________конец обработки 1й строки ______________________________________________________________________________________________________________________________________________________________________________

//обработка 2й строки______________________________________________________________________________________________________________________________________________________________________________

//    версия_прошивки/время_работы  
                //TIMER = (  pauseTimeAKB  + timeUntilALLOff - millis()  )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)
                
if (    ( millis()-pauseTimeACC  30000 )&& flagACC == 1   ){  sprintf(strokaII,"m__             ") ; IntToCharII(ver, &strokaII[1]);}   //Первые 30с после вкл ACC выводим версию блока.
                    
else { 
                          
sprintf(strokaII,"                ");   
                         } 
                         
                if (
flagACC == 0// после выключения зажиганя выводим полное время работы блока 
                
{
                
IntToCharIII(H, &strokaII[0]);  // вывод часов 000 
                
strokaII[3] =  ':';             // вывод двоеточия 
                
IntToCharII(M, &strokaII[4]);   // вывод минут 00 
                


//              OTG   HUB   POGO   HALL   Питание_планшета_по_USB   флаг_AKB   напряжение_АКБ
                        
                
if (OTG == 1) {strokaII[6]=  'O';} else {strokaII[6]=  'o';}                          // вывод флага OTG 
                
if (FIVE_Volt_OUT_na_USB_or_POGO == 1) {strokaII[7]=  'U';} else {strokaII[7]=  'u';} // вывод флага FIVE_Volt_OUT_na_USB_or_POGO (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб)
                
if (SLEEP == 1) {strokaII[8]=  'd';} else {strokaII[8]=  'D';}                        // вывод флага flagHALL 8 символ (инверсно)  1-экран включен, 0 - выключен                            
                
if (flagAKB == 1) {strokaII[10]=  'B';} else {strokaII[10]=  'b';}                    // вывод флага AKB
                
FloatToCharIIIII (U_akb_real,  &strokaII[11]);                                        // вывод напряжения АКБ
//______________конец обработки 2й строки ______________________________________________________________________________________________________________________________________________________________________________



if (kalibrovkaNOW >= && 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();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>> 
  
}

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

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

/*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_real99.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. Потом можно дописать другую логику.
    
if (REM == 1) {DRLED 1;}  // включаем ДРЛ при норм аккумуляторе или при заводке. 
    
if (SLEEP == 1){DRLED 0;} // вЫключаем ДРЛ при вЫключении экрана планшета (датчиком холла).
    
}//void ODRABOTKA_DRLED()


void ODRABOTKA_EasyCAP()
{
//ODRABOTKA_EasyCAP()

byte temp_R= (digitalRead (REAR_GEAR_in_pin)); // читаем состояние задней передачи
// temp_R = !temp_R; //  для редких машин с общим плюсом на задних фонарях (99.8% что вам это НЕ понадобится) инверсно читаем состояние задней передачи 

// обработка ВКЛЮЧЕНИЯ задней передачи    
    
if (temp_R==&& flagREAR_GEAR ==&& flagACC ==1  && HUB == 1// если включенa задняя передача И вЫключен изикап И зажигание включено и ХАБ включен
    
{
        
flagREAR_GEAR 1;
        
pauseTime_rear millis();
    }
    
    if (
flagREAR_GEAR == 1)
    {
          if (
millis() - pauseTime_rear >= zaderzka_pered_VKL_izikapa // пауза zaderzka_pered_VKL_izikapa после включения ЗАДНЕЙ_ПЕРЕДАЧИ и потом делать следующ(пока включена ЗАДНЯЯ_ПЕРЕДАЧА):
        
{
         
EasyCAP 1;  // включаем питание на дсдс изикапа 0 - выкл. 1- вкл
        
}      
    }
    
// обработка ВЫКЛЮЧЕНИЯ задней передачи    
    
if ( (temp_R==&& flagREAR_GEAR ==&& flagACC ==1) || (flagACC == 0) ) // если (вЫключенa задняя передача И включен изикап И зажигание включено) ИЛИ (выключено зажигание)
    
{
        
flagREAR_GEAR =0;
        
pauseTime_rear millis();
    }
    
    if (
flagREAR_GEAR == 0)
    {
          if (
millis() - pauseTime_rear >= zaderzka_pered_VYKL_izikapa // пауза zaderzka_pered_VYKL_izikapa после включения ЗАДНЕЙ_ПЕРЕДАЧИ и потом делать следующ(пока вЫключена ЗАДНЯЯ_ПЕРЕДАЧА):
        
{
         
EasyCAP 0;   // вЫключаем питание на дсдс изикапа 0 - выкл. 1- вкл
        
}
    }
    
    if ( 
HUB ==0)
        {
         
EasyCAP 0
        }
    
}
//конец 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 >= )
        {
        
U_akb_real 14.50;    
        if (
OTLADKA >= )  {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)== && 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 == && flagREM == 0  ) {flagREM 1TimerREM millis();} //если подзаряжен акб и включили зажигание  - ВКЛЮЧАЕМ REM
    
if (U_akb_real >= UrabotyREM && flagACC == && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM ;}  //  если кончилось время обратного отсчета - статус рем - 2.
     //if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
    
if (U_akb_real >= UrabotyREM && flagREM == && flagACC == 0){ flagREM 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
    
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM 2;} //если подсел акб при включенном зажигании - статус рем - 2.
      
if (U_akb_real >= UnevykluczeniaREM && flagACC == ){ (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 == ||  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 == && flagAKB == //проверка напруги АСС и АКБ при флаге ACC = 0
  
{
    
flagACC 1;
    
pauseTimeACC millis();
    
pauseTimeAKB millis();
  }

if (
U_acc_real >= UaccONorOFF)  //как только включили зажигание ( при любом напряжении батареи)
// как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
// конец как только включили зажигание ( при любом напряжении батареи)


if (flagACC ==)
{
// если flagACC == 1
      
if (((millis() - pauseTimeACC) >= (100)) )
      {
      if (
flagACC==&& 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 == ){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 == ){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==&& 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_najatoj_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+timeAfterACC))  ) 
                                                            {
                                                            
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 == && 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 >= ) { rejim_kalibrovki();}
 } 
}

OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора 

if (TipBlokaPitania==133// на BP5.PLUS считываем состояние задней передачи и управляем изикапом
{
    
ODRABOTKA_EasyCAP();
    
ODRABOTKA_DRLED();
}


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении  и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if ( (millis() > pauseTimeHALL && flagHALL == )|| ((millis() > 15000) && flagACC == 1)) 
  {
flagHALL 1;} /*проверка отсчета при холодном старте при включении  и сразу выключении ACC*/
  /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if ((U_akb_real U_acc_real) >=)/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
          
{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 << (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;
   
// выводим на дисплей раз в 350( запуская фушкцию)
   // 133 - BP5.PLUS; 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 
   
if (TipBlokaPitania == 133){   print_in_DISPLAY_BUFER_BP_PLUS();   }
   if (
TipBlokaPitania == 255){   print_in_DISPLAY_BUFER();           }
    
   
  }
}  

 
/*настраиваем режимы моргания встроенного светодиода ардуины*/  
  
if (blink_mode != modes[5] || blink_mode != modes[5]) 
  {
  if (
flagAKB == ){blink_mode modes[4];}                 // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду 
  
if (flagAKB == && flagACC == 0) {blink_mode modes[3];} //- нормальное напряжение АКБ авто, ACC выключено.                     - Короткая вспышка раз в секунду
  
if (flagAKB == && 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-43 - добавление ячеек памяти в еепром. 
    - добавление нового типа БП BP5.PLUS ( тестовая плата), возможность использовать одну прошивку на разных платах БП. Это деаёт мне возможность поддерживать прошивку даже при устаревании "железа"  
    - считывание показаний с терморезистора и их пересчет в температуру. на BP5.PLUS встроено. На младших версиях - можно допаять.
    - на BP5.PLUS считываем состояние задней передачи и управляем изикапом ( и питанием +12В камеры, если необходимо, брать на входе дсдс изикапа)
m43-46    - на BP5.PLUS  - обработка включения выхода DRLED
    - на BP5.PLUS и BP5 изменена индикация на дисплее 1602. Теперь вместо 01101 выводятся буквы. Не обрабатывается и выводится некоторая информация после тушения подсветки1602 дисплея 
 собственное потребление блока по 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\ . 


Alex15BV 21.07.2019 18:32

Олег, только сейчас внимание обратил... При таком объёмом коде (и, насколько помнится, жалобы на нехватку памяти) - и такой ужас в объявлениях! 16 байт на описание пинов, по байту на однобитный флаг... Что-то как-то странненько, непонятненько... :blush:

oleg707 21.07.2019 19:32

Цитата:

Сообщение от Alex15BV (Сообщение 410825)
Олег, только сейчас внимание обратил... При таком объёмом коде (и, насколько помнится, жалобы на нехватку памяти) - и такой ужас в объявлениях! 16 байт на описание пинов, по байту на однобитный флаг... Что-то как-то странненько, непонятненько... :blush:

Памяти теперь примерно половина свободной, что флеша, что оперативной. :no:
А по 16 байт - там разве компилятор не оптимизирует потом? Код и так очень большой, даже мне трудно его читать ( и это явно не в стандартной ide), поэтому названия сделаны удобночитаемыми и интуитивно понятными.
Более того, у меня там запасные переменные есть по 4 байта, и много:big:, на будущее.
Или ты про что-то попроще, что я упустил?

Alex15BV 21.07.2019 20:59

Нет, именно про это...
1. Выделять память под пины Ардуино - дефайны с теми же именами нисколько не испортят код
2. Булевы переменные под флаги - однобайтные регистры флагов и упаковка по восемь флагов в один регистр. Объявление тех же самых имён, только по биту получится
3. Unsigned long в 4 байта - когда переменная со свистом умещается в unsigned int 2 байта (туда ж 65535 можно запихнуть) ...
... Ну и т. д., и т. п. Вплоть до того, что на черырех байтах и одном прерывании можно таймер на 134 года замутить :big: (ну ли на 255 дней, если честно по 60 считать :blush:)

oleg707 21.07.2019 21:25

Цитата:

Сообщение от Alex15BV (Сообщение 410828)
Нет, именно про это...
1. Выделять память под пины Ардуино - дефайны с теми же именами нисколько не испортят код
2. Булевы переменные под флаги - однобайтные регистры флагов и упаковка по восемь флагов в один регистр. Объявление тех же самых имён, только по биту получится
3. Unsigned long в 4 байта - когда переменная со свистом умещается в unsigned int 2 байта (туда ж 65535 можно запихнуть) ...
... Ну и т. д., и т. п. Вплоть до того, что на черырех байтах и одном прерывании можно таймер на 134 года замутить :big: (ну ли на 255 дней, если честно по 60 считать :blush:)

Твоё кунг-фу сильнее моего :big:
Дай примеры, попробую оптимизировать, чисто из спортивного интереса ( да и поучусь чему новому)

Alex15BV 21.07.2019 22:42

Да я вообще не конфуист! Что ты!
Две одинаковых для текста программы записи:
const LED_PIN = 1; // 1 байт в памяти
#define LED_PIN 1 // ничего

... Или флаги. Восемь байт булевы переменных можно упаковать в одну:
byte FlagRegister1 = 0;
#define PEREM1 FlagRegister1, 0
#define PEREM2 FlagRegister1, 1
#define PEREM3 FlagRegister1, 2
...
#define PEREM8 FlagRegister1, 7

И, соответственно, вводим флаг: bitSet(PEREM1);
сбрасываем: bitClear(PEREM1);

Как-то так...

oleg707 21.07.2019 22:59

Цитата:

Сообщение от Alex15BV (Сообщение 410832)
Да я вообще не конфуист! Что ты!
Две одинаковых для текста программы записи:
const LED_PIN = 1; // 1 байт в памяти
#define LED_PIN 1 // ничего

... Или флаги. Восемь байт булевы переменных можно упаковать в одну:
byte FlagRegister1 = 0;
#define PEREM1 FlagRegister1, 0
#define PEREM2 FlagRegister1, 1
#define PEREM3 FlagRegister1, 2
...
#define PEREM8 FlagRegister1, 7

И, соответственно, вводим флаг: bitSet(PEREM1);
сбрасываем: bitClear(PEREM1);

Как-то так...

ну если с дефайном все ясно, например, в 3Д принтерах в прошивке всё на них и построено, то с битами сложнее. Короче, надо поиграться, чтобы почувствовать.

Alex15BV 21.07.2019 23:20

А уж про задержки/паузы/часы - так тут вообще полет фантазии! Развернуться есть где художнику :big:
Какой самый маленький интервал в программе? Например 1 сек. Настраиваем прерывание от таймера на одну секунду и в прерывании щелкаем счётчиками: от одного простейшего, до многоуровневых "часовых" (секунды, минуты, часы, дни...) - в зависимости от потребностей.
Ну и, допустим, интервал 2 дня 10 часов 25 минут 40 сек:
- заряжаем четыре счётчика и запускаем отсчет
- начинаем заполнять переменную окончания отсчёта в обратном порядке (с дней)
если оттикал дни - bitSet(PAUSE, 0);
часы - bitSet(PAUSE, 1);
минуты...

А в программе сравниваем не "start = millis() - 3456000000",
а PAUSE = 0x0F (это для четырёх счётчиков - 0b00001111)

Alex15BV 21.07.2019 23:34

Цитата:

Сообщение от oleg707 (Сообщение 410833)
ну если с дефайном все ясно, например, в 3Д принтерах в прошивке всё на них и построено, то с битами сложнее. Короче, надо поиграться, чтобы почувствовать.

Что ж тут сложного? Булево - это "истина" / "ложь", то есть 1/0
А это один бит и есть - так зачем на него тратить байт?
Ардуино - восьмибитный контроллер, он байтами оперирует: вот ему в байты и нужно форматировать данные.
Чтобы 8 флагов хранить в памяти - нужна однобайтная переменная. А именовать биты (и уж тем более пины Ардуино) надо только для восприятия кода, его читаемости - а это дефайн делает. Тупо директива компилятору: везде, где увидишь это имя в коде - подставляй вот эту строчку. То есть ты пишешь
digitalWrite(LED_PIN, HIGH), а в прошивке будет digitalWrite(10, HIGH) - но только без лишней переменной

Для флагов то же самое: вместо твоей именованной переменной будет совершенно обычная запись;
bitSet(FlagRegister1, 0) - то есть "установить в лог. единицу нулевой бит переменной FlagRegister 1"

oleg707 21.07.2019 23:37

в общем ПРАКТИКА
если в начале скетча меняем
PHP код:

static byte vkluczic_wywod_dannyh_w_COM_port 0;  // 1- для включения вывода в ком порт для отладки, 0- для вЫключения вывода в ком порт для отладки 

на
PHP код:

#define  vkluczic_wywod_dannyh_w_COM_port 0 

то всё ОК. То есть кидает в ком порт данные при 1 и не кидает при 0.

Но если я пытаюсь заменить
PHP код:

static byte reset_HUB_on_power_on 0

на
PHP код:

 #define reset_HUB_on_power_on  0 

выкидывает ошибку при компиляции
PHP код:


m47
:33errorexpected unqualified-id before numeric constant

  
#define reset_HUB_on_power_on  0

                                 
^

D:\BP_707\5mini_test\m47\m47.ino:121:7notein expansion of macro 'reset_HUB_on_power_on'

  
byte reset_HUB_on_power_on;         // РїРµСЂРµРґС‘ргивать Р»Рё С…аб РїСЂРё РєР°Р¶РґРѕРј РІРєР»СЋС‡РµРЅРёРё Р·Р°Р¶РёРіР°РЅРёСЏ, РґР»СЏ СЂРµС€РµРЅРёСЏ РїСЂРѕР±Р»РµРјС‹ СЃ РѕРїСЂРµРґРµР»РµРЅРёРµРј РёР·РёРєР°РїР° (STK1160) 1 - РїРѕСЃР»Рµ Р’РљР› РђРЎРЎ РІРєР»СЋС‡РёС‚СЊ С…аб, РІС‹РєР»СЋС‡РёС‚СЊ РЅР° 0,5СЃ Рё РІРєР»СЋС‡РёС‚СЊ РѕРїСЏС‚СЊ. 0 - РїСЂРѕСЃС‚Рѕ РІРєР»СЋС‡РёС‚СЊ С…аб.

       
^

In file included from D:\BP_707\5mini_test\m47\m47.ino:194:0:

D:\777\soft\arduino\ARDiSTM\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:43:30warningtype qualifiers ignored on function return type [-Wignored-qualifiers]

     
operator const uint8_t() const       { return **this; }

                              ^

D:\777\soft\arduino\ARDiSTM\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:92:26warningtype qualifiers ignored on function return type [-Wignored-qualifiers]

     
operator const int() const          { return index; }

                          ^

D:\BP_707\5mini_test\m47\m47.inoIn function 'void RABOTA_z_EEPROM()':

m47:628errortoo many initializers for 'myStruct_Znachenija_peremennyh_i_timingov'

 
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia

 
^

D:\BP_707\5mini_test\m47\m47.ino:628:1warningnarrowing conversion of 'HALL_as_power_Switch' from 'byte {aka unsigned char}' to 'float' inside { } [-Wnarrowing]

D:\BP_707\5mini_test\m47\m47.ino:628:1warningnarrowing conversion of 'UaccONorOFF' from 'float' to 'long unsigned int' inside { } [-Wnarrowing]

D:\BP_707\5mini_test\m47\m47.ino:628:1warningnarrowing conversion of 'rezerv20' from 'long unsigned int' to 'float' inside { } [-Wnarrowing]

m47:33errorexpected unqualified-id before numeric constant

  
#define reset_HUB_on_power_on  0

                                 
^

D:\BP_707\5mini_test\m47\m47.ino:638:29notein expansion of macro 'reset_HUB_on_power_on'

 
if (znachenija_polzovatelia.reset_HUB_on_power_on<|| kalibrovkaNOW >= 14)

                             ^

m47:33errorexpected ')' before numeric constant

  
#define reset_HUB_on_power_on  0

                                 
^

D:\BP_707\5mini_test\m47\m47.ino:638:29notein expansion of macro 'reset_HUB_on_power_on'

 
if (znachenija_polzovatelia.reset_HUB_on_power_on<|| kalibrovkaNOW >= 14)

                             ^

m47:33errorexpected unqualified-id before numeric constant

  
#define reset_HUB_on_power_on  0

                                 
^

D:\BP_707\5mini_test\m47\m47.ino:640:75notein expansion of macro 'reset_HUB_on_power_on'

 
reset_HUB_on_power_on                           znachenija_polzovatelia.reset_HUB_on_power_on;

                                                                           ^

exit 
status 1
expected unqualified
-id before numeric constant 

При этом я сэкономил таки немного байт памяти:rofl:
PHP код:

Скетч использует 17106 байт (55%) памяти устройстваВсего доступно 30720 байт

PHP код:

Скетч использует 17310 байт (56%) памяти устройстваВсего доступно 30720 байт


oleg707 21.07.2019 23:44

ладно, пойду хоть порты задефайню ))

практика:big: Найдите 10 отличий. Компилятор всё таки не идиот :rofl:
PHP код:

//PORTB
#define DRLED_pin                           8   //PB0 номер пина, управляющего выходом +12 LED
#define SAMOZAPITKA_Pin                     9   //PB1 номер пина самозапитки блока
#define OTG_Pin                             10  //PB2 номер пина управляющего микросхемой, управляющей режимом OTG
#define HUB_Pin                             11  //PB3 номер пина управляющего транзистором, управляющего Питанием ХАБа
#define SLEEP_Pin                           12  //PB4 номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла) (опционально управление кнопкой питания)
#define LED_Pin                                 13   //PB5 номер пина встроенного светодиода индикации 

против
PHP код:

//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 номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла) (опционально управление кнопкой питания)
#define LED_Pin                                 13   //PB5 номер пина встроенного светодиода индикации 

PHP код:

Скетч использует 17106 байт (55%) памяти устройстваВсего доступно 30720 байт.
Глобальные переменные используют 1014 байт (49%) динамической памятиоставляя 1034 байт для локальных переменныхМаксимум2048 байт

против
PHP код:

Скетч использует 17106 байт (55%) памяти устройстваВсего доступно 30720 байт.
Глобальные переменные используют 1014 байт (49%) динамической памятиоставляя 1034 байт для локальных переменныхМаксимум2048 байт


Alex15BV 22.07.2019 00:21

:big: И это только начало... Оно потянет за собой...
Не ту переменную ты взялся заменять :yes2:
Дело в том, что дефайн ничего не хранит - нет в памяти "reset USB hub after start", есть только воздух, 0 в коде прошивки. А ты переменные сохраняешь в структуру и ЕЕПРОМ. Конечно же он ругается.
А вот FlagRegister1 в моём примере - вот он физический. И при записи в ЕЕПРОМ он будет сохранять актуальные значения восьми флагов сразу...
И текущие состояния из него читаются например:
if (bitRead(PEREM1) == 0) then...

oleg707 22.07.2019 00:45

Цитата:

Сообщение от Alex15BV (Сообщение 410840)
:big: И это только начало... Оно потянет за собой...
Не ту переменную ты взялся заменять :yes2:
Дело в том, что дефайн ничего не хранит - нет в памяти "reset USB hub after start", есть только воздух, 0 в коде прошивки. А ты переменные сохраняешь в структуру и ЕЕПРОМ. Конечно же он ругается.
А вот FlagRegister1 в моём примере - вот он физический. И при записи в ЕЕПРОМ он будет сохранять актуальные значения восьми флагов сразу...
И текущие состояния из него читаются например:
if (bitRead(PEREM1) == 0) then...

Про регистры ... это отдельная тема. Я раньше вообще делал так:
PHP код:

uint8_t  PORTBregistr 0;               // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr 

А потом сразу регистр в порт писал, командами ассемблера. Типа это быстрее, правильнее и вообще по феншую. А потом я решил сделать проект совместимым с СТМ32 :shok::secret:. Думаю продолжать не надо.
Можно по этому же принципу паковать флаги состояний в 8 бит.
Но это надо перепахивать, отлаживать и тестировать код заново, и к тому же он станет еще труднее читаемый.
А по выходу мы будем иметь тот же самый блок питания, но с меньшим потреблением памяти. (На 100 байт?)
При этом больше килобайта свободно вот прямо сейчас.

Про дефайны.
Так в том то и дело, что дефайн тупо заменяет "ИМЯ_ПОСТОЯННОЙ" на присвоенное ему значение при компилировании. Но это же делает компилятор, когда видит const .
А у меня почти все значения переменные, хотя бы потому, что настройки пользователя можно:
а - брать из прошивки
б - писать в ЕЕПРОМ
в - читать из ЕЕПРОМ
Компилятор поэтому и ругается, что конфликт с массивом идёт.
... Хотя ты в принципе это же и написал:yes2: ...

Sultan 03.08.2019 22:23

Здравствуйте. Прочитал всю тему . Так и не понял, батарея выбрасывается или просто блок подключается на мать с установленным АКБ?

oleg707 04.08.2019 11:42

Цитата:

Сообщение от Sultan (Сообщение 411029)
Здравствуйте. Прочитал всю тему . Так и не понял, батарея выбрасывается или просто блок подключается на мать с установленным АКБ?

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

oleg707 27.08.2019 23:34

итак, дошли до меня вот эти юсб провода.
http://pccar.ru/attachment.php?attac...1&d=1563017957
Очень надеялся, что наконец таки появился кабель, который не надо переделывать, а просто подключить к блоку питания.
Но ожидания не оправдались.
прозвонил
красный - +5В 1 пин
белый - юсб дата 2 пин
зеленый - юсб дата 3 пин
черный - масса - 5 пин
синий - видимо экран
ID НЕ ПОДКЛЮЧЕН ( должен был быть- 4 пином)

Такая вот грустная история.
Ищем кабель дальше, в связи с этим повторяю своё старое сообщение.
_________________________________________________
ребят, вопрос. Уже задавался, но внятного ответа нет.
Для нового БП мне нужен кабель отг. То есть полноценно разведенный 5-и проводной кабель с микро юсб.
Паять не сильно хочется ( хотя могу :smile1:)
Есть ли готовые заводские решения?
Или нужно покупать кабель ЮСБ 3,0, потрошить его и припаивать к нему что то типа такого?
https://cdn2.sellbe.com/p27/s-27598/...428/276327.jpg

Есть еще интересная инфа, но на каждое устройство нужно подбирать своё.
Можно ли заряжать активное устройство в режиме OTG?
Да, такой режим предусмотрен разработчиками, но далеко не каждое портативное устройство этот режим поддерживает.
Режим зарядки при работе с периферией называется 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)»

Опять же, меня интересует юсб тип С плюс зарядка. Для телефона вместо планшета в машине.

mazay66 28.08.2019 18:15

Цитата:

Сообщение от oleg707 (Сообщение 411530)
ID НЕ ПОДКЛЮЧЕН ( должен был быть- 4 пином)
Такая вот грустная история.
Ищем кабель дальше

Думается мне, что такой кабель как на фото, сделать не просто, а очень просто. И искать не надо.

oleg707 29.08.2019 00:02

Цитата:

Сообщение от mazay66 (Сообщение 411601)
Думается мне, что такой кабель как на фото, сделать не просто, а очень просто. И искать не надо.

Китайцы продают 0.7$ за кабель ( такой, как на ссылке выше).
За каждый кабель даю 1,5$. Сделаешь?

mazay66 29.08.2019 09:11

Ради сохранения проекта, конечно сделаю. Только зачем врать? Здесь же не лохи. Могут пройти по твоей ссылке выше и посмотреть стоимость кабеля. Она составляет 2,48$ за 2шт, по акции, сейчас можно приобрести за 1,86$. Но, так и быть, сделаю для тебя за 0,7$, надо же дать свет новому проекту. Посмотришь один комплект, как это просто делается. Дальше сам.
P.S. Да, оплата стоимости доставки и проезда до почты твоя, по твоей калькуляции, которую ты делал выше. Думаю, к своей калькуляция вопросов не будет. Тогда пиши адрес отправки, в личку

oleg707 29.08.2019 23:52

Цитата:

Сообщение от mazay66 (Сообщение 411701)
Ради сохранения проекта, конечно сделаю. Только зачем врать? Здесь же не лохи. Могут пройти по твоей ссылке выше и посмотреть стоимость кабеля. Она составляет 2,48$ за 2шт, по акции, сейчас можно приобрести за 1,86$. Но, так и быть, сделаю для тебя за 0,7$, надо же дать свет новому проекту. Посмотришь один комплект, как это просто делается. Дальше сам.
P.S. Да, оплата стоимости доставки и проезда до почты твоя, по твоей калькуляции, которую ты делал выше. Думаю, к своей калькуляция вопросов не будет. Тогда пиши адрес отправки, в личку

:big:Хм, по порядку.
Цитата:

Ради сохранения проекта, конечно сделаю.
1 - Ради сохранения проекта я не просил, я за деньги ( потом вернёмся к этому).
Цитата:

Только зачем врать? Здесь же не лохи. Могут пройти по твоей ссылке выше и посмотреть стоимость кабеля. Она составляет 2,48$ за 2шт, по акции, сейчас можно приобрести за 1,86$.
2 - Врать? Специально зашёл на Али. цена была $ 1.85 на момент заказа. Купил я за 1.74 ( за 2 штуки, хз почему, может купон какой был, может еще какой бонус). Для меня это примерно 1,5$. Акция там нонстопом, что всё равно погоды не делает. Но тут ты меня подловил, я СОВРАЛ:shok: Простите,каюсь,грешен:yes2:
Цитата:

Но, так и быть, сделаю для тебя за 0,7$, надо же дать свет новому проекту.
3 - я благодарен за попытку помочь в моём проекте, потому как почти никто за последние 3 года реально не помогает, только поговорить :pleasantry: Хотя я не отдолжений просил, но так и быть, подумаю.
Цитата:

Посмотришь один комплект, как это просто делается. Дальше сам.
4 - года за 2 до появления каких либо инструкций по изготовлению кабеля я просто взял старый юсб кабель за основу, припаял к нему микроюсб разьем, купленный в соседнем магазине, и получил ОТГ кабель. Который по сей день отлично ездит у меня в машине. Так что как это делается я прекрасно знаю:yes2:
Цитата:

P.S. Да, оплата стоимости доставки и проезда до почты твоя, по твоей калькуляции, которую ты делал выше. Думаю, к своей калькуляция вопросов не будет. Тогда пиши адрес отправки, в личку
5 - к калькуляции вопросов как ни странно нет. В том смысле, что сомневаюсь, что отправить посылку из России в Польшу будет, дешевле чем из Польши в Россию. Не буду специально смотреть, сколько там, примерно 7-10$.

И теперь смотри, считаем.
С твоей точки зрения всё ОК; несмотря на саркастический и, как мне показалось, уничижительный тон сообщения ты действительно вышлешь мне этот кабель. На самом деле спасибо, это уже готовность сделать, а не только поговорить.
С моей точки зрения: В Китае кабель ( правда неподходящий) стоит 1-2$ с доставкой. Максимум доставка 0,7-2$. У тебя заказать кабель ( правда подходящий!) будет стоить примерно 10-11$.

Теперь я хочу рассмотреть временные затраты.
С твоей точки зрения - я не понимаю. Серьёзно. 30 минут спаять кабель. 30-60 минут заполнить и отослать посылку. Итого потери времени 1-1,5 часа. Заработать за 1-1,5ч пускай даже доллар? Для хобби эти затраты времени допустимы, для коммерции - не имеют смысла. Поэтому и не понимаю.
С моей точки зрения - за 30 минут перепаять кабель и "сэкономить" 10-11$ минус материалы - это нормально.
А вот тратить 30 минут ради заработка 1$ (цена кабеля) - это несерьёзно. Даже 3$ - несерьёзно.

У меня то цель была ( и остаётся) найти готовый ОТГ кабель, недорого ( ~2$) . :yes2:
Поэтому предложение реально только для партий кабелей, для штук 10.

PS
Много букв. Не знаю, имели ли смысл, но раз написал, пусть будут. В конце концов это форум, что подразумевает выражение своего мнения и точки зрения.
В любом случае спасибо и добра:drinks:

PPS
вложения не могу делать, потому как неожиданно оказалось, что превышен лимит ( 26 Мб), удалить старые вложения я не могу, а новые жалко - там актуальная и хорошая информация и исходники.
В связи с этим не знаю, как мне выкладывать свежие версии, прошивки и т.п. Буду подумать ))

mazay66 30.08.2019 20:10

Первое - думаю, на написание этого письма, ты потратил больше времени, чем на изготовление одного нужного кабеля.
Второе - Саркастический тон был выбран в ответ на предложение "барина" побатрачить на него, за копейку.
Третье - о коммерции смешно слышать. Партию из 10 блоков будешь продавать не один месяц. Думаю, этого времени на изготовление 10 шт кабелей более чем достаточно.
P.S. Аналогично, с вложениями всё, более ни как. Тоже превышен лимит

oleg707 30.08.2019 20:21

Ага, минут тридцать точно ушло. :)
Про барина - ничего такого не имел в виду. :blush:
Вообще у меня нету разъемов микроюсб, их заказывать надо, поэтому тут вообще вопрос времени, из Китая месяц идти будет.
На самом деле уже что-то надоело искать готовый кабель, придется видимо самому делать, как бы лениво не было.

skanch 31.08.2019 10:43

На мой взгляд, USB-шнурок должен быть не фиксированной длины, а изготавливаться исходя из индивидуальных особенностей установки твоего БП конкретным пользователем. Кто-то поставит блок на крышку планшета-длина 10-15 см., если установка в "бардачке" - 70-90см., а для установки в подлокотник уже надо 1,2-1,5 м. Поэтому нет смысла заранее их делать. Поиск готового шнура вряд ли принесёт результат-никто, кроме энтузиастов не использует автоматическое управление режимом OTG. Другое дело, если искать тонкий качественный экранированный кабель для USB 2.0 с отдельной экранированной data-парой и двумя силовыми проводами внутри для самостоятельного изготовления...

oleg707 31.08.2019 15:58

https://ae01.alicdn.com/kf/HTB1NF2Bf....jpg_50x50.jpg
Micro USB 5Pin полный подключенный Мужской к женскому Удлинительный зарядный кабель для передачи данных с функцией MHL OTG черный и белый 0,1 m-2 m
https://ru.aliexpress.com/item/32867...022ce1333c70d7

Что думаете?

skanch 31.08.2019 19:57

Цитата:

Сообщение от oleg707 (Сообщение 411899)
https://ae01.alicdn.com/kf/HTB1NF2Bf....jpg_50x50.jpg
Micro USB 5Pin полный подключенный Мужской к женскому Удлинительный зарядный кабель для передачи данных с функцией MHL OTG черный и белый 0,1 m-2 m
https://ru.aliexpress.com/item/32867...022ce1333c70d7

Что думаете?

Без экрана будет "глючить".

oleg707 31.08.2019 20:50

Цитата:

Сообщение от skanch (Сообщение 411919)
Без экрана будет "глючить".

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

skanch 31.08.2019 21:01

Самый "безглючный", проверенный неоднократно вариант шнурка USB, когда экранирована именно витая пара с правильным волновым сопротивлением линии в 90 Ом и есть общая плотная оплётка.
На скорости до 480 Мбит/с может работать только кабель с экранированной витой парой для сигнальных линий. По другому никак.

oleg707 31.08.2019 21:30

Цитата:

Сообщение от skanch (Сообщение 411921)
Самый "безглючный", проверенный неоднократно вариант шнурка USB, когда экранирована именно витая пара с правильным волновым сопротивлением линии в 90 Ом и есть общая плотная оплётка.
На скорости до 480 Мбит/с может работать только кабель с экранированной витой парой для сигнальных линий. По другому никак.

до кучи заказал orico, посмотрим что внутри.

skanch 31.08.2019 21:36

Цитата:

Сообщение от oleg707 (Сообщение 411925)
до кучи заказал orico, посмотрим что внутри.

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

Бача 31.08.2019 23:19

Вот похоже оно https://ru.aliexpress.com/item/32531...534b5016ErTgJe Я просто все свои провода покупаю у них.


Часовой пояс GMT +4, время: 08:39.

Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot