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