Гуру
Регистрация: 16.04.2014
Возраст: 40
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
|
дублирую на всякий случай прошивку m38 в текстовом виде. Откатался почти 2 недели - стабильно себя ведет.
1250 строк, 130000 символов. Я в шоке, кто мне там ATtiny советовал?
PHP код:
const byte ver = 38;// ( чем больше цифра, тем новее) byte TipBlokaPitania = 255; // 177 - BP7. 255 - BP5mini, BP5mini2.1, BP5mini+2.2 //выбор типа блока питания. // дата правки 3.01.19.2117
// для 5mini, 5mini2.1, 5mini+2.2 версии блока питания. // скетч проверен и записан на версии ардуино IDE 1.9.0 1,8,1 win7, 1.63 xp, win10 // МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing
//Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И
const byte OTLADKA = 0; // режим ОТЛАДКИ. 0 = нормальная работа. 1 = отладка. 2 = отладка. // Если на столе или в машине блок питания не включает выходы, выключается послы выключения зажигания, то для проверки функций включаем OTLADKA = 1; // Для штатной, нормальной работы блока питания ставим OTLADKA = 0; // 1 - если напряжение ACC > 6В то считаем ACC=14,5В если AKB > 6В то считаем AKB=14,5В // 2 - режим отладки, при котором напряжение АКБ принято за 14.50. Напряжение АСС = 14.50 при включенном АСС и реальное напряжениие на линии АСС при вЫключенном. // 3 - режим отладки, при котором ВСЕГДА напряжения АСС и АКБ приняты за 14.50В
byte brac_nastrojki_iz_EEPROM = 0; // если вы хотите СОХРАНИТЬ свои настройки в энергонезависимую память(еепром), тогда ставим 1, 0 - берём значения из скетча, игнорируя память ( кроме калибровки), 2 - берем значения из памяти eeprom,(если память пустая, берем значения из скетча.) // 0 - 0 - берём значения из скетча, игнорируя память // 1 - сохраняем в EEPROM // 2 - берем значения из памяти eeprom игнорируя скетч byte reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. При 1 могут быть проблемы с определением флешки в хабе, отгда поставить 0. byte power_off_HUB_on_starting = 1; // выключать ли питание на хаб при старте авто ( 1- да, выключать) (0 - не выключать) byte power_off_OTG_on_starting = 1; // выключать ли массу на OTG при старте авто ( 1- да, выключать) (0 - не выключать) byte HALL_as_power_Switch = 0; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = vremia_uderjanija_najatoj_knopki_POWER. ДХ = Датчик Холла. unsigned long vremia_uderjanija_najatoj_knopki_POWER = 250; //если HALL_as_power_Switch = 1, то время "зажатия" (нажимания) кнопки питания планшета устанавливаем тут. 500 = 0,5с.
//НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________ // напряжения должны быть записаны ТОЛЬКО в XX.X формате, например 11.0 float Uperezariadki = 15.7; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто. float UrabotyREM = 11.8; // напряжение, выше которого будет работать усилитель звука, если акб не садился. float UnevykluczeniaREM = 13.4; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ. float Uakb_Kogda_ACC_vYkluczeno = 11.9; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС float Uakb_Kogda_ACC_vkluczeno = 11.1; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС float UaccONorOFF = 10.1; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным. //КОНЕЦ НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________НАСТРОЙКИ Пороговых напряжений!!!!!!!!_________ /*счётчики времени*/ //НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000) unsigned long timeBeforeRemOff = 1800000; // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ)
unsigned long timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером unsigned long timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания unsigned long timeWhileAkbLow = 45000; // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/ unsigned long pauseTimeHALL = 140000; // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин unsigned long vremia_obnovlenia_displeya = 250; // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея)
//тут настраиваем паузу при вКлючении зажигания ( АСС) и по истечении этого времени активируем/деактивируем //соответствующий пин блока питания (время независимо друг от друга) unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ) unsigned long OTG_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.) unsigned long HUB_timer_pri_vkl_ACC = 3500;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC. unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука) unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла) unsigned long I_dva_C_szina_ON_time = 150; //не используем? //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C.
//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем //соответствующий пин блока питания (время независимо друг от друга) unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.) unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ) unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC. unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла) unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 17000; // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602) unsigned long I_dva_C_szina_OFF_time = lcd_noBacklight_timer_pri_vykl_ACC + 3000; //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C. unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 1800000; // = timeUntilALLOff; пауза после вЫключения ACC перед вЫключением питания +12В на видеорегистратор // unsigned long REGISTRATOR_timer_pri_vYkl_ACC = 10000; = 10 секунд
unsigned long LONG_koefficient_delitelia_ACC =0; unsigned long LONG_koefficient_delitelia_AKB =0; float rezerv5 =0; float rezerv6 =0; float rezerv7 =00.00; //конец настроек таймингов.__________________________________________________________________________________________
//К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И // К О Н Е Ц Н А С Т Р О Й К И П О Л Ь З О В А Т Е Л Я П О Д С В О И П О Т Р Е Б Н О С Т И const int nachalnyj_address_dannyh_polzovatelja_v_eeprom = 2; // Переменная для хранения начального адреса еепром
struct myStruct_Znachenija_peremennyh_i_timingov // Создаем пользовательскую структуру { byte reset_HUB_on_power_on; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. byte power_off_HUB_on_starting ; // выключать ли питание на хаб при старте авто ( 1- да, выключать) byte power_off_OTG_on_starting; // выключать ли массу на OTG при старте авто ( 1- да, выключать) byte HALL_as_power_Switch ; // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с. float Uperezariadki ; // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто. float UrabotyREM ; // напряжение, выше которого будет работать усилитель звука, если акб не садился. float UnevykluczeniaREM ; // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ. float Uakb_Kogda_ACC_vYkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС float Uakb_Kogda_ACC_vkluczeno ; // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС float UaccONorOFF ; // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным. unsigned long timeUntilBATOff; // 4 байта unsigned long timeUntilALLOff; // 4 байта unsigned long timeBeforeRemOff; // 4 байта unsigned long timeAfterACC_starting; // 4 байта unsigned long timeAfterACC_accOFF ; // 4 байта unsigned long timeWhileAkbLow ; // 4 байта unsigned long pauseTimeHALL ; // 4 байта unsigned long vremia_obnovlenia_displeya ; // 4 байта unsigned long PlanshBAT_timer_pri_vkl_ACC; // 4 байта unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC; // 4 байта unsigned long OTG_timer_pri_vkl_ACC; // 4 байта unsigned long HUB_timer_pri_vkl_ACC; // 4 байта unsigned long REGISTRATOR_timer_pri_vkl_ACC; // 4 байта unsigned long REM_timer_pri_vkl_ACC; // 4 байта unsigned long SLEEP_timer_pri_vkl_ACC; // 4 байта unsigned long I_dva_C_szina_ON_time; // 4 байта unsigned long OTG_timer_pri_vykl_ACC ; // 4 байта unsigned long FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC ;// 4 байта unsigned long HUB_timer_pri_vykl_ACC; // 4 байта unsigned long SLEEP_timer_pri_vykl_ACC; // 4 байта unsigned long REM_timer_pri_vykl_ACC ; // 4 байта unsigned long lcd_noBacklight_timer_pri_vykl_ACC ; // 4 байта unsigned long I_dva_C_szina_OFF_time ; // 4 байта unsigned long vremia_uderjanija_najatoj_knopki_POWER ; unsigned long REGISTRATOR_timer_pri_vYkl_ACC ; unsigned long LONG_koefficient_delitelia_ACC ; unsigned long LONG_koefficient_delitelia_AKB ; float rezerv5 ; float rezerv6 ; float rezerv7 ; };
//*************************************************************************************************************************************************** // Массив режимов работы светодиода const byte modes[] = { 0B00000000, //Светодиод выключен 0B11111111, //Горит постоянно 0B00111111, //Мигание по 0.8 сек 0B00000001, //Короткая вспышка раз в секунду 0B00000101, //Две короткие вспышки раз в секунду 0B00010101, //Три короткие вспышки раз в секунду 0B01010101 //Частые короткие вспышки (4 раза в секунду) }; uint32_t ms, ms1 = 0; uint8_t blink_loop = 0; uint8_t blink_mode = 0; //*************************************************************************************************************************************************** #include <JeeLib.h> // Low power functions library // у кого ошибки компиляции! МОЮ сборку ардуино можно скачать тут https://drive.google.com/file/d/1oAzCQYh9XUnrhFRb314IWGtA45K7Vonh/view?usp=sharing ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup the watchdog //для сна #include <Wire.h> // для дисплея - I2C шина #include <LiquidCrystal_I2C.h> // библиотека для дисплея #include <EEPROM.h> // для использования ЕЕПРОМ //#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ ) char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей /*//13 ВРЕМЕННО ЗАКОММЕНТИРОВАНО ДЛЯ ОСВОБОЖДЕНИЯ ДИНАМИЧЕСКОЙ ПАМЯТИ // ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 4 Adafruit_SSD1306 display2(OLED_RESET); #define XPOS 0 #define YPOS 1 #define DELTAY 2 // конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей *///13 //Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347 // обьявляем переменные и задаём их начальные значениия float UakbONorOFF = 12.1; // напряжение порога сработки акб float U_acc_real = 7.0; // реальное напряжение +ACC на входе делителя float U_akb_real = 7.0; // реальное напряжение +30 на входе делителя int Uacc = 0; // напряжение с делителя ACC 0-1024 int Uakb = 0; // напряжение с делителя АКБ 0-1024 int cykly_usrednenij_U = 0; // служебный счетчик уже прошедших количеств замера напряжений int = 1024MAX long = 0 до 4,294,967,295MAX static int ilosc_usrednenij = 60; // Нужное количество замеров напряжений, после которого будет вычисляться среднее значение АКБ и АСС int = 1024MAX long = 0 до 4,294,967,295MAX float Uacc_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего float Uakb_TMP =0.00; // для хранения временного значения напряжения, нужно для вычисления среднего
//PORTB const byte SAMOZAPITKA_Pin = 9; // номер пина самозапитки блока const byte LED_Pin = 13; // номер пина встроенного светодиода индикации const byte OTG_Pin = 10; // номер пина управляющего микросхемой, управляющей режимом OTG const byte HUB_Pin = 11; // номер пина управляющего транзистором, управляющего Питанием ХАБа const byte SLEEP_Pin = 12; // номер пина управляющего микросхемой, которая даёт массу на пин сна ( датчик холла) //PORTD const byte PlanshBAT_Pin = 6; // номер пина управляющего микросхемой, управляющей питанием БАТАРЕЕЙ планшета (через управляющую ногу IN2-5pin )0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета) const byte REGISTRATOR_Pin = 4; // номер пина управляющего микросхемой управляющей питанием видеорегистратора const byte FIVE_Volt_OUT_na_POGO_or_USB_Pin = 2; // номер пина управляющего сном 2 преобразователя DC-DC (+5В) const byte REM_Pin = 7; // номер пина управляющего транзистором, управляющего Питанием ХАБа //логические состояния блока питания (какая ножка какой сигнал должна выдавать) uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки boolean LED = 0; // Светодиод 1 = светит; 0 = не светит boolean SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.) boolean HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен boolean OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG
uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета) boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/ boolean FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO boolean REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM static byte PINrawACC = A0; // замер для 5й версии static byte PINrawAKB = A1; // замер для 5й версии static byte PINkalibrovki = A2; // замер для 5й версии
//static byte PINrawACC = A7; // замер для 7й версии //static byte PINrawAKB = A8; // замер для 7й версии //static byte PINkalibrovki = A3; // замер для 7й версии //пины состояния ITS static byte STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/ static byte STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/
/*логические переменные, используемые в коде*/
byte flagACC = 0; /*признак включенного зажигания*/ byte flagAKB = 0; /* признак заряженной батареи*/ byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/ byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ. byte kalibrovkaACC = 255; // значение для калибровки для делителя АСС byte kalibrovkaAKB = 255; // значение для калибровки для делителя АКБ byte razreszenie_raboty_I_dva_C_sziny = 0; // Разрешили ли мы работать (инициализировали ли) I2C устройствам (дисплеи, звуковой процессор) в текущем цикле. 1 - инициализировали и разрешили, 0 - НЕ инициализировали и запретили 2 - НЕ ВКЛЮЧАЕМ ШИНУ byte flagHALL = 0; //флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался) byte STARTUEM = 0; //Стартует ли авто ( крутим ли стартером) 0- не крутим, 1 - крутим.
static byte vremia_sna_ATMEGI = 50; // sleep for XXX seconds - когда запретили работу I2C шины, запускаем сон каждый цикл(loop) на 0,1 сек. (0-200) Нужно для режима энергосбережения атмеги. unsigned long eventTime = 0; unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки unsigned long pauseTimeAKB = millis(); unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/ unsigned long timeAfterACC = 5000; /*базовое (для инициализации) , ни на что не влияет. Меняйте timeAfterACC_accOFF и timeAfterACC_starting ! время после выключения зажигания, после истечения которого вырубается экран, хаб, otg-режим*/ unsigned long TimerREM = 0; /*базовое (для инициализации) , ни на что не влияет. Отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */ unsigned long TIMER = millis(); /*базовое (для инициализации) , ни на что не влияет. */ unsigned long H = (millis()/3600000); // часы byte M = ((millis()-(H*3600000))/60000); //минуты //=========================================================================================================================================================================================================================================================================== //=========================================================================================================================================================================================================================================================================== //===========================================================================================================================================================================================================================================================================
void INIT_I2C () // запускаем инициализацию дисплеев на I2C шине { if (razreszenie_raboty_I_dva_C_sziny == 0) // переопрашиваем дисплеи I2C и ставим флаг, чтобы они работали. { lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки /*//13 display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея display2.clearDisplay(); // для 1306 дисплея display2.setTextColor(WHITE); // для 1306 дисплея *///13 // ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ТУТ надо будет включать питание на TDA7442 ! ! ! ! ! ! ! ! ! - для БП7 razreszenie_raboty_I_dva_C_sziny = 1; // разрешаем работу шины I2C } } void vykluchic_vse() // функция выключения всех выходов и напряжений с блока питания. { PORTBregistr = 0; // выключили всё SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; управление самозапиткой блока питания IN4//1 = есть самозапитка; 0 = нет самозапитки if (kalibrovkaNOW <= 5) {LED = 0;} // Светодиод 1 = светит; 0 = не светит В режиме калибровки не трогаем SLEEP=0; //byte SLEEPpin = ; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) ( также 0 означает ненажатую кнопку питания, если мы используем канал ДХ для управления кнопкой питания планшета.) HUB = 0; //byte HUBpin = 11; 0-хаб вЫключен, 1 - хаб включен OTG = 0; //byte OTGpin = ; //1 = есть масса на OTG; 0 = нет массы на OTG
PORTDregistr = 0; // выключили всё PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета) REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1) FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить управление SS2 выходом питания +5V на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM UPRAVLENIE_PINAMI(); // сказали регистрам исполнить " выключили всё ", вызвав функцию управления пинами }
void UPRAVLENIE_PINAMI() // функция перевода логических параметров в реальные состояния пинов // http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry // https://geektimes.ru/post/255744/ Ускоряем свою Arduino /* http://robotosha.ru/arduino/digitalwrite-optimizing-arduino.html */ {
// UPRAVLENIE_PINAMI ~~~//тут мы сначала пишем в переменную регистры, а потом сделаем PORTB = PORTBregistr; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PORTBregistr - обрабатывем регистры порта B атмеги
/* if (LED == 1 ){ PORTBregistr |= 1<<5; } //PORTB |= 1<<5; //установит "1" (сигнал высокого уровня) на выводе PB5. //digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) else { PORTBregistr &= ~(1<<5); } //PORTB &= ~(1<<5); //установит "0" (сигнал низкого уровня) на выводе PB5. //digitalWrite(13, LOW); // turn the LED off by making the voltage LOW if (SAMOZAPITKA == 1){ PORTBregistr |= (1 << 1); } else {PORTBregistr &= ~((1 << 1));} //PB1 управление самозапиткой блока питания IN4///1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html if (OTG == 1){ PORTBregistr |= (1 << 2); } else {PORTBregistr &= ~((1 << 2));} //byte SLEEPpin = 10; PB2 управление транзистор ом сна VT4 (на датчик холла)) //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна) if (HUB == 0) { PORTBregistr |= (1 << 3); } else {PORTBregistr &= ~((1 << 3));} //HUB =0;//byte HUBpin = 11; PB3 управление транзистор ом питания хаба // 1-есть питание, 0 - нет питания if (SLEEP == 0) { PORTBregistr |= (1 << 4); } else {PORTBregistr &= ~((1 << 4));} //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO // управление транзистор ом OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG */ digitalWrite(LED_Pin, LED); //управление встроенным светодиодом digitalWrite(SAMOZAPITKA_Pin, SAMOZAPITKA); // управление самозапиткой блока питания 1 = есть самозапитка; 0 = нет самозапитки //http://microsin.net/programming/avr/accessing-avr-ports-with-winavr-gcc.html digitalWrite(OTG_Pin, OTG); // управление OTG digitalWrite(HUB_Pin, !HUB); // управление транзистором питания хаба // 1-есть питание, 0 - нет питания digitalWrite(SLEEP_Pin, !SLEEP); // управление микросхемой, которая даёт массу на пин сна ( датчик холла) // PORTDregistr - обрабатывем регистры порта D атмеги //PORTD
digitalWrite(PlanshBAT_Pin, PlanshBAT); //управление питанием БАТАРЕЕЙ планшета (+4,0) digitalWrite(REGISTRATOR_Pin, REGISTRATOR); //управление питанием видеорегистратора (+12) digitalWrite(FIVE_Volt_OUT_na_POGO_or_USB_Pin, FIVE_Volt_OUT_na_POGO_or_USB); //управление вторым преобразователем DC-DC (+5В) digitalWrite(REM_Pin, REM); //управление выходом REM (+12) // if (PlanshBAT == 1){ PORTDregistr |= (1 << 6); } else {PORTDregistr &= ~((1 << 6));} //bool PlanshBAT = 0; //byte PlanshBATpin = 6; 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета) // if (REGISTRATOR == 1){ PORTDregistr |= (1 << 4); } else {PORTDregistr &= ~((1 << 4));} //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1) //if (FIVE_Volt_OUT_na_POGO_or_USB == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool FIVE_Volt_OUT_na_POGO_or_USB = 0; //byte FIVE_Volt_OUT_na_POGO_or_USBpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO // if (REM == 1){ PORTDregistr |= (1 << 7); } else {PORTDregistr &= ~((1 << 7));} //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
// Serial.print ("PORTB, BIN = " ); Serial.println (PORTB, BIN); // вывели порт B атмеги на монитор порта // Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта // Serial.print ("SAMOZAPITKA = " ); Serial.println (SAMOZAPITKA); //PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц. //PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup() //настройки при первой подаче питания. выполняются 1 раз. { Serial.begin(115200); // работа с ком портом, при необходимости раскомментировать if (brac_nastrojki_iz_EEPROM == 1) {brac_nastrojki_iz_EEPROM=0; RABOTA_z_EEPROM(); brac_nastrojki_iz_EEPROM=1;} //елии стоит режим записи значений в ЕЕПРОМ нужно считать калибровку из еепром, вытянуть ее из структуры и вписать ее со значениями пользователя из скетча. RABOTA_z_EEPROM(); //читаем значения пользователя из памяти процессора, или пишем, или берем по умолчанию, в зависимости от переменной brac_nastrojki_iz_EEPROM OBRABOTKA_KALIBROWKI(); // настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ DDRD = 0b11010100; // настройки порта D DDRB = 0b00111110; // настройки порта B pinMode(PINkalibrovki, INPUT); // пин калибровки digitalWrite(PINkalibrovki, 1); // подтяжка +5 пина калибровки // конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //vykluchic_vse(); /* PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на OTG (8 pin PW1) FIVE_Volt_OUT_na_POGO_or_USB = 0; //digitalWrite(FIVE_Volt_OUT_na_POGO_or_USBpin, 0); //вЫключаем +5V (POGO(USB)) HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзистор хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор */ //конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ } //=========================================================================================================================================================================================================================================================================== //=========================================================================================================================================================================================================================================================================== //===========================================================================================================================================================================================================================================================================
void displayDataToDISPLAY()//>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>> {//void displayDataToDISPLAY() //вывод на 2хстрочный дисплей LCM 1602 с I2C ( на базе расширителя портов PCF8574)<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //Serial.print("strokaI = "); Serial.println(strokaI); // раскомментить для вывода информации в ком порт для отладки lcd.setCursor(0, 0); lcd.print(strokaI); //Serial.print("strokaII = "); Serial.println(strokaII); // раскомментить для вывода информации в ком порт для отладки lcd.setCursor(0, 1); //2строка 0символ lcd.print(strokaII);
//вывод на 128*64 дисплей (Adafruit_SSD1306) первой строки /*//13 display2.clearDisplay(); // очистили буфер display2.setTextSize(1); // установили размер текста (1-4) display2.setCursor(0,0); // начальная точка вывода display2.println(strokaI); // скинули значение I строки в буфер 128*64 дисплея //вывод на 128*64 дисплей (Adafruit_SSD1306) второй строки display2.println(strokaII); // скинули значение II строки в буфер 128*64 дисплея if ( ((millis() - pauseTimeACC) >= (10000+timeAfterACC)) && (flagACC==0) ) // после 10 сек после выключения зажигания буфер будет чиститься перед выводом, соответственно на 128*64 Adafruit_SSD1306 дисплей выводиться ничего не будет Это нужно для того, чтобы ночью экран не светился ( так как пиксели активные и дают свет без подсветки) { display2.clearDisplay(); // очистили буфер } display2.display(); //эта строка выводит картинку 1306 из буфера на экран! *///13 //Вывод строк окончен.______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ }//void displayDataToDISPLAY() void IntToCharI(int num, char *text)//функция, возвращающая число в текстовый вид 0 1 { //text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. //text[1] = ((num/10)%10) + '0';// второе значение __0 text[2] = (num%10) + '0'; // третее значение ___ }
void IntToCharII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11 { //text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. text[0] = ((num/10)%10) + '0';// второе значение __0 text[1] = (num%10) + '0'; // третее значение ___ }
void IntToCharIII(int num, char *text)//функция, возвращающая число в текстовый вид 00 11 { text[0] = (num/100) + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. text[1] = ((num/10)%10) + '0';// второе значение __0 text[2] = (num%10) + '0'; // третее значение ___ } void IntToCharIIII(int num, char *text)//функция, возвращающая число в текстовый вид 0000 1111 { text[0] = (num/1000) + '0';//0 знач text[1] = (num/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. text[2] = ((num/10)%10) + '0';// второе значение __0 text[3] = (num%10) + '0'; // третее значение ___ }
void LongToCharIIIII(long num, char *text)//функция, возвращающая число в текстовый вид 0000 1111 { text[0] = (num/10000) + '0'; //0 знач text[1] = (num/1000)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. text[2] = ((num/100)%10) + '0';// второе значение __0 text[3] = ((num/10)%10) + '0'; // третее значение ___ text[4] = (num%10) + '0'; // 4е значение ___ }
void FloatToCharIIIII(float num, char *text)//функция, возвращающая число в текстовый вид 00.00 11.11 {
int Int = num*100; text[0] = (Int/1000) + '0';//0 знач 7896 text[1] = (Int/100)%10 + '0'; // первое значение _00 - эта строчка нужна для 3хзначного числа. text[2] = '.'; text[3] = ((Int/10)%10) + '0';// второе значение __0 text[4] = (Int%10) + '0'; // третее значение ___ }
void OBRABOTKA_KALIBROWKI() {//void OBRABOTKA_KALIBROWKI()
// проверка на прописанную в памяти калибровку if ( kalibrovkaACC == 255 || kalibrovkaAKB == 255 ) // проверяем, прописана ли калибровка в EEPROM и если нет, выводим сообщение. { if (LONG_koefficient_delitelia_ACC == 4294967295 || LONG_koefficient_delitelia_AKB == 4294967295) { sprintf(strokaI, "!!! KALIBROVKA ") ; IntToCharI(ver, &strokaII[1]); sprintf(strokaII, "NE PROPISANA !!!") ; INIT_I2C (); // запускаем инициализацию дисплеев и устройств на I2C шине displayDataToDISPLAY(); //>>>>>>>>>>>>>> Сформировали строки, теперь надо их вывести на дисплеи:>>>>>>>>>>>>>> delay (1000); // задержка чтобы успеть прочитать } } if (LONG_koefficient_delitelia_ACC == 4294967295) { LONG_koefficient_delitelia_ACC = 15364; } if (LONG_koefficient_delitelia_AKB == 4294967295){LONG_koefficient_delitelia_AKB = 15364;}
}//void OBRABOTKA_KALIBROWKI()
void RABOTA_z_EEPROM ()
{//void RABOTA_z_EEPROM () kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
//в любом случае считываем значения из еепром для считывания коэффициента коррекции делителей напряжений АСС и AKB myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM
if (brac_nastrojki_iz_EEPROM == 1)//1 - ПИШЕМ в еепром значения из скетча. {//if (brac_nastrojki_iz_EEPROM == 1) myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia[] = // Создаем массив объектов пользовательской структуры из значений, прописанных в скетче в настройках пользователя {//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia {// Создаем массив объектов reset_HUB_on_power_on , // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с определением изикапа (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб. power_off_HUB_on_starting , // выключать ли питание на хаб при старте авто ( 1- да, выключать) power_off_OTG_on_starting , // выключать ли массу на OTG при старте авто ( 1- да, выключать) HALL_as_power_Switch , // 0 - используем ДХ как обычно. 1 - вместо ДХ подключаем кнопку питания планшета. Если подключено как КНОПКА, то задержка перед нажатием "кнопки" после включения АСС это SLEEP_timer_pri_vkl_ACC, а после вЫключения SLEEP_timer_pri_vykl_ACC. Удержание нажатия = 0,5с. Uperezariadki, // напряжение, выше которого будет считаться, что идёт перезарядка аккумулятора авто. UrabotyREM, // напряжение, выше которого будет работать усилитель звука, если акб не садился. UnevykluczeniaREM, // напряжение, когда машина считается заведённой. Тогда, если завели машину, ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ. Uakb_Kogda_ACC_vYkluczeno, // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вЫключенном АСС Uakb_Kogda_ACC_vkluczeno , // напряжение, ниже которого АКБ авто будет считаться разряженным (севшим) при вКлюченном АСС UaccONorOFF, // напряжение порога сработки асс. Т.е. если на пин блока питания "вход АСС" подать ниже UaccONorOFF (11,1), то зажигание будет считаться выключенным. timeUntilBATOff, // время до выключения питания на батарею планшета после выключения зажигания., считаем ОТ момента выключения зажигания. если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч) timeUntilALLOff , // время до полного выключение блока, после выключения зажигания (ACC)и уже после того, как выключится питание на батарею планшета ) (2суток = 172800000)) (4суток = 345600000) timeBeforeRemOff , // 1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ( то есть сколько времени будет включён усилитель звука, если заглушить машину и просто слушать музыку, при нормальном АКБ) timeAfterACC_starting , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером timeAfterACC_accOFF , // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания timeWhileAkbLow, // 40000 время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/ pauseTimeHALL , // Для первого включения планшета. Раньше этого времени экран не будет тухнуть! Время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин vremia_obnovlenia_displeya, // Время, через которое будет обновляться информация на дисплей I2C (время обновления I2C дисплея) PlanshBAT_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания на батарею планшета FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC, // пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ) OTG_timer_pri_vkl_ACC , // пауза после включения ACC перед включением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (включается определение ЮСБ периферии планшетом.) HUB_timer_pri_vkl_ACC , // пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vkl_ACC. REGISTRATOR_timer_pri_vkl_ACC, // пауза после включения ACC перед включением питания +12В на видеорегистратор REM_timer_pri_vkl_ACC , // пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука) SLEEP_timer_pri_vkl_ACC, // пауза после включения ACC перед включением экрана планшета (масса на Датчик Холла) I_dva_C_szina_ON_time , //Время, через которое I2C шина включится после вКлючения зажигания - начнётся передача по шине I2C. OTG_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением минуса на OTG ( 4й контакт ЮСБ разъема на планшете) (вЫключается определение ЮСБ периферии планшетом.) FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ) HUB_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно FIVE_Volt_OUT_na_POGO_or_USB_timer_pri_vykl_ACC. SLEEP_timer_pri_vykl_ACC , // пауза после вЫключения ACC перед вЫключением экрана планшета (масса на Датчик Холла) REM_timer_pri_vykl_ACC , // не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями lcd_noBacklight_timer_pri_vykl_ACC, // 7000 пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602) I_dva_C_szina_OFF_time, //Время, которое I2C шина работает после вЫключения зажигания, потом - закончится передача по шине I2C. vremia_uderjanija_najatoj_knopki_POWER, REGISTRATOR_timer_pri_vYkl_ACC, LONG_koefficient_delitelia_ACC, LONG_koefficient_delitelia_AKB, rezerv5, rezerv6, rezerv7 }// конец Создаем массив объектов };//myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia EEPROM.put(nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia); // ПИШЕМ пакет данных в EEPROM из созданнго массива (znachenija_polzovatelia) начиная с адреса (nachalnyj_address_dannyh_polzovatelja_v_eeprom) }//if (brac_nastrojki_iz_EEPROM == 1) if (brac_nastrojki_iz_EEPROM == 2) //2 - берем значения из памяти eeprom, игнорируя скетч (если память пустая, берем(оставляем) значения из скетча.) {//if (brac_nastrojki_iz_EEPROM == 2) myStruct_Znachenija_peremennyh_i_timingov znachenija_polzovatelia; // В переменную znachenija_polzovatelia будем считывать данные из EEPROM EEPROM.get (nachalnyj_address_dannyh_polzovatelja_v_eeprom, znachenija_polzovatelia); // теперь считанные данные из переменной znachenija_polzovatelia вытаскиваем и присваеваем соответственной переменоой //но только ЕСЛИ reset_HUB_on_power_on равно 0 или 1 ( косвенный признак нормально записанных данных в ЕЕПРОМ) if (znachenija_polzovatelia.reset_HUB_on_power_on<2 || kalibrovkaNOW >= 14) { //if znachenija_polzovatelia.reset_HUB_on_power_on) reset_HUB_on_power_on = znachenija_polzovatelia.reset_HUB_on_power_on; power_off_HUB_on_starting = znachenija_polzovatelia.power_off_HUB_on_starting; power_off_OTG_on_starting = znachenija_polzovatelia.power_off_OTG_on_starting; HALL_as_power_Switch = znachenija_polzovatelia.HALL_as_power_Switch; Uperezariadki = znachenija_polzovatelia.Uperezariadki; UrabotyREM = znachenija_polzovatelia.UrabotyREM; UnevykluczeniaREM = znachenija_polzovatelia.UnevykluczeniaREM; Uakb_Kogda_ACC_vYkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vYkluczeno; Uakb_Kogda_ACC_vkluczeno = znachenija_polzovatelia.Uakb_Kogda_ACC_vkluczeno; UaccONorOFF = znachenija_polzovatelia.UaccONorOFF; timeUntilBATOff = znachenija_polzovatelia.timeUntilBATOff; timeUntilALLOff = znachenija_polzovatelia.timeUntilALLOff; timeBeforeRemOff = znachenija_polzovatelia.timeBeforeRemOff; timeAfterACC_starting = znachenija_polzovatelia.timeAfterACC_starting; timeAfterACC_accOFF = znachenija_polzovatelia.timeAfterACC_accOFF; timeWhileAkbLow = znachenija_polzovatelia.timeWhileAkbLow; pauseTimeHALL = znachenija_polzovatelia.pauseTimeHALL; vremia_obnovlenia_displeya = znachenija_polzovatelia.vremia_obnovlenia_displeya; PlanshBAT_timer_pri_vkl_ACC = znachenija_polzovatelia.PlanshBAT_timer_pri_vkl_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% динамической памяти. Калибровка полностью другого типа, теперь пишется в общий "пакет еепром". В связи с этим напряжение вычисляется по другому алгоритму и другой формуле. собственное потребление блока по 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\ .
|