Гуру
Регистрация: 16.04.2014
Возраст: 40
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
|
новая версия прошивки
обновление не критическое. 99% изменений не заметят.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.
PHP код:
const byte ver = 39;// ( чем больше цифра, тем новее)
byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания.
// дата правки 3.01.19.2117
// для 5mini, 5mini2.1, 5mini+2.2 версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10
// МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка.
// Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1;
// Для штатной, нормальной работы блока питания ставим OTLADKA = 0;
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном.
// 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В
byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.)
// 0 - 0 - берём значения из скетча, игнорируя память
// 1 - сохраняем в EEPROM
// 2 - берем значения из памяти eeprom игнорируя скетч
byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0.
byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать)
byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать)
byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла.
unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.
//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
// напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0
float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
//КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________
/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!
unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд
unsigned long LONG_koefficient_delitelia_ACC =0;
unsigned long LONG_koefficient_delitelia_AKB =0;
float rezerv5 =0;
float rezerv6 =0;
float rezerv7 =00.00;
//конец настроек таймингов.__________________________________________________________________________________________
//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
// К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром
struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру
{
byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать)
byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать)
byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился.
float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
unsigned long timeUntilBATOff; // 4 байта
unsigned long timeUntilALLOff; // 4 байта
unsigned long timeBeforeRemOff; // 4 байта
unsigned long timeAfterACC_starting; // 4 байта
unsigned long timeAfterACC_accOFF ; // 4 байта
unsigned long timeWhileAkbLow ; // 4 байта
unsigned long pauseTimeHALL ; // 4 байта
unsigned long vremia_obnovlenia_displeya ; // 4 байта
unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта
unsigned long OTG_timer_pri_vkl_ACC; // 4 байта
unsigned long HUB_timer_pri_vkl_ACC; // 4 байта
unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта
unsigned long REM_timer_pri_vkl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта
unsigned long I_dva_C_szina_ON_time; // 4 байта
unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта
unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта
unsigned long HUB_timer_pri_vykl_ACC; // 4 байта
unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта
unsigned long REM_timer_pri_vykl_ACC ; // 4 байта
unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта
unsigned long I_dva_C_szina_OFF_time ; // 4 байта
unsigned long vremia_uderjanija_najatoj_knopki_POWER ;
unsigned long REGISTRATOR_timer_pri_vYkl_ACC ;
unsigned long LONG_koefficient_delitelia_ACC ;
unsigned long LONG_koefficient_delitelia_AKB ;
float rezerv5 ;
float rezerv6 ;
float rezerv7 ;
};
//***************************************************************************************************************************************************
// Массив режимов работы светодиода
const byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//***************************************************************************************************************************************************
#include <JeeLib.h> // Low power functions library
// у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна
#include <Wire.h> // для дисплея - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для дисплея
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
/*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
*///13
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
// обьявляем переменные и задаём их начальные значениия
float UakbONorOFF = 12.1; // напряжение порога сработки акб
float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя
float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя
int Uacc = 0; // напряжение с делителя ACC 0-1024
int Uakb = 0; // напряжение с делителя АКБ 0-1024
int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX
static int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX
float Uacc_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
float Uakb_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
//PORTB
const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока
const byte LED_Pin = 13; // номер пина встроенного светодиода индикации
const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG
const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа
const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла)
//PORTD
const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора
const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В)
const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа
//логические состояния блока питания (какая ножка какой сигнал должна выдавать)
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG
uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
static byte PINrawACC = A0; // замер для 5й версии
static byte PINrawAKB = A1; // замер для 5й версии
static byte PINkalibrovki = A2; // замер для 5й версии
//static byte PINrawACC = A7; // замер для 7й версии
//static byte PINrawAKB = A8; // замер для 7й версии
//static byte PINkalibrovki = A3; // замер для 7й версии
//пины состояния ITS
static byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
static byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/
/*логические переменные, используемые в коде*/
byte flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС
byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ
byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ
byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)
byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги.
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/
unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */
unsigned long H = (millis()/3600000); // часы
byte M = ((millis()-(H*3600000))/60000); //минуты
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине
{
if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали.
{
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
/*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
*///13
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7
razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C
}
}
void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания.
{
PORTBregistr = 0; // выключили всё
SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки
if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем
SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.)
HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен
OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG
PORTDregistr = 0; // выключили всё
PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами
}
void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */
{
// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PORTBregistr - обрабатывем регистры порта B атмеги
/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания
if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO // управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
*/
digitalWrite(LED_Pin, LED); //управление встроенным светодиодом
digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html
digitalWrite(OTG_Pin, OTG); // управление OTG
digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания
digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла)
// PORTDregistr - обрабатывем регистры порта D атмеги
//PORTD
digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0)
digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12)
digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В)
digitalWrite(REM_Pin, REM); //управление выходом REM (+12)
// if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
// if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
//if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
// if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта
// Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
// Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA);
//PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
//PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup() //настройки при первой подаче питания. выполняются 1 раз.
{
Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать
if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча.
RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM
OBRABOTKA_KALIBROWKI();
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; // настройки порта D
DDRB = 0b00111110; // настройки порта B
pinMode(PINkalibrovki, INPUT); // пин калибровки
digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//vykluchic_vse();
/* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1)
FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
*/
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
{//void displayDataToDISPLAY()
//вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 0);
lcd.print(strokaI);
//Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки
lcd.setCursor(0, 1); //2строка 0символ
lcd.print(strokaII);
//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки
/*//13
display2.clearDisplay(); // очистили буфер
display2.setTextSize(1); // установили размер текста (1-4)
display2.setCursor(0,0); // начальная точка вывода
display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея
//вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки
display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея
if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки)
{
display2.clearDisplay(); // очистили буфер
}
display2.display(); //эта строка выводит картинку 1306 из буфера на экран!
*///13
//Вывод строк окончен.______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
}//void displayDataToDISPLAY()
void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
//text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}
void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
//text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[0] = ((num/10)%10) + '0';// второе значение __0
text[1] = (num%10) + '0'; // третее значение ___
}
void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11
{
text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[1] = ((num/10)%10) + '0';// второе значение __0
text[2] = (num%10) + '0'; // третее значение ___
}
void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/1000) + '0';//0 знач
text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/10)%10) + '0';// второе значение __0
text[3] = (num%10) + '0'; // третее значение ___
}
void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111
{
text[0] = (num/10000) + '0'; //0 знач
text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = ((num/100)%10) + '0';// второе значение __0
text[3] = ((num/10)%10) + '0'; // третее значение ___
text[4] = (num%10) + '0'; // 4е значение ___
}
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11
{
int Int = num*100;
text[0] = (Int/1000) + '0';//0 знач 7896
text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа.
text[2] = '.';
text[3] = ((Int/10)%10) + '0';// второе значение __0
text[4] = (Int%10) + '0'; // третее значение ___
}
void OBRABOTKA_KALIBROWKI()
{//void OBRABOTKA_KALIBROWKI()
// проверка на прописанную в памяти калибровку
if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение.
{
if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295)
{
sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]);
sprintf(strokaII, "NE PROPISANA !!!") ;
INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине
displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
delay (1000); // задержка чтобы успеть прочитать
}
}
if (LONG_koefficient_delitelia_ACC == 4294967295)
{
LONG_koefficient_delitelia_ACC = 15364;
}
if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}
}//void OBRABOTKA_KALIBROWKI()
void RABOTA_z_EEPROM ()
{//void RABOTA_z_EEPROM ()
kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча.
{//if (brac_nastrojki_iz_EEPROM == 1)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя
{//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
{// Создаем массив объектов
reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать)
power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать)
HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с.
Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто.
UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился.
UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС
Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС
UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным.
timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000)
timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин
vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.)
HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC.
REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор
REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла)
I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.)
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC.
SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла)
REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C.
vremia_uderjanija_najatoj_knopki_POWER,
REGISTRATOR_timer_pri_vYkl_ACC,
LONG_koefficient_delitelia_ACC,
LONG_koefficient_delitelia_AKB,
rezerv5,
rezerv6,
rezerv7
}// конец Создаем массив объектов
};//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia
EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom)
}//if (brac_nastrojki_iz_EEPROM == 1)
if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.)
{//if (brac_nastrojki_iz_EEPROM == 2)
myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
// теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой
//но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ)
if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14)
{ //if znachenija_polzovatelia.reset_HUB_on_power_on)
reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on;
power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting;
power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting;
HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch;
Uperezariadki = znachenija_polzovatelia.Uperezariadki;
UrabotyREM = znachenija_polzovatelia.UrabotyREM;
UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM;
Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno;
Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno;
UaccONorOFF = znachenija_polzovatelia.UaccONorOFF;
timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff;
timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff;
timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff;
timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting;
timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF;
timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow;
pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL;
vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya;
PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC;
OTG_timer_pri_vkl_ACC = znachenija_polzovatelia.OTG_timer_pri_vkl_ACC;
HUB_timer_pri_vkl_ACC = znachenija_polzovatelia.HUB_timer_pri_vkl_ACC;
REGISTRATOR_timer_pri_vkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vkl_ACC;
REM_timer_pri_vkl_ACC = znachenija_polzovatelia.REM_timer_pri_vkl_ACC;
SLEEP_timer_pri_vkl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vkl_ACC;
I_dva_C_szina_ON_time = znachenija_polzovatelia.I_dva_C_szina_ON_time;
OTG_timer_pri_vykl_ACC = znachenija_polzovatelia.OTG_timer_pri_vykl_ACC;
FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = znachenija_polzovatelia.FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC;
HUB_timer_pri_vykl_ACC = znachenija_polzovatelia.HUB_timer_pri_vykl_ACC;
SLEEP_timer_pri_vykl_ACC = znachenija_polzovatelia.SLEEP_timer_pri_vykl_ACC;
REM_timer_pri_vykl_ACC = znachenija_polzovatelia.REM_timer_pri_vykl_ACC;
lcd_noBacklight_timer_pri_vykl_ACC = znachenija_polzovatelia.lcd_noBacklight_timer_pri_vykl_ACC;
I_dva_C_szina_OFF_time = znachenija_polzovatelia.I_dva_C_szina_OFF_time;
vremia_uderjanija_najatoj_knopki_POWER = znachenija_polzovatelia.vremia_uderjanija_najatoj_knopki_POWER;
REGISTRATOR_timer_pri_vYkl_ACC = znachenija_polzovatelia.REGISTRATOR_timer_pri_vYkl_ACC;
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia_ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia_AKB;
rezerv5 = znachenija_polzovatelia.rezerv5;
rezerv6 = znachenija_polzovatelia.rezerv6;
rezerv7 = znachenija_polzovatelia.rezerv7;
} //if znachenija_polzovatelia.reset_HUB_on_power_on)
} //if (brac_nastrojki_iz_EEPROM == 2)
//0 - берём значения из скетча, игнорируя память ( кроме калибровки)
EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia);
LONG_koefficient_delitelia_ACC = znachenija_polzovatelia.LONG_koefficient_delitelia_ACC;
LONG_koefficient_delitelia_AKB = znachenija_polzovatelia.LONG_koefficient_delitelia_AKB;
}//void RABOTA_z_EEPROM ()
void printDISPLAY() //функция формирования информации на дисплей ( точнее на два: 128*64 и 1602)
{
//_____________________________________________ФОРМИРУЕМ СООБЩЕНИЕ НА LCD ДИСПЛЕЙ____________________________________________________________
H = (millis()/3600000);
M = ((millis()-(H*3600000))/60000);
//int S = (((millis()/1000)-(H*3600))- (M*60));
//if ((((millis())-(H*3600000))- (M*60000)) < 200 ){lcd.clear(); }//очистка дисплея
//int M = (millis()/60000); //минуты
if (flagACC == 1){lcd.backlight();}// включаем подсветку дисплея 1602
// в 256 строке выключение подсветки LCD дисплея
//пример: sprintf( strokaII,"SETUP volume on ");
//обработка 1й строки_________AKB ACC REM_____________________________________________________________________________________________________________________________________________________________________
sprintf(strokaI," ") ;
//IntToCharIIII((millis()/60000), &strokaI[0]); // вывод минут 0000 4 цифры СЕКУНД // если превысит 9999, то будут кроказябры!!! вида ;0129
IntToCharIII(H, &strokaI[0]); // вывод часов 000
strokaI[3] = ':'; // вывод двоеточия
IntToCharII(M, &strokaI[4]); // вывод минут 00
strokaI[7]= flagAKB + '0';// вывод флага AKB 5 символ
strokaI[8]= flagACC+ '0';// вывод флага AСС 6 символ
strokaI[9]= REM + '0';// вывод rem 7 символ 1-усилитель звука включен, 0 - выключен
strokaI[10]= flagREM + '0';// вывод флага!!! rem 7 символ 1-усилитель звука включен, 0,2 - выключен
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АСС
//конец обработки 1й строки ______________________________________________________________________________________________________________________________________________________________________________
//обработка 2й строки______________________________________________________________________________________________________________________________________________________________________________
TIMER = ( pauseTimeAKB + timeUntilALLOff - millis() )/60000; // вывод кол-ва минут, оставшиеся до вЫключения блока (когда выключено АСС)
// _______________________________Первые 30с после вкл ACC выводим версию блока.____________________________________________________________________________________________________________________________________________________
if ( ( millis()-pauseTimeACC < 30000 )&& flagACC == 1 ){ sprintf(strokaII,"m__ ") ; IntToCharII(ver, &strokaII[1]);} else { sprintf(strokaII,"____ "); IntToCharIIII(TIMER, &strokaII[0]); } //Первые 30с после вкл -выкл ACC выводим версию блока
// _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//вывод STARTUEM OTG HUB POGO HALL
strokaII[5]= STARTUEM + '0';// Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= FIVE_Volt_OUT_na_POGO_or_USB + '0';// вывод флага FIVE_Volt_OUT_na_POGO_or_USB (ПРИЗНАК ЗАРЯДКИ или зарядка на юсб) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки ______________________________________________________________________________________________________________________________________________________________________________
if (kalibrovkaNOW >= 1 && kalibrovkaNOW < 255 )// если активен режим калибровки, то выводим данные для калибровки.
{
sprintf (strokaI," ") ;
IntToCharIII(Uacc, &strokaI[0]);
IntToCharIII(Uakb, &strokaI[4]);
IntToCharII(kalibrovkaNOW, &strokaI[8]); // вывод счетчика РЕЖИМА калибровки
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
}
//Вывод строк.______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
if (razreszenie_raboty_I_dva_C_sziny == 1) {displayDataToDISPLAY();} //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>>
/* так выглядит индикация на дисплее
================
|000:00 110212.10| 1 строка * вывод времени работы блока H:M * AKB ACC REM * вывод напряжения АСС
|2616 01110 14.50|
================ 2 строка * кол-во минут, оставшиеся до выключения блока * STARTUEM OTG HUB POGO HALL * вывод напряжения АКБ
*/
}
/******************************************конец индикации светодиодом и вывода на дисплей********************************************************************************************************************************************************************************/
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
/*void analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(PINrawACC);
int newUakb = analogRead(PINrawAKB);
if (averageFactor > 0) // усреднение показаний для устранения "скачков"
{
Uacc = (Uacc * (averageFactor - 1) + newUacc) / averageFactor;
Uakb = (Uakb * (averageFactor - 1) + newUakb) / averageFactor;
// <новое среднее> = (<старое среднее>*4 + <текущее значение>) / 5
} else {
Uakb=newUakb; // не делаем усреднений, что прочитали то и считаем выводом
Uacc=newUacc; // не делаем усреднений, что прочитали то и считаем выводом
}
// новое ( с T12 версии) вычисление реального напряжения, с учетом значений калибровки в еепром (0 и 1 адреса)
U_acc_real = Uacc * (1410.0+kalibrovkaACC)/100000;
U_akb_real = Uakb * (1410.0+kalibrovkaAKB)/100000;
}//void analogReadU
*/
void READ_SREDNIEJE_U()
{ //void READ_SREDNIEJE_U
Uacc = analogRead(PINrawACC);
Uakb = analogRead(PINrawAKB);
Uacc_TMP = (Uacc_TMP + Uacc );
Uakb_TMP = (Uakb_TMP + Uakb );
cykly_usrednenij_U ++;
if (cykly_usrednenij_U == ilosc_usrednenij)
{
U_acc_real = Uacc_TMP*(LONG_koefficient_delitelia_ACC+1)/1000000.0/ilosc_usrednenij;
U_akb_real = Uakb_TMP*(LONG_koefficient_delitelia_AKB+1)/1000000.0/ilosc_usrednenij;
if (kalibrovkaACC<255 && kalibrovkaAKB<255) //если калибровка старого типа, вычисляем напряжение по старому, если мы не в режиме калибровки.
{
U_acc_real = (Uacc_TMP * (1410.0+kalibrovkaACC+0.05)/100000.0/ilosc_usrednenij);
U_akb_real = (Uakb_TMP * (1410.0+kalibrovkaAKB+0.05)/100000.0/ilosc_usrednenij );
}
cykly_usrednenij_U = 0;
Uacc_TMP = 0; // обнуляем для начала нового отсчета
Uakb_TMP = 0;
}
} //void READ_SREDNIEJE_U
void OBRABOTKA_REJIMA_OTLADKI()
{//OBRABOTKA_REJIMA_OTLADKI
if (OTLADKA >= 1)
{ //if (OTLADKA >= 1)
// 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В
// 2 - если напряжение ACC > 6В то считаем ACC=14,5В АКБ считаем всегда AKB=14,5В
// 3 - напряжение ACC всегда считаем ACC=14,5В напряжение АКБ всегда считаем AKB=14,5В
if (U_acc_real > 6) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (если реальное напряжение АСС > 6В)
if (U_akb_real > 6) {U_akb_real = 14.50;} // принимаем напряжение аккумалятора автомобиля за 14,50В (если реальное напряжение AKB > 6В)
if (OTLADKA >= 2 )
{
U_akb_real = 14.50;
if (OTLADKA >= 3 ) {U_acc_real = 14.50;} // принимаем напряжение после замка зажигания за 14,50В (всегда, в режиме OTLADKA == 2 )
}
// принимаем напряжение аккумалятора автомобиля за 14,50В ( в режиме OTLADKA == 1 и OTLADKA == 2)
}//if (OTLADKA >= 1) //конец режима отладки.
}//OBRABOTKA_REJIMA_OTLADKI
void rejim_kalibrovki() //функция измерения, калибровки и записи полученных значений в еепром
{//void rejim_kalibrovki()
lcd.noBacklight();
delay (50);
lcd.backlight();
delay (250);
if (digitalRead(PINkalibrovki)== 1 && kalibrovkaNOW < 6) {kalibrovkaNOW ++;}
else // тут достигли 6 касаний точки калибровки и ЗАПУСКАЕМ НЕПОСРЕДСТВЕННО ПРОЦЕСС КАЛИБРОВКИ ( ДЛЯ ЭТОГО ПОДАЁМ РОВНО 12,00В НА БЛОК ПИТАНИЯ ( асс и акб)
{ //else
if (kalibrovkaNOW >= 6)
{//if (kalibrovkaNOW >= 6)
vykluchic_vse(); // вызвали функцию выключения всех выходов и напряжений с блока питания.
delay (500); // для зарядки конденсаторов после снятия нагрузки
//тут позже можно опционально добавить усреднение Uacc Uakb
//вычисляем новое значение калибровки
brac_nastrojki_iz_EEPROM =2; // включили режим считывания настроек из энергонезависимой памяти
RABOTA_z_EEPROM (); // считали значения пользователя из энергонезависимой памяти.
LONG_koefficient_delitelia_ACC = 12000000/Uacc;
LONG_koefficient_delitelia_AKB = 12000000/Uakb;
kalibrovkaNOW ++;
}//if (kalibrovkaNOW >= 6)
}//else
if ( kalibrovkaNOW >= 15 && digitalRead(PINkalibrovki)== 0) //по достижению счета в 15 и ПРИ МАССЕ НА ПИНЕ КАЛИБРОВКИ данные калибровки запишутся в еепром
{
kalibrovkaNOW = 255;
EEPROM.update(0,255);
EEPROM.update(1,255);
brac_nastrojki_iz_EEPROM = 1; // включили режим записи настроек в энергонезависимую память
RABOTA_z_EEPROM (); // вписали значения пользователя с калибровкой в энергонезависимую память.
sprintf (strokaI,"end KALIBR. ") ;
sprintf(strokaII," / ") ;
LongToCharIIIII(LONG_koefficient_delitelia_ACC, &strokaII[0]);
LongToCharIIIII(LONG_koefficient_delitelia_AKB, &strokaII[6]);
FloatToCharIIIII (U_acc_real, &strokaI[11]); // вывод напряжения АКБ
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
displayDataToDISPLAY(); //
delay (60000);
}
}//void rejim_kalibrovki()
void STATUS_REM()
{//void STATUS_REM()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обработка статуса выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*если напруга батареи больше 12В, то включаем еще и усилитель звука (выход REM) /но включаем его только на timeBeforeRemOff (30 минут), если не заведены.*/
if (U_akb_real >= UrabotyREM && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= UrabotyREM && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= UnevykluczeniaREM && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UrabotyREM && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= UrabotyREM && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= UnevykluczeniaREM && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= UnevykluczeniaREM && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= Uperezariadki){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()
void obrabotka_ACC_ON()
{ //START void obrabotka_ACC_ON()
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((Uperezariadki > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (U_acc_real >= UaccONorOFF) //как только включили зажигание ( при любом напряжении батареи)
{ // как только включили зажигание ( при любом напряжении батареи)
INIT_I2C (); // запускаем инициализацию дисплеев на I2C шине
} // конец как только включили зажигание ( при любом напряжении батареи)
if (flagACC ==1 )
{// если flagACC == 1
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==1 && flagAKB==1){STARTUEM = 0;} // определяем предположительный старт авто c задержкой XXXмс
}
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}
if (millis() - pauseTimeACC >= FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
FIVE_Volt_OUT_na_POGO_or_USB = 1; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}
if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на OTG (включается определение периферии планшетом.)*/
}
if (millis() - pauseTimeACC >= HUB_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
if (reset_HUB_on_power_on == 1)
{
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+500) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 0; //digitalWrite(HUBpin, 1); /*Выключаем хаб*/
}
if (millis() - pauseTimeACC >= (HUB_timer_pri_vkl_ACC+1000) ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
HUB = 1; //digitalWrite(HUBpin, 0); /*Включаем хаб = подаем минус на управляющий транзистор хаба, тот открывается и пускает +5В dc-dc (2вых)на хаб*/
}
}
if (millis() - pauseTimeACC >= REGISTRATOR_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
REGISTRATOR = 1;// digitalWrite(REGISTRATORpin, 1); /* включаем питание на видеорегистратор*/
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}
if (millis() - pauseTimeACC >= REM_timer_pri_vkl_ACC )/*через 2,2с после включения ACC включаем: */
{
if (millis() < 15000) {flagREM =0;} // в первые 15 секунд при холодном пуске держим REM выключенным
if( flagREM == 1 && flagAKB == 1 ){REM = 1;} /* включаем выход REM*/
}
if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{SLEEP = 0;} //digitalWrite(SLEEPpin, 0); /*включаем экран*/
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+vremia_uderjanija_najatoj_knopki_POWER) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vkl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)
}// если flagACC == 1
STATUS_REM(); //зашли в функцию обработки статуса выхода REM
}//END void obrabotka_ACC_ON()
void obrabotka_ACC_OFF()
{ //START obrabotka_ACC_OFF()
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
//
if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/
if (((millis() - pauseTimeACC) >= (100)) )
{
if (flagACC==0 && flagAKB==0){STARTUEM = 1;} // определяем предположительный старт авто c задержкой XXXмс
}
if (HALL_as_power_Switch == 0)
{ //if (HALL_as_power_Switch == 0)
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{SLEEP = 1;}//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
else {SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
} //if (HALL_as_power_Switch == 0)
if (HALL_as_power_Switch == 1)
{//if (HALL_as_power_Switch == 1)
if (millis() - pauseTimeACC >= SLEEP_timer_pri_vykl_ACC ) {SLEEP = 1;}//digitalWrite(SLEEPpin, 0); /*включаем экран*/
if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+HALL_as_power_Switch) ) { SLEEP = 0;}
//if (millis() - pauseTimeACC >= (SLEEP_timer_pri_vykl_ACC+1000) ) { SLEEP = 1;}
}//if (HALL_as_power_Switch == 1)
if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG (8 pin PW1)*/
}
if ( ((millis() - pauseTimeACC) >= (FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC+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 )) && (razreszenie_raboty_I_dva_C_sziny == 1) ) //когда вЫключили зажигание, по истечении времени (I_dva_C_szina_OFF_time) и если разрешение на работу I2C шины всё еще вЫключено - вЫключаем шину I2C
{
lcd.clear(); //очистка дисплея
razreszenie_raboty_I_dva_C_sziny = 0; //запрещаем работу I2C шины
// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет вЫключать питание на TDA7442 ! ! ! ! ! ! ! ! !
}
if ( ((millis() - pauseTimeACC) >= (REGISTRATOR_timer_pri_vYkl_ACC+timeAfterACC)) )
{
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
}
if (razreszenie_raboty_I_dva_C_sziny == 0) //Не даём заснуть при активном режиме
{Sleepy::loseSomeTime(vremia_sna_ATMEGI);}// Т У Т С П И М sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек.
}// if (flagACC==0)
} //END obrabotka_ACC_OFF()
void obrabotka_AKB()
{//START obrabotka_AKB()
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
if (U_acc_real >= UaccONorOFF) {UakbONorOFF = Uakb_Kogda_ACC_vkluczeno;} else {UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;} /*при включении зажигания напряжение самовырубания станет 11,1 вместо 11,9*/
if ((Uperezariadki > U_akb_real) && ((U_akb_real >= UakbONorOFF) && flagAKB == 0)) /*проверка +30 на перезаряд >15.5В, и больше заданного в 266 строке, и флага акб */
{
if ((millis() - pauseTimeACC >= 100) && flagAKB == 0)
{
SAMOZAPITKA =1;//digitalWrite(SAMOZAPITKApin, 1); /* включаем самозапитку процессора */
flagAKB = 1; /*подняли флаг батареи*/
}
}
if (((U_akb_real < UakbONorOFF) && flagAKB == 1)||(U_akb_real >Uperezariadki))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = Uakb_Kogda_ACC_vYkluczeno;
}
if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
vykluchic_vse();
//PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
//OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на OTG )*/
//FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); /*вЫключаем +5V (POGO(USB))*/
//HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
//REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
//REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
//SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (5000); // задержка для аппаратного выключения
}
if (flagAKB == 1 && flagACC == 0) /*ситуация, когда норм акб и выключено зажигание (ACC)*/
{
if ((millis() - pauseTimeAKB )>= timeUntilBATOff && flagAKB == 1) /* если прошло "timeUntilBATOff" 24 (86400000) часа, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)*/
{
PlanshBAT = 0; // digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета (in2)//(батарея планшета))*/
}
if ((millis() - pauseTimeAKB) >= timeUntilALLOff && flagAKB == 1) /* если давно выключили ACC ) "timeUntilALLOff" (2суток = 172800000)) (самозапитка для регистратора, процессор БП активен)*/
{
vykluchic_vse();
//SAMOZAPITKA = 0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом система ПОЛНОСТЬЮ обесточивается*/
//UPRAVLENIE_PINAMI();
delay (10000); // задержка для аппаратного выключения
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
} //END obrabotka_AKB()
void loop()
{while (1){//для ускорения void loop
READ_SREDNIEJE_U(); //вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП АКБ и АСС, потом их усреднили(ilosc_usrednenij)раз.
if ( (millis() < 120000) )
{
if (kalibrovkaNOW != 255 && digitalRead(PINkalibrovki)== 0) // после 120с или если стоит ЗАПРЕТ(255-калибровка выполнена), калибровку НЕ ДЕЛАЕМ
{
if ( (millis() < 120000) || kalibrovkaNOW >= 6 ) { rejim_kalibrovki();}
}
}
OBRABOTKA_REJIMA_OTLADKI(); //переходим в функцию отладки = если включен режим ОТЛАДКИ, тогда игнорируем реальные напряжения аккумулятора
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем, нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = timeAfterACC_accOFF; } //выключили зажигание.
else { timeAfterACC = timeAfterACC_starting; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//заводим машину (стартуем) или сел акб при включенном зажигании.
if (U_akb_real >= Uperezariadki){timeAfterACC = 0;}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// -------------------------========================= блок контроля АКБ ==========================-------------------------------------------------------------------------------
obrabotka_AKB(); // запустили блок обработки АКБ
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
obrabotka_ACC_ON(); // запустили блок обработки ACC (обработка режима включённого зажигания)
obrabotka_ACC_OFF(); // запустили блок обработки ACC (обработка режима вЫключенного зажигания)
/******************************************индикация светодиодом и задержка вывода на дисплей********************************************************************************************************************************************************************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}
if (razreszenie_raboty_I_dva_C_sziny == 1) // если разрешена работа для шины I2C
{
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > vremia_obnovlenia_displeya || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
}
/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[4];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - Две короткие вспышки раз в секунду
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[3];} //- нормальное напряжение АКБ авто, ACC выключено. - Короткая вспышка раз в секунду
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - Мигание по 0.8 сек
if (kalibrovkaNOW >= 1) {blink_mode = modes[6];} // режим калибровки
}
/* ***********************данные для справки****************************************************************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2];
0B00000001, //Короткая вспышка раз в секунду = modes[3];
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6];
*/
//**********************************************************************************************************
if (STARTUEM == 1) // когда крутим стартером ( заводимся)
{ //если включено в настройках
if (power_off_HUB_on_starting == 1){HUB = 0;} // выключаем питание на хаб в момент старта, если включено в настройках
if (power_off_OTG_on_starting ==1) {OTG = 0;} // выключаем массу на OTG в момент старта, если включено в настройках
}
if (kalibrovkaNOW <= 5) //если запущена активная стадия режима калибровки, то НЕ запускаем управление выходами а преходим в функцию выключения всех выходов.
{UPRAVLENIE_PINAMI();
}else {vykluchic_vse(); }
}} /*конец цикла void loop() и конец while (1)*/
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
/* _
______Сделано__________________________________________________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напряжение батареи больше UrabotyREM (11.8 В), то включаем еще и усилитель звука (выход REM) /но включаем его только на 30-60мин, если не заведены. После заводки счетчик постоянно обнуляется.
v92 сделанъ плавный пуск - определяем нужное состояние пинов без их предварительного дергания в начальное нулевое.
v94 сделанъ вывод на экран через переменную, а не напрямую. ЭТО позволит выводить информацию ЕЩЕ И В КОМ ПОРТ!!! <<<<<<<========================================
v94 Сделана задержка включения REM после холодного запуска, 15с. Через 10 с после начала загрузки идёт инициализация звуковой, в этот момент слышен ПУК
t00 новая ветка блока, по факту продолжение старой.
t02 поскольку аптаймблока в машине превысил 9999 минут, то переделан вывод аптайма 000:00 ( часы : минуты)
t03 дисплей тухнет через 3 сек после операции завершения.
t04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 (тестово). Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master
Без 2х библиотек одновременно работать не будет https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
t06 обработка напряжений выше 15,5 ( тушим экран и выключаем усилитель звука)
t07 в войд сетап задержки по 0,1с для инициализации дисплеев. Изменен алгоритм выключения - сначала тушим экран, потом все остальное( для таскера, чтобы паузу ставил и плей жал)
выключен Serial.print. display2.begin(SSD1306_ - перекинута инициализация на включение зажигания
t09 - перенесена строка проверки заведённой авто, в конец, перед проверкой перезаряда.
t10 - перешел на другую библиотеку для 1602 дисплея( newE) https://github.com/enjoyneering/LiquidCrystal_I2C. 128*64 не проверял.
t11 - в связи с тем, что у меня дребезжит контактная группа в машине, изменён алгоритм выключения выхода REM
t12 - возможность калибровки с записью в еепром, переделан метод вывода на дисплей ( теперь через две функции (формирования строк и непосредственно вывода.), а не в основном цикле), убрн вотчдог, как не имеющий практического смысла( пока что просто заккоментирован).
t13 поправлена Логика работы REM = когда стартуем flagREM = 3 Обработка логики работы REM в 538 строках.
t14 - введена новая переменная timeUntilBATOff = время до выключения питания на батарею планшета после выключения зажигания. 24ч = 86400000 (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) (2суток = 172800000) (4суток = 345600000)
timeUntilALLOff = время до полного выключение блока, после выключения зажигания (ACC) ((самозапитка для регистратора)- чтобы легче было менять это время в начале скетча.
увеличено время поддержки планшета включённым-timeUntilBATOff ( 2 суток после выкл АСС и еще 2 суток после этого до полного выключения блока)
m01-05 - Новая версия БП5mini. Переход на новые, хорошо себя зарекомендовавшие, дс-дс (mini360). Датчик холла и отг теперь управляются специализированной микросхемой-твердотельным реле. Из-за неё же теперь потеряна совместимость прошивок на БП5 (поскольку на управление холлом теперь нужен инверсный сигнал). Поэтому уже заодно поменял местами пины управления ОТГ и ХОЛЛА (физически). Фишка полностью совместима с БП5, БП4, БП3.
m6 - обработка статуса выхода REM переведена в отдельную функцию
m7 - поменян порядок включения элементов и их тайминги. Тестово. По идее, должно быть стабильнее, либо вообще никак не повлияет. Убраны лишние закомментированны строчки.
m11 - отг включаю сразу.
m12 - Сделал все основные тайминги настраиваемыми в начале скетча. Отдельно на включение, отдельно на выключение. Искать по строке ______НАСТРОЙКИ ТАЙМИНГОВ!!!______.
m14 - теперь тайминги в const unsigned long. В настройках скетча можно включить ресет хаба после каждого включения зажигания( reset_HUB_on_power_on )= передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
m15 - добавил тайминг timeWhileAkbLow = 40000; в настройки, увеличил с 20до 40с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
m18 - перевел все основные значения напряжений, таймингов и пинов на переменные. Облегчение портирования на разные аппаратные платформы. ----> Подготовка совместимости с БП7.
m19 - более дружественные комментарии.
m20-22 - переписывание скетча, чтобы не выводить через I2C шину информацию, для экономии энергопотребления и совместимости с БП7. Изменены режимы моргания встроенного светодиода ардуины ( тоже даёт экономию при выключенном зажигании 0,005А). Добавлено время обновления I2C дисплея в настройках пользователя.
m23 - исправлено. иногда не выключалась самозапитка при севшем АКБ! теряется 1 байт в конце PORTBregistr. Поправил - пока стандартными командами в void UPRAVLENIE_PINAMI_BPV.
m24-26 - оптимизация кода и комментариев.
m27 - добавлен спящий режим для атмеги при выключении зажигания. Уменьшено энергопотребление блока питания. когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. ________________________________________________________________
m28 - перенесена обработка режимов АСС (вкл, вЫкл) в отдельнее функции. Добавлены настройки для пользователя ( выключать ли питание на хаб при кручении стартером, убирать ли массу с IDюсб = OTG при кручении стартером)
m29 - добавлена задержка на определение, крутим ли мы стартером и прекратили ли крутить, искать по переменной STARTUEM
m30 - добавлена возможность канал датчика холла подключать к физической кнопке питания планшета ( для тех, у кого нету датчика холла).
m31 - добавлена возможность писать свои некоторые персональные настройки в энергонезависимую память (EEPROM), подробнее в настройках пользователя и в void RABOTA_z_EEPROM ().
m32 - Реализована возможность ВСЕ настройки пользователя писать в энергонезависимую память (EEPROM). Настройки НЕ совместимы с серсией m31, поэтому их надо переписать еще раз (brac_nastrojki_iz_EEPROM =1)
добавлена настройка vremia_uderjanija_najatoj_knopki_POWER. уменьшено время сна атмеги с 100 до 50, на потребление не повлияло.
m33 - добавлен в настройки пользователя тайминг на вЫключение питания на регистратор после выключения зажигания. Управляемый канал +12В можно использовать в своих целях.
m34 - добавлен режим ОТЛАДКИ. Если на столе или в машине блок питания не включает выходы, выключается после выключения зажигания, то
для проверки функций включаем OTLADKA = 1; при этом напряжения аккумулятора принимается за 14,50(В) НЕЗАВИСИМО от реального напряжения источника питания.
для штатной, нормальной работы блока питания ставим OTLADKA = 0;
m35 - добавлены комментарии, функция obrabotka_AKB поставлена первее obrabotka_ACC_ON,
в режим отладки добавлена возможность включения-выключения зажигания, теперь есть два типа отладки.
сделана переинициализация I2C дисплея при каждом включении зажигания
m36 - оптимизирован режим калибровки. Добавлена функция void vykluchic_vse()
m37 - если калибровка НЕ записана в EEPROM то выводим сообщение при первом включении блока на дисплей. Также в режиме калибровки начинает быстро мигать LED и отключаются выходы.
Изменен Алгоритм включения хаба.
Было reset_HUB_on_power_on = 1;OTG_timer_pri_vkl_ACC = 50 HUB_timer_pri_vkl_ACC = 2100
Стало reset_HUB_on_power_on = 0;OTG_timer_pri_vkl_ACC = 2500 HUB_timer_pri_vkl_ACC = 3500
Понижено до UnevykluczeniaREM = 13.4; повышено Uperezariadki = 15.7;
Обработка режима отладки перенесена в отдельную функцию void OBRABOTKA_REJIMA_OTLADKI и дополнена
Изменен алгоритм измерения напряжения, теперь берем среднее значение за (ilosc_usrednenij) циклов опроса, количество настраивается.
m38 - убран из поддержки дисплей адакрафт (Adafruit_SSD1306 128*64 закомментирован). Потреблял до 30% динамической памяти.
Калибровка полностью другого типа, теперь пишется в общий "пакет еепром".
В связи с этим напряжение вычисляется по другому алгоритму и другой формуле.
m39 - добавлено выключение усилителя звука ( REM) в режиме старта.
собственное потребление блока по 12 вольтам, без планшета (для БП5mini)
- при 10В +30 и +15 выключены = 0,014-0,017 А ( меньше, если выпаять светодиоды с ардуины; также много из этого потребляет CH340G)
- при 12В +30 и +15 включены = 0,056-0,060 A
- при 12В +30 включены +15 выключены (при питании батареи) = 0,020-0,021 A
________________________________________________________________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает
ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
//в версии m25 добавлена обязательная библиотека JeeLib library https://github.com/jcw/jeelib .
// НЕДОСТАЮЩИЕ БИБЛИОТЕКИ СКАЧАТЬ И CКОПИРОВАТЬ В ПАПКУ libraries, например d:\777\Soft\arduino\arduino-1.6.11\libraries\ .
|