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=23236)

Az0m@ 27.11.2017 16:51

Цитата:

Сообщение от Las42kuz (Сообщение 395405)
Скажите а ядро даниэля отвечает за то что бы планшет показывал всегда 100% батареи? И на какую версию его можно поставить? Заранее спасибо!!!

который с обходом батареи показывает всегда 100 процентов

Las42kuz 27.11.2017 20:20

Цитата:

Сообщение от oleg707 (Сообщение 395444)
в ядре Даниэля всё расписано.

Стоковое ядро с поддержкой USB-аудио, easycap STK1160 для Android 4.4.4
Стоковое ядро с поддержкой USB-аудио, easycap STK1160 и обходом контроллера батареи для Android 4.4.4
Стоковое ядро с поддержкой USB-аудио, easycap для Android 5.1
и так далее.
Для 7-12 и 7-13 естественно раздельно.
На данный момент я вообще не уверен, стоит ли его менять. На стоке или на любой другой прошивке всё должно работать ( вопрос только в драйверах, чтобы ядро видело периферию)

Олег спасибо за ответ! У меня вот проблема ни как не могу определить почему Нексус 13 отключается! Подключён через преобразователь kis3r33 без контроллера и батареи, уходит в сон через датчик холла через релейный модуль ! К планшету подключён хаб с питанием от пребразователя lm2596s на у- кабеле убрал + который идёт в планшет, в хаб подключены ардуйно, изикап, pcm2704, и одна флешка! Помогите советом что я не правильно сделал? Почему он вырубается?

oleg707 27.11.2017 21:00

Цитата:

Сообщение от Las42kuz (Сообщение 395495)
Олег спасибо за ответ! У меня вот проблема ни как не могу определить почему Нексус 13 отключается! Подключён через преобразователь kis3r33 без контроллера и батареи, уходит в сон через датчик холла через релейный модуль ! К планшету подключён хаб с питанием от пребразователя lm2596s на у- кабеле убрал + который идёт в планшет, в хаб подключены ардуйно, изикап, pcm2704, и одна флешка! Помогите советом что я не правильно сделал? Почему он вырубается?

Да вроде бы должно работать с первого взгляда; наберите меня в вайбер или whatsApp, голосом обсудим. Будет быстрее, чем писать. +375293девять52семь87.

Las42kuz 27.11.2017 21:16

Цитата:

Сообщение от oleg707 (Сообщение 395496)
Да вроде бы должно работать с первого взгляда; наберите меня в вайбер или whatsApp, голосом обсудим. Будет быстрее, чем писать. +375293девять52семь87.

Можно завтра наберу вечером?

oleg707 27.11.2017 21:37

Цитата:

Сообщение от Las42kuz (Сообщение 395497)
Можно завтра наберу вечером?

ок, напиши и потом созвонимся.

oleg707 30.11.2017 03:07

тестовая версия, на железе не проверял
 
PHP код:

byte ver 19;// ( чем больше цифра, тем новее)
// дата правки 30.11.17.202

// для 5mini версии блока питания. 
// скетч проверен и записан на версии ардуино IDE 1,8,1 win7, 1.63 xp
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например  d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\  https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64  Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master  https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
/* _
хотелки


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

 собственное потребление блока по 12 вольтам, без планшета 
                                                    - при 10В +30 и +15 выключены                              = 0,02 А  
                                                    - при 12В +30 и +15 включены                               = 0,092-0,1 А
                                                    - при 12В +30 включены +15 выключены (при питании батареи) = 0,06А
________________________________________________________________
поведение встроенного светодиода
    низкое напряжение АКБ авто                                         - коротко моргает
    нормальное напряжение АКБ авто, ACC выключено.                     - быстро моргает
    нормальное напряжение, включено ACC, рабочий режим.                - медленно моргает 


ПРИМЕЧАЕНИЯ
->  strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так:  strcpy(strokaIIold,strokaII); // копируем новую строку в старую 
*/ 
//***************************************************************************************************************************************************
// Массив режимов работы светодиода
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 <Wire.h> // для экрана - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для экрана 
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char     strokaI[32] = "                ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char    strokaII[32] = "                ";// Массив для вывода 2 строки на дисплей

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


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

LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A014561611121314POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347

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

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

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

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

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

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


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

const boolean reset_HUB_on_power_on 0// передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.


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

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

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
 
  
float Uperezariadki 15.5;              //напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
  
float UrabotyREM 11.8;                 //напряжение, выще которого будет работать усилитель звука, если акб не садился.
  
float UnevykluczeniaREM 13.7;          // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
  
float Uakb_Kogda_ACC_vYkluczeno 11.9;  // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
  
float Uakb_Kogda_ACC_vkluczeno 11.1;   // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
  
float UaccONorOFF 11.4;                // напряжение порога сработки асс.  Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,4), то зажигание будет считаться выключенным.
 
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
  
//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем  
//соответствующий пин блока питания (время независимо друг от друга)
const unsigned long  PlanshBAT_timer_pri_vkl_ACC 1100;// пауза  после включения ACC перед включением питания на батарею планшета
const unsigned long  II_KIW_pin_POGO_timer_pri_vkl_ACC 1400;// пауза  после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ) 
const unsigned long  OTG_timer_pri_vkl_ACC 50;// пауза  после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете)  (включается определение ЮСБ перифирии планшетом.)
const unsigned long  HUB_timer_pri_vkl_ACC 2100;// пауза  после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно II_KIW_pin_POGO_timer_pri_vkl_ACC.
const unsigned long  REGISTRATOR_timer_pri_vkl_ACC 2500;// пауза  после включения ACC перед включением  питания +12В на видеорегистратор
const unsigned long  REM_timer_pri_vkl_ACC 2500;// пауза  после включения ACC перед включением  питания +12В на REM (включение усилителя звука)
const unsigned long  SLEEP_timer_pri_vkl_ACC 3000// пауза  после включения ACC перед включением экрана

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

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


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






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




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

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

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

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



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

 
  

  
Serial.begin(115200);
lcd.begin(162); //инициализация дисплея 1602 для newE библиотеки
if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию  
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию  =127

// настройки портов  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~   
 
DDRD 0b11010100//работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*  
  pinMode(2, OUTPUT);         //bool II_KIW_pin_POGO = 0;   //byte II_KIW_pin_POGOpin = 2;   32pin = PD2 = pin D2         включить 2 канал KIW    управление SS2 выходом питания  +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
  pinMode(4, OUTPUT);         //bool REGISTRATOR = 0;   //byte REGISTRATORpin = 4;  2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
  pinMode(5, INPUT);          //pinMode(STATEpinI, INPUT);
  pinMode(6, OUTPUT);         //pinMode(PlanshBATpin, OUTPUT);   16pin = PB4 = pin D12 MISO
  pinMode(7, OUTPUT);         //bool REM = 0; //byte REMpin = 7;           11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
  */
   //ПРИМЕР DDRB = 0b00100010;// pinMode(13, OUTPUT); pin9 =OUT       //DDRx - регистр направления передачи данных светодиодик на плате ардуины
 
 
DDRB   0b00111110//работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  /*
  pinMode(8, INPUT);          //pinMode(STATEpinII, INPUT);
  pinMode(9, OUTPUT);         //pinMode(SAMOZAPITKApin, OUTPUT); 13pin = PB1 = pin D9
  pinMode(10, OUTPUT);        // pinMode(SLEEPpin, OUTPUT);
  pinMode(11, OUTPUT);        //byte HUBpin = 11; // PB3 
  pinMode(12, OUTPUT);        //bool OTG = 0; //byte OTGpin = 12;  16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
  pinMode(13, OUTPUT);        //светодиодик на плате ардуины
 */
  //digitalWrite(5, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPinsdigitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
  //digitalWrite(8, 1);  
 
pinMode(PINkalibrovkiINPUT);  // пин калибровки
 
digitalWrite(PINkalibrovki1); // подтяжка +5 пина калибровки
  
// конец настроек портов  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

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

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

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

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

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

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

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


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


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

if (kalibrovkaNOW >= && kalibrovkaNOW 255 )// если активен режим калибровки, то выводим данные для калибровки.
                      
{
                       
sprintf (strokaI,"                ") ; 
                       
IntToCharIII(Uacc,  &strokaI[0]);
                       
IntToCharIII(Uakb,  &strokaI[4]);
                       
IntToCharIII(kalibrovkaNOW, &strokaI[7]);  // вывод РЕЖИМА калибровки 
                       
                       
sprintf(strokaII,"c               ") ;
                       
IntToCharIII(kalibrovkaACC, &strokaII[1]);  // вывод значения калибровки АСС 
                       
IntToCharIII(kalibrovkaAKB, &strokaII[5]);  // вывод значения калибровки АСС 
                       
                       
FloatToCharIIIII (U_acc_real,  &strokaI[11]); // вывод напряжения АКБ
                       
FloatToCharIIIII (U_akb_real,  &strokaII[11]); // вывод напряжения АКБ

                      
}

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



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

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


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

                                                          
display2.display();             //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
      
}//void displayDataToDISPLAY()
 /******************************************конец индикации светодиодом и  вывода на дисплей********************************************************************************************************************************************************************************/
                                    

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

void analogReadU (byte averageFactor//функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
  
int newUacc analogRead(PINrawACC);
  
int newUakb analogRead(PINrawAKB); 
 
   if (
averageFactor 0)        // усреднение показаний для устранения "скачков"
  
{      
    
Uacc = (Uacc * (averageFactor 1) + newUacc) / averageFactor;  
    
Uakb = (Uakb * (averageFactor 1) + newUakb) / averageFactor;  
    
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
  
} else {
    
Uakb=newUakb// не делаем усреднений, что прочитали то и считаем выводом
    
Uacc=newUacc// не делаем усреднений, что прочитали то и считаем выводом
  
}


}
//void analogReadU

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

}
//void rejim_kalibrovki()




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

    
if (U_akb_real >= UrabotyREM && flagACC == && 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 loop()
{while (
1){//для ускорения void loop
           
analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

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



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


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении  и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if ( (millis() > pauseTimeHALL && flagHALL == )|| ((millis() > 15000) && flagACC == 1)) 
  {
flagHALL 1;} /*проверка отсчета при холодном старте при включении  и сразу выключении ACC*/
  /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if ((U_akb_real U_acc_real) >=)/*проверка, выключили ли мы зажигание или просто стартуем (1 - выключили заж, 0 - стартуем), нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
          
{timeAfterACC timeAfterACC_accOFF;} //выключили зажигание /*  1000       1 - выключили зажигание.  ЕСЛИ +15 ПРОПАДАЕТ ВО ВРЕМЯ СТАРТА, ТО ВМЕСТО 500 НАДО 5000 или вообще убрать этот блок if-else.*/
          
else {timeAfterACC timeAfterACC_starting;     if (U_akb_real <=UakbONorOFF) {flagREM 3;REM 0;}   }//стартуем  /* 5000  0 - заводим машину (стартуем) или сел акб при включенном зажигании.*/ Логика работы REM в 537 строках 
         
if (U_akb_real >= Uperezariadki){timeAfterACC 0;}
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


  //  ------------========================== блок ACC ========================-----------------------------------------------------------------------------


  //             -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============---------------- 
  
if ((Uperezariadki U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == && flagAKB == //проверка напруги АСС и АКБ при флаге ACC = 0
  
{
    
flagACC 1;
    
pauseTimeACC millis();
    
pauseTimeAKB millis();
    
//lcd.clear(); //очистка экрана не нужна со строковым выводом
    
display2.begin(SSD1306_SWITCHCAPVCC0x3C);  // display 2 or adres 0x3D для 1306 дисплея
    
lcd.begin(162); //инициализация дисплея 1602 для newE библиотеки
    
display2.clearDisplay();        // для 1306 дисплея
    
display2.setTextColor(WHITE);   // для 1306 дисплея
  
}


if (
flagACC ==)
{
// если flagACC == 1

  
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 >= II_KIW_pin_POGO_timer_pri_vkl_ACC /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
        
{
          
II_KIW_pin_POGO 1;  //digitalWrite(II_KIW_pin_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 (
millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC // пауза  после включения ACC и потом делать следующ(пока включено ACC):
        
{
          
SLEEP 0//digitalWrite(SLEEPpin, 0); /*включаем экран*/
        
}
        
}
// если flagACC == 1

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

    


  //-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------

  
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) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) ) 
                                                    {
                                                        if (
flagHALL == 1)
                                                            {
                                                            
SLEEP 1;//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
                                                            
}
                                                            else
                                                         {
SLEEP 0;}//{digitalWrite(SLEEPpin, 0);}
                                                    
}
    if ( ((
millis() - pauseTimeACC) >=  (OTG_timer_pri_vykl_ACC+timeAfterACC))  ) /* 3000 пауза 3с чтобы не пукал усилитель*/
                                                            
{
                                                            
OTG 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/
                                                           
                                                            
}
 if ( ((
millis() - pauseTimeACC) >=  (II_KIW_pin_POGO_timer_pri_vykl_ACC+timeAfterACC))  ) 
                                                            {
                                                            
II_KIW_pin_POGO 0;//digitalWrite(II_KIW_pin_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 (flagACC==0)
   

  //  -------------------------========================= блок АКБ ==========================-------------------------------------------------------------------------------


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с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
    
{
      
PlanshBAT 0;          //digitalWrite(PlanshBATpin, 0);       /*вЫключаем питание на батарею планшета */
      
OTG 0;                //digitalWrite(OTGpin, 0);             /*вЫключаем минус на OTG )*/
      
II_KIW_pin_POGO 0;    //digitalWrite(II_KIW_pin_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, система ПОЛНОСТЬЮ обесточивается*/
      //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))     (самозапитка для регистратора, процессор БП активен)*/
      
REGISTRATOR 0//digitalWrite(REGISTRATORpin, 0);       /* выключаем питание  на видеорегистратор*/
        
SAMOZAPITKA 0;  //digitalWrite(SAMOZAPITKApin, 0);      /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
        
UPRAVLENIE_PINAMI(); 
        
delay (10000);              /* задержка для аппаратного выключения*/
      
}
  }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений  АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

 

/*
// ******************************************отслеживания аварийной ситуации ITS716G (превышение по току по выходам out1-4)********************************************************************************************************************************************************************************
   
      
    // *отслеживания аварийной ситуации ITS716G канал 1 (питание KIW3312s-out2 и регистратор-out1) 0 = норма  1 = авар. сит.  //тогда моргаем 13 ногой код "1"
    // *отслеживания аварийной ситуации ITS716G канал 2 (выход REM-out3 и самозапитка БП-out4 )0 = норма  1 = авар. сит.  //тогда моргаем 13 ногой  код "2"
  
    if(SAMOZAPITKA==1 || PlanshBAT ==1 ||REM==1 || REGISTRATOR ==1) // если проц включал любой канал ITS
              {
                
                
                STATEpinI =  digitalRead(5); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        STATEpinII = digitalRead(8);  
                if(STATEpinI == 0)             {   // и если пин защиты STATEpinI показал аварию
                                                                                                             for (int i=0; i <= 300; i++)   { //тогда моргаем 13 ногой код "1"  10 минут, если они прошли и асс ВКЛ, тогда еще раз и еще по кругу, пока неисправность не уйдёт
                                                                                                                                           LED = 1; UPRAVLENIE_PINAMI(); delay(500); LED = 0; UPRAVLENIE_PINAMI(); delay(1493);
                                     PlanshBAT = 0;         //digitalWrite(PlanshBATpin, 0);  //вЫключаем питание на батарею планшета (in2)
                                     OTG = 0;               //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
                                     II_KIW_pin_POGO = 0;   //digitalWrite(II_KIW_pin_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, система ПОЛНОСТЬЮ обесточивается
                                     wdt_reset();           //Сброс таймера watchdog
                                                                                                                                           }
                                   } ;
    if(STATEpinII == 0)             {   // и если пин защиты STATEpinII показал аварию
                                                                                                             for (int i=0; i <= 150; i++)   { //тогда моргаем 13 ногой ногой код "2" 10 минут, если они прошли и асс ВКЛ, тогда еще раз и еще по кругу, пока неисправность не уйдёт
                                                                                                                                           LED = 1; UPRAVLENIE_PINAMI();  delay(500); LED = 0; UPRAVLENIE_PINAMI();delay(493); LED = 1; UPRAVLENIE_PINAMI();  delay(500); LED = 0; UPRAVLENIE_PINAMI();  delay(1493);
                                     PlanshBAT = 0;         //digitalWrite(PlanshBATpin, 0);  //вЫключаем питание на батарею планшета (in2)
                                     OTG = 0;               //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
                                     II_KIW_pin_POGO = 0;   //digitalWrite(II_KIW_pin_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, система ПОЛНОСТЬЮ обесточивается
                                     wdt_reset();           //Сброс таймера watchdog
                                                                                                                                           }
                                   } ;
                               }

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

/******************************************индикация светодиодом и задержка вывода на дисплей********************************************************************************************************************************************************************************/
   
ms millis();
  
// Событие срабатывающее каждые 125 мс
  
if ( ( ms ms1 ) > 125 || ms ms1 ) {
    
ms1 ms;
    
// Режим светодиода ищем по битовой маске
    
if (  blink_mode << (blink_loop 0x07) ) {LED 1;}
    else { 
LED 0;}
    
blink_loop++;
  }
  
  
  
  
   
// Событие срабатывающее каждые 350 мс
  
if ( ( ms pauseDisplay ) > 350 || ms pauseDisplay )
  { 
   
pauseDisplay ms;
   
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
  
}

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

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

UPRAVLENIE_PINAMI(); 

//wdt_reset(); /*Сброс таймера watchdog*/

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


oleg707 01.12.2017 21:21

Нашел критический баг в программе BP5mini - что-то смещает значение в переменной вывода портов (PORTBregistr) Пропадает последний байт.
Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI - работает, как ожидаемо.
Обнаружил случайно - БП не прошел тест на полное отключение при низком напряжении. Процессор всё равно оставался активным, хотя перифирию аварийно отключал.

На столе работает. На машине - потом отпишусь.
PHP код:

byte ver 24;// ( чем больше цифра, тем новее)
byte TipBlokaPitania 255// 177 - BP7. 255 - BP5mini //выбор типа блока питания.
// дата правки 2.12.17.0028

// для 5mini версии блока питания. 
// скетч проверен и записан на версии ардуино IDE 1,8,1 win7, 1.63 xp
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например  d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\  https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64  Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master  https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
/* _
хотелки


______Сделано__________________________________________________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C,  библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C  и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 100 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволило выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска,  15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
                   Без 2х библиотек одновременно работать не будет                    https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилок)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)  
                        выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания - 318 строка
t08- ничего
t09 - перенесена строка  проверки заведённой авто, в конец, перед проверкой перезаряда. 
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM 
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13  поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания.  24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000) 
                               timeUntilALLOff = время до полного выключение блока,  после выключения зажигания (ACC)  ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
      увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)    
                           
m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал).  Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию                           
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой.    //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. 
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные.  Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено.  не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI.
________________________________________________________________ 

 собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
                                                    - при 10В +30 и +15 выключены                              = 0,022 А  
                                                    - при 12В +30 и +15 включены                               = 0,06 А
                                                    - при 12В +30 включены +15 выключены (при питании батареи) = 0,03А
________________________________________________________________
поведение встроенного светодиода
    низкое напряжение АКБ авто                                         - коротко моргает
    нормальное напряжение АКБ авто, ACC выключено.                     - быстро моргает
    нормальное напряжение, включено ACC, рабочий режим.                - медленно моргает 


ПРИМЕЧАЕНИЯ
->  strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так:  strcpy(strokaIIold,strokaII); // копируем новую строку в старую 
*/ 
//***************************************************************************************************************************************************
// Массив режимов работы светодиода
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 <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея 
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char     strokaI[32] = "                ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char    strokaII[32] = "                ";// Массив для вывода 2 строки на дисплей

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


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

LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A014561611121314POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347

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

//PORTB
const byte SAMOZAPITKA_Pin                    9;   // номер пина самозапитки блока
const byte LED_Pin                            13;  // номер пина встроенного светодиода индикации 
const byte OTG_Pin                            10;  // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin                            11;  // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin                          12;  // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)
 
//PORTD
const byte PlanshBAT_Pin                      6;  // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin                    4;  // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin   2;  // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin                            7;  // номер пина управляющего транзистором, управляющего Питанием ХАБа
 
 
/*ноги ардуины логические*/
    
uint8_t  PORTBregistr 0;               // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA 0;                     // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED 0;                             // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0;                             //byte SLEEPpin = 10; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
boolean HUB 0;                             //byte HUBpin = 11;  0-хаб вЫключен, 1 - хаб включен
boolean OTG 0;                             //byte OTGpin = 12; //1 = есть масса на OTG; 0 = нет массы на OTG

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

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

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

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


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

const boolean reset_HUB_on_power_on 1// передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
  
float Uperezariadki 15.5;              // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
  
float UrabotyREM 11.8;                 // напряжение, выше которого будет работать усилитель звука, если акб не садился.
  
float UnevykluczeniaREM 13.7;          // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
  
float Uakb_Kogda_ACC_vYkluczeno 11.9;  // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
  
float Uakb_Kogda_ACC_vkluczeno 11.1;   // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
  
float UaccONorOFF 10.1;                // напряжение порога сработки асс.  Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
  
/*счётчики времени*/
  //НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!
  
 
const unsigned long timeUntilBATOff 345600000;                     // время до выключения питания на батарею планшета после выключения зажигания., если прошло 48 часов, как выключили ACC // пауза  (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
 
const unsigned long timeUntilALLOff 172800000 timeUntilBATOff;   // время до полного выключение блока,  после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета    ) (2суток = 172800000)) (4суток = 345600000)
 
unsigned long timeBeforeRemOff 1800000;                            // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку,  при нормальном АКБ)

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

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

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

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


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






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




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

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

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



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

 
  

  
Serial.begin(115200);

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

// настройки портов  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~   
 
DDRD 0b11010100//работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*  
  pinMode(2, OUTPUT);         //bool FIVE_Volt_OUT_na_POGO_or_USB = 0;   //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2;   32pin = PD2 = pin D2         включить 2 канал KIW    управление SS2 выходом питания  +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
  pinMode(4, OUTPUT);         //bool REGISTRATOR = 0;   //byte REGISTRATORpin = 4;  2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
  pinMode(5, INPUT);          //pinMode(STATEpinI, INPUT);
  pinMode(6, OUTPUT);         //pinMode(PlanshBATpin, OUTPUT);   16pin = PB4 = pin D12 MISO
  pinMode(7, OUTPUT);         //bool REM = 0; //byte REMpin = 7;           11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
  */
   //ПРИМЕР DDRB = 0b00100010;// pinMode(13, OUTPUT); pin9 =OUT       //DDRx - регистр направления передачи данных светодиодик на плате ардуины
 
 
DDRB   0b00111110//работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  /*
  pinMode(8, INPUT);          //pinMode(STATEpinII, INPUT);
  pinMode(9, OUTPUT);         //pinMode(SAMOZAPITKApin, OUTPUT); 13pin = PB1 = pin D9
  pinMode(10, OUTPUT);        // pinMode(SLEEPpin, OUTPUT);
  pinMode(11, OUTPUT);        //byte HUBpin = 11; // PB3 
  pinMode(12, OUTPUT);        //bool OTG = 0; //byte OTGpin = 12;  16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
  pinMode(13, OUTPUT);        //светодиодик на плате ардуины
 */
  //digitalWrite(5, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPinsdigitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
  //digitalWrite(8, 1);  
 
pinMode(PINkalibrovkiINPUT);  // пин калибровки
 
digitalWrite(PINkalibrovki1); // подтяжка +5 пина калибровки
  
// конец настроек портов  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

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

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

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

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

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

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

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


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


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

if (kalibrovkaNOW >= && kalibrovkaNOW 255 )// если активен режим калибровки, то выводим данные для калибровки.
                      
{
                       
sprintf (strokaI,"                ") ; 
                       
IntToCharIII(Uacc,  &strokaI[0]);
                       
IntToCharIII(Uakb,  &strokaI[4]);
                       
IntToCharIII(kalibrovkaNOW, &strokaI[7]);  // вывод РЕЖИМА калибровки 
                       
                       
sprintf(strokaII,"c               ") ;
                       
IntToCharIII(kalibrovkaACC, &strokaII[1]);  // вывод значения калибровки АСС 
                       
IntToCharIII(kalibrovkaAKB, &strokaII[5]);  // вывод значения калибровки АСС 
                       
                       
FloatToCharIIIII (U_acc_real,  &strokaI[11]); // вывод напряжения АКБ
                       
FloatToCharIIIII (U_akb_real,  &strokaII[11]); // вывод напряжения АКБ

                      
}

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



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

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


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

                                                          
display2.display();             //эта строка выводит картинку 1306 из буфера на экран!
//Вывод строк окончен.______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
      
}//void displayDataToDISPLAY()
 /******************************************конец индикации светодиодом и  вывода на дисплей********************************************************************************************************************************************************************************/
                                    

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

void analogReadU (byte averageFactor//функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
  
int newUacc analogRead(PINrawACC);
  
int newUakb analogRead(PINrawAKB); 
 
   if (
averageFactor 0)        // усреднение показаний для устранения "скачков"
  
{      
    
Uacc = (Uacc * (averageFactor 1) + newUacc) / averageFactor;  
    
Uakb = (Uakb * (averageFactor 1) + newUakb) / averageFactor;  
    
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5 я тут немного поправил
  
} else {
    
Uakb=newUakb// не делаем усреднений, что прочитали то и считаем выводом
    
Uacc=newUacc// не делаем усреднений, что прочитали то и считаем выводом
  
}


}
//void analogReadU

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

}
//void rejim_kalibrovki()




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

    
if (U_akb_real >= UrabotyREM && flagACC == && 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 loop()
{while (
1){//для ускорения void loop
           
analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(5)раз.

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



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


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении  и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if ( (millis() > pauseTimeHALL && flagHALL == )|| ((millis() > 15000) && flagACC == 1)) 
  {
flagHALL 1;} /*проверка отсчета при холодном старте при включении  и сразу выключении ACC*/
  /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if ((U_akb_real U_acc_real) >=)/*проверка, выключили ли мы зажигание или просто стартуем (1 - выключили заж, 0 - стартуем), нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
          
{timeAfterACC timeAfterACC_accOFF;} //выключили зажигание /*  1000       1 - выключили зажигание.  ЕСЛИ +15 ПРОПАДАЕТ ВО ВРЕМЯ СТАРТА, ТО ВМЕСТО 500 НАДО 5000 или вообще убрать этот блок if-else.*/
          
else {timeAfterACC timeAfterACC_starting;     if (U_akb_real <=UakbONorOFF) {flagREM 3;REM 0;}   }//стартуем  /* 5000  0 - заводим машину (стартуем) или сел акб при включенном зажигании.*/ Логика работы REM в 537 строках 
         
if (U_akb_real >= Uperezariadki){timeAfterACC 0;}
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


  //  ------------========================== блок 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)  //как только включили зажигание ( при любом напряжении батареи)


 if (
millis() - pauseTimeACC >= I_dva_C_szina_ON_time /* пауза XXX=I_dva_C_szina_ON_timec после появления напряжения на ACC и потом делать следующ(пока включено ACC):*/
        
{
            if (
rezreszenie_raboty_I_dva_C_sziny  == 0// переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали. 
      

             
//lcd.clear(); //очистка дисплея не нужна со строковым выводом
               
lcd.begin(162); //инициализация дисплея 1602 для newE библиотеки
         
sprintf(strokaI,"    INIT OK     ") ;
         
lcd.setCursor(00);
               
lcd.print(strokaI);
               
display2.begin(SSD1306_SWITCHCAPVCC0x3C);  // display 2 or adres 0x3D для 1306 дисплея
               
display2.clearDisplay();        // для 1306 дисплея
               
display2.setTextColor(WHITE);   // для 1306 дисплея
      // ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! 
      
}
      
rezreszenie_raboty_I_dva_C_sziny  1// разрешаем работу шины I2C 
      
        
}
               
        
// конец как только включили зажигание ( при любом напряжении батареи)
//} не нужна скобка


if (flagACC ==)
{
// если flagACC == 1

    
  
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
        
{
         
PlanshBAT 1;        //digitalWrite(PlanshBATpin, 1);  /*включаем питание на батарею планшета  = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/ 
        
}
  
  if (
millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
        
{
          
FIVE_Volt_OUT_na_POGO_or_USB 1;  //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
        
}
  
if (
millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
       
{
         
OTG 1;              //digitalWrite(OTGpin, 1); /*включаем минус на OTG  (включается определение перифирии планшетом.)*/
       
}

if (
millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
       
{
         
HUB 1;               //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
       
}
                  
  if (
reset_HUB_on_power_on == 1)
  {
                  if (
millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
                         
{
                           
HUB 0;               //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
                         
}
                         
                  if (
millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
                         
{
                           
HUB 1;               //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзюк хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
                         
}
  }
       
  if (
millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем:  */
        
{
          
REGISTRATOR 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание  на видеорегистратор*/
          
if (millis() < 15000)  {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
      
if( flagREM == 1  && flagAKB == ){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 (
millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC // пауза  после включения ACC и потом делать следующ(пока включено ACC):
        
{
          
SLEEP 0//digitalWrite(SLEEPpin, 0); /*включаем экран*/
        
}
        
}
// если flagACC == 1

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

    


  //-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
   
//if (U_acc_real < UaccONorOFF) 

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

                                                            
  
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) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) ) 
                                                    {
                                                        if (
flagHALL == 1)
                                                            {
                                                            
SLEEP 1;//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
                                                            
}
                                                            else
                                                         {
SLEEP 0;}//{digitalWrite(SLEEPpin, 0);}
                                                    
}
    if ( ((
millis() - pauseTimeACC) >=  (OTG_timer_pri_vykl_ACC+timeAfterACC))  ) /* 3000 пауза 3с чтобы не пукал усилитель*/
                                                            
{
                                                            
OTG 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/
                                                           
                                                            
}
    if ( ((
millis() - pauseTimeACC) >=  (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+timeAfterACC))  ) 
                                                            {
                                                            
FIVE_Volt_OUT_na_POGO_or_USB 0;//digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
                                                            
}
 
    if ( ((
millis() - pauseTimeACC) >=  (HUB_timer_pri_vykl_ACC+timeAfterACC))  ) 
                                                            {
                                                             
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
                                                            
}
                                                                                                                        
              
  if ( ((
millis() - pauseTimeACC) >=  (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC))  ) 
                                                            {
                                                            
lcd.noBacklight();// тушим подсветку дисплея для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея 
                                                            
}
                              
                              
    if  ( ((
millis() - pauseTimeACC) >=  (I_dva_C_szina_OFF_time timeAfterACC ))  && (rezreszenie_raboty_I_dva_C_sziny  == 1) )  //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
                                                            

                                                            
lcd.clear(); //очистка дисплея 
                                                            
rezreszenie_raboty_I_dva_C_sziny  0//запрещаем работу I2C шины
                                                            // ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !    
                                                            
}                              

                                                            
 }
// if (flagACC==0)
   

  //  -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------


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

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

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

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

        
PlanshBAT 0;                                            // digitalWrite(PlanshBATpin, 0);  /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
      
}

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

 



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

 
/*настраиваем режимы моргания встроенного светодиода ардуины*/  
  
if (blink_mode != modes[5] || blink_mode != modes[5]) 
  {
  if (
flagAKB == ){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[1];} // режим калибровки
      
  

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



//Serial.print ("HUB = "  ); Serial.println (HUB); 

UPRAVLENIE_PINAMI(); 



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


oleg707 02.12.2017 18:55

на машине - день - полет нормальнй m24

strangle 06.12.2017 18:26

Не много не по теме. Но подскажите, знатоки KIW-3312S. Как им управлять, если без наворотов. Чтобы 1 канал работал напрямую от АКБ, а второй канал включался только при появлении ACC?
БП автора, без ардуино, по-моему для меня немного избыточен

oleg707 06.12.2017 22:17

Цитата:

Сообщение от strangle (Сообщение 396060)
Не много не по теме. Но подскажите, знатоки KIW-3312S. Как им управлять, если без наворотов. Чтобы 1 канал работал напрямую от АКБ, а второй канал включался только при появлении ACC?
БП автора, без ардуино, по-моему для меня немного избыточен

на KIW-3312S есть выходы ss1 и ss2. Подав на этот выход массу мы выключаем канал.
Дальше объяснять нужно?

strangle 07.12.2017 06:58

oleg707, нет, спасибо, я даташит читал, в курсе.
Просто предположил, что есть способ по аналогии с 3R33S, управляя "плюсом"

skanch 07.12.2017 08:27

Цитата:

Сообщение от strangle (Сообщение 396094)
...Просто предположил, что есть способ по аналогии с 3R33S, управляя "плюсом"

Ничего не мешает управлять через Mosfet-ключ.

jonikus81 07.12.2017 14:33

Цитата:

Сообщение от skanch (Сообщение 396096)
Ничего не мешает управлять через Mosfet-ключ.

или даже оптрон
кстати ищу миниатюрные оптроны, кто что посоветует?

skanch 07.12.2017 14:41

Цитата:

Сообщение от jonikus81 (Сообщение 396113)
или даже оптрон
кстати ищу миниатюрные оптроны, кто что посоветует?

Лучше mosfet в корпусе SOT-23 . Или твердотельное реле. Достаточно мелко...

oleg707 07.12.2017 15:18

Цитата:

Сообщение от skanch (Сообщение 396096)
Ничего не мешает управлять через Mosfet-ключ.

а зачем? достаточно же ( и проще) EN на землю завести. Или + 12в с АСС брать, потом через делитель на EN. Только если для защиты по току ставить интеллектуальный ключ.

skanch 07.12.2017 15:42

Цитата:

Сообщение от oleg707 (Сообщение 396115)
а зачем? достаточно же ( и проще) EN на землю завести. Или + 12в с АСС брать, потом через делитель на EN. Только если для защиты по току ставить интеллектуальный ключ.

Если управлять только по линии "АСС", то делителя достаточно, но если управлять от контроллера, то развязка в виде mosfeta только приветствуется. Это мое мнение, а так - вариантов масса...

oleg707 07.12.2017 16:31

Вложений: 1
Цитата:

Сообщение от skanch (Сообщение 396118)
Если управлять только по линии "АСС", то делителя достаточно, но если управлять от контроллера, то развязка в виде mosfeta только приветствуется. Это мое мнение, а так - вариантов масса...

если взять, например, из даташита на MP1584

Enable Control
The MP1584 has a dedicated enable control pin
(EN). With high enough input voltage, the chip
can be enabled and disabled by EN which has
positive logic. Its falling threshold is a precision
1.2V, and its rising threshold is 1.5V (300mV
higher).
When floating, EN is pulled up to about 3.0V by
an internal 1μA current source so it is enabled.
To pull it down, 1μA current capability is needed.
When EN is pulled down below 1.2V, the chip is
put into the lowest shutdown current mode.
When EN is higher than zero but lower than its
rising threshold, the chip is still in shutdown
mode but the shutdown current increases
slightly.
Вложение 48783
То есть напряжение сработки ниже 5 В ( но толерантно), ток вообще никакой, так зачем в схеме лишний элемент?
Тут только один момент. Когда ардуина выключена ( процессор без питания), то на ножках ардуины, бывает, начинает гулять наводки (0,5-2В), особенно где нет нагрузки на массу.
Тогда у меня было, что ардуина может открыть полевик, например. Приходилось ставить еще один транзистор, для развязки.
В случае с управляющим пином step-down преобразователя, как вариант, такое тоже может быть, но достаточно будет подтянуть EN на массу резистором.
Хотя размеры дополнительного транзистора и смешны, я просто развязываю на всякий случай резистором 1К от процессора до управляющего входа (EN), этого более чем достаточно.

НСО154 08.12.2017 19:35

http://pccar.ru/showpost.php?p=396179&postcount=2
В описании алгоритма работы (выключение зажигания)...опечатка?
Или реально через несколько суток обесточиваем систему?:)

oleg707 08.12.2017 21:44

Цитата:

Сообщение от НСО154 (Сообщение 396181)
http://pccar.ru/showpost.php?p=396179&postcount=2
В описании алгоритма работы (выключение зажигания)...опечатка?
Или реально через несколько суток обесточиваем систему?:)

2 суток планшет ждёт в спящем режиме.
Потом сутки еще BP5mini активен ( и питает видеорегистратор, если есть).

Время можно настраивать, хочешь - секунда, хочешь - неделя.
PHP код:

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

const boolean reset_HUB_on_power_on 1// передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.

//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
  
float Uperezariadki 15.5;              // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
  
float UrabotyREM 11.8;                 // напряжение, выше которого будет работать усилитель звука, если акб не садился.
  
float UnevykluczeniaREM 13.7;          // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
  
float Uakb_Kogda_ACC_vYkluczeno 11.9;  // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
  
float Uakb_Kogda_ACC_vkluczeno 11.1;   // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
  
float UaccONorOFF 10.1;                // напряжение порога сработки асс.  Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
  
/*счётчики времени*/
  //НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!      НАСТРОЙКИ ТАЙМИНГОВ!!!
  
 
const unsigned long timeUntilBATOff 345600000;                     // время до выключения питания на батарею планшета после выключения зажигания., если прошло 48 часов, как выключили ACC // пауза  (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
 
const unsigned long timeUntilALLOff 172800000 timeUntilBATOff;   // время до полного выключение блока,  после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета    ) (2суток = 172800000)) (4суток = 345600000)
 
unsigned long timeBeforeRemOff 1800000;                            // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку,  при нормальном АКБ)

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

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

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

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


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


jonikus81 11.12.2017 07:44

Цитата:

Сообщение от oleg707 (Сообщение 396120)
если взять, например, из даташита на MP1584

То есть напряжение сработки ниже 5 В ( но толерантно), ток вообще никакой, так зачем в схеме лишний элемент?
Тут только один момент. Когда ардуина выключена ( процессор без питания), то на ножках ардуины, бывает, начинает гулять наводки (0,5-2В), особенно где нет нагрузки на массу.
Тогда у меня было, что ардуина может открыть полевик, например. Приходилось ставить еще один транзистор, для развязки.
В случае с управляющим пином step-down преобразователя, как вариант, такое тоже может быть, но достаточно будет подтянуть EN на массу резистором.
Хотя размеры дополнительного транзистора и смешны, я просто развязываю на всякий случай резистором 1К от процессора до управляющего входа (EN), этого более чем достаточно.

Кстати отлично работает уже 3й блок питания! Просто и надежно :good1:

oleg707 11.12.2017 14:29

Вложений: 2
Цитата:

Сообщение от jonikus81 (Сообщение 396290)
Кстати отлично работает уже 3й блок питания! Просто и надежно :good1:

В процессе БП7:be: = БП5мини + юсб ХАБ + звуковая карта ( аналоговый, оптический и цифровой выходы) + звуковой процессор (для ааппаратной регулировки громкости) + встроенный изикап с передёргиванием питания.
Вложение 48807Вложение 48808
По размерам немного больше БП3.
Не знаю, как я под это дело писать программу буду, да еще с энергопотреблением повозиться.

demtro 12.12.2017 20:33

Изик разобрал и распаял на плату?

Саймон 12.12.2017 21:10

Я уже хотеть!

oleg707 12.12.2017 22:54

Цитата:

Сообщение от demtro (Сообщение 396402)
Изик разобрал и распаял на плату?

нет, там по центру место для этого. Выпаивается ЮСБ и напрямую к плате БП7 штырьками. Перепаивать долго.
Один процессор на 100 ножек в первый раз паять было тяжеловато с непривычки - сначала я с ардуины меги (2650) его выпаял ( фен) а потом на плату пастой ( фен + паяльник контрольно), и потом под лупой:be:


Цитата:

Сообщение от Саймон (Сообщение 396405)
Я уже хотеть!

Я тоже:big:
Пока работает прототип на столе. Мега 2650 жрёт 0,05А. Плюс периферия. Итого 0,1А на холостом ходу выходит.
BP5mini 0,022А на холостом и 0,03А на включенном зажигании , и это у него светодиоды не выпаяны и на ардуине CH340 активный. И проц не в спящем режиме.

Alekssandr 13.12.2017 23:02

Приложение на android будешь делать что всё настраивать? Звук не проверял ещё?

oleg707 14.12.2017 00:16

Цитата:

Сообщение от Alekssandr (Сообщение 396507)
Приложение на android будешь делать что всё настраивать? Звук не проверял ещё?

Нет, приложение если и будет, то потом. В дополнение.
Основные настройки через энкодер громкости ( центральная кнопка - долгое нажатие - меню). Не основные - еще подумаю. Может через скетч, может вообще запрещу их изменение - защита от блудливых рук.
Звук по выходу PCM2704 отличный, чистый. Но по выходу - со звуковым процем косяк - он вешает I2C шину без питания, заказал микросхему- разделитель шины I2C. Заодно и изоляцию шины от КЗ пользователем получу. Иначе атмега пытается получить инфу по I2C, а там по 2,5В висит. Ну и атмега висит - такое стандартное поведение у wire, я так понял.

Плюс сейчас со спящим режимом проца вожусь - не должен проц (пусть и на сто ножек) в простое есть 0,05А. Со спящим интересно - Самые вкусные режимы стандартный загрузчик ардуины не поддерживает. И тут выбор - сохранить простоту обновлений прошивки или расширенный функционал и характеристики. Но слёту без оптимизаций 0,025 получается.
Функции БП5 уже выполняет, а вот то, что задумывалось - еще далеко.
В общем, уже устал немного. Железо оказалось для меня проще, чем софт. Пока на столе большая ардуина мега за 70$ со встроенным хабом, звуком, тремя ДС-ДС и прочими радостями. И осознание, что могу лучше китайцев, плюс куча практического опыта (самое важное).

А еще заказал логический анализатор, а то ловить пакеты I2C шины и сравнивать команды и физический сигнал даже на цифровом осциллографе то еще извращение:shok: ( зато протокол понял чуть ли не до байта)

Alekssandr 17.12.2017 21:54

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

Чисто ради интереса скачай программу RightMark Audio Analyzer и проверь уровень шумов на выходе аудиопроца, я буду удивлён если оно будет выше 35-40dB на максимальной громкости. Это кстати очень важный показатель при установке планшета в машину, если он будет ниже 60db то белый шум в колонках будет напрягать.

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

oleg707 18.12.2017 02:54

Цитата:

Сообщение от Alekssandr (Сообщение 396711)
I2C никак не может вешать мегу. Да и смысла на одной плате разделять I2C нет, другое дело если это модульное устройство с отдельной цифровой и аналоговой частью. Я уже проходил это когда делал первую версию своего аудиопроца, примерно с таким же набором микросхем что и у Вас. Скажу сразу, работать с аналоговым звуком очень сложно, любая не верная разведённая дорожка увеличит уровень шумов на выходе.

Чисто ради интереса скачай программу RightMark Audio Analyzer и проверь уровень шумов на выходе аудиопроца, я буду удивлён если оно будет выше 35-40dB на максимальной громкости. Это кстати очень важный показатель при установке планшета в машину, если он будет ниже 60db то белый шум в колонках будет напрягать.

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

I2C замечательно вешает мегу. И нану тоже - легко. Это я еще на БП3 проходил, когда резисторы подтяжки не поставил, полагаясь на внутренние. От чуть влажного пальца на шине - зависание, спасал только ресет. Ну и аппаратная подтяжка, естествено :big:.
Так устроена библиотека WIRE, насколько я понял.
Когда на шине около 2,5В, то проц ждёт сообытия на шине. ( возможно, там запилено на прерываниях). Как только даю питание на аудиопроц, через него перестаёт идти масса на I2C контактах, и программа весело крутится.

По поводу шума - дома пробовал на нормальном ресивере по аналогу. На максимальной громкости. Уровень шума не больше шума усилителя ( rx-v 1071).

Сейчас у меня в машине вообще напрямую с звуковой карты на УЗЧ идёт. И регулировка громкости андроидом с планшета. Белый шум устраивает, точнее его почти нет, а на заведённой в принципе не слышно. ( естественно настроена чувствительность УЗЧ).

По поводу RightMark Audio Analyzer - "Для этого необходима отдельная высококачественная звуковая карта, вход которой должен быть подключен к выходу тестируемой." То есть уровень шумов линейного входа "замерочной" звуковой должен быть наааамного ниже шумов источника звука (в нашем случае аудиопроца). Иначе будет шуметь уже "замерочная" звуковая карта
Чего я гарантировать не могу. Но как нибудь и с ней поиграюсь.

Тем более у меня есть готовая печатная плата, есть уже впаянный туда аудиопроц с обвязкой.
Осталось только найти время и написать программу на атмегу, и подключить всё это хозяйство в машину, на послушать (надо будет всё переделывать, это тоже останавливает).
После этих движений и буду принимать решение, оставлять ли этот аудиопроц либо менять его ( на что? цена аудиочипа не должна превышать 5-10$ в данном случае).
Вообще можно полноценный аудиопроц (от 500-1000$ )подключить по оптике. Но это ИМХО в машину немножко перебор.

Тут же тоже стоит вопрос соотношения цена\результат. И за 5% результата я не готов платить 30-40% цены. :blush:

Alekssandr 18.12.2017 10:22

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

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

По поводу цена качество я вам уже предлагал ADAU1701 если не достаточно 4-х аналоговых выходов, + 2х канальный ЦАП PCM5102.
Цена вопроса:
1) DSP ADAU1701 5$ ~300 руб за шт.
2) DAC PC5102 3$ ~200 руб за шт.
За весьма скромные деньги получишь практический все возможности аудиопроцессоров за 500-1000$.

ИМХО в итоге разочаруешься в этом аудиопроце TDA, 99%. В общем удачи, опыт тоже важен) Главное не бросать свою идею и доводить её до идеала.

oleg707 18.12.2017 15:20

Похоже, что таки придётся изучать сигма студио.

oleg707 20.12.2017 18:24

открыл для себя спящий режим процессора. Удалось при сохранении загрузчика снизить энергопотребление блока в режиме ожидания (с включённой запиткой батареи планшета) на 30%.
Было:
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
__________________________________________________ ______________
Стало:
- при 10В +30 и +15 выключены = 0,022 А
- при 12В +30 и +15 включены = 0,06 А
- при 12В +30 включены +15 выключены (при питании батареи) = 0,03А
__________________________________________________ ______________

если включен просто проц , то опускалось до 0,007А, когда из этого половина ест светодиод питания на ардуине. Я так понял, в этот момент ch340 заходил в спящий режим и не успевал включиться ни один из ДС-ДС.
Потестирую - выложу.

Мега 2650 так вообще с 0,100 А снижает потребление до 0,000 (0,001 со светодиодом).

НСО154 20.12.2017 19:19

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

oleg707 20.12.2017 20:00

Цитата:

Сообщение от НСО154 (Сообщение 396896)
Из собственного опыта да и ты правильно размышляешь, можно выпаять стабилизатор и диоды с ардуино.
Потребление значительно упадёт.
Я вообще в недоумении...на какой они впиндюрили такой стаб...

Я на 3й версии БП еще игрался с выпаиванием кусков с ардуины - не понравилось. Если так уже ставить вопрос, то мне проще собрать "ардуину" на плате. Только по факту чистую атмегу с правильным стабилизатором +5В ( дс-дс для этого слишком много). Использовать атмегу 32u4 или 328p + ch340. ch340 запитать от юсб. 32u4 не понравилась - иногда загрузка скетча не шла, хоть и юсб встроен.
Тут вообще идея в том, что эти 0,02 машина даже не заметит за 2-3 дня. В этом режиме вообще на месяцы можно оставлять. А потом БП сам выключается и потребление становится 0,0000А. Поэтому смысл лишних телодвижений вообще теряется.
Да и по себестоимости ардуина дешевле, чем просто процессор на китае купить.

НСО154 20.12.2017 20:09

Тоже верно.
Пысы: на плате не дёшево получится, если с качественными компонентами.
Но зато вид будет достойный, это я в плане эстетики:)

По авто вообще голову можно не греть...у некоторых борт сеть выжирает большее колличество миллиампер, а владельцы об этом и не догадываюся:)
В общем удачи!

skanch 20.12.2017 22:52

Цитата:

Сообщение от oleg707 (Сообщение 396890)
открыл для себя спящий режим процессора....

Ты же с ним (режим сна) начал баловаться уже давно...! Или что-то новое обнаружил?

oleg707 21.12.2017 00:16

Цитата:

Сообщение от skanch (Сообщение 396912)
Ты же с ним (режим сна) начал баловаться уже давно...! Или что-то новое обнаружил?

Можно и так сказать:blush:
Загнать то в сон не проблема, даже вывести из него ( неважно, по прерыванию или по ватчдогу), хоть на прямом ассемблере или СИ ( сначала так и загонял). Там фишка в другом - millis() во сне не считается. А все тайминги рассчитываются через millis().
А, еще, в ардуине почти у всех процессоров не поддерживается режим ватчдога со стандартным загрузчиком. В том числе и на nano, с учётом того, что загрузчик я заливал с самой последней на сегодня ардуино IDE (1.9.0-beta) по ISP, через USBasp. В итоге тестового скетча получалось вместо ватчдога и внятного ребута просто мельтешение светодиода, и даже на ресет не реагировало.
В итоге разобрался, как скрестить бобра с ослом, чтобы на выходе получилось то, что нужно.
А наткнулся вообще, потому как полез разбираться, почему голая атмега2650 с эффективным стабилизатором +5В потребляет 0,1А. Потому как сильно это много для включения в авто.
И тормозить нельзя цикл, потому как энкодер, ему риалтайм нужен ( на прерывания не вешал - оно для регулировки громкости и по менюшке лазить)

skanch 21.12.2017 00:36

Цитата:

Сообщение от oleg707 (Сообщение 396914)
А наткнулся вообще, потому как полез разбираться, почему голая атмега2650 с эффективным стабилизатором +5В потребляет 0,1А. Потому как сильно это много для включения в авто.

Проблема с потреблением в дежурном режиме блока питания действительно актуальная тема. Тем более, что у тебя блок задуман универсальный и контроллер, как я понимаю нужен "многоногий"... Не пробовал вывести режим отслеживания напряжения за контроллер? Т.е. сделать его не привязанным к процессору, а отслеживать отдельным супервизором. Тогда и вовсе можно отключать питание на контроллер во время сна (планшета) и оставить только дежурное питание на сам планшет (достаточно LDO-преобразователя на 100-150 мА с низким током собственного потребления).

oleg707 21.12.2017 01:57

Цитата:

Сообщение от skanch (Сообщение 396918)
Проблема с потреблением в дежурном режиме блока питания действительно актуальная тема. Тем более, что у тебя блок задуман универсальный и контроллер, как я понимаю нужен "многоногий"... Не пробовал вывести режим отслеживания напряжения за контроллер? Т.е. сделать его не привязанным к процессору, а отслеживать отдельным супервизором. Тогда и вовсе можно отключать питание на контроллер во время сна (планшета) и оставить только дежурное питание на сам планшет (достаточно LDO-преобразователя на 100-150 мА с низким током собственного потребления).

думал, тиньку например. Но тут уже вопросы удобства:
Перепрошивка - по юсб через ардуино IDE сделает и школьник, а вот тиньку прошить - тут как минимум USBasp нужен ( мне проще обычным программатором, например).
Выставление своих значений напряжений и таймингов - то же самое. Мало того, я код стараюсь делать так, чтобы его можно было отредактировать под себя даже новичку ( например выключение через 3 часа или 4 суток). У каждого свои потребности.
И сейчас просто надо изменить нужные значения и записать их одним кликом мышки ( ладно, тремя).

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

Пока что меня абсолютно устраивают первичные тесты с потреблением в 0,001 (0,000 без светодиода, то есть мне предела измерения довольно точного амперметра не хватает) и "Low-Noise Ultra-Low-Dropout Regulator на 150 мА"

Таки не поленился, померил нормальным амперметром.
напряжение 15В.
0,000779А без светодиода
0,00325А с светодиодом.
напряжение 12В.
0,000665А без светодиода
0,003135А с светодиодом.

Код типа блинк, только проц, кварц на 16МГц, и стабилизатор на 5В. Спящий режим всё время, кроме времени переключения.

обманул немного. мега2560 на холостом ходу потребляет 0,055А

oleg707 23.12.2017 02:48

Ладно, пока свежая прошивка обкатывается в моём самоходе, посоветуйте чего.

Дано: i2c в арддуине через стандартный wire.h
Когда делаешь старт библиотеки, то ЕСЛИ коротнуть шину, то библиотека ждёт ответа или сообщения, и проц по факту висит!
Проблема известная, но мало распространённая.
Есть ли альтернативная библиотека или какой другой програмный способ заставить работать проц при низком уровне на i2c.
Согласователи i2c интерфейса уже едут, но хотелось бы не только железную защиту.

PS
Разобрался, но железную защиту тоже прикручу. Зря, что ли, микросхемы заказывал ? :)


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

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

https://drive.google.com/file/d/1oAz...ew?usp=sharing

urikz 10.03.2018 06:01

Здравствуйте oleg707!!! По возможности перезалейте вашу сборку на другой обменник...Никак не качается с mega.nz.Спасибо!


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

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