Гуру
Регистрация: 16.04.2014
Возраст: 40
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
|
тестовая, для 5mini
PHP код:
byte ver = 15;// ( чем больше цифра, тем новее)
// дата правки 24.11.17.1556
// для 5mini версии блока питания.
// скетч проверен и записан на версии ардуино IDE 1,8,1 win7, 1.63 xp
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/enjoyneering/LiquidCrystal_I2C например
//в версии T04 добавлена поддержка дисплея Adafruit_SSD1306 128*64 Библиотеки (2 штуки ): https://codeload.github.com/adafruit/Adafruit_SSD1306/zip/master https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master
/* _
хотелки
______Сделано__________________________________________________
.
Контроль напряжения АКБ машины.
вывод информации на внешний дисплей по I2C, библиотека вывода на экран https://github.com/enjoyneering/LiquidCrystal_I2C и http://elchupanibrei.livejournal.com/27443.html
если в скетче в названии 0x27, значит библиотека старая.
активный вотчдог,
программная защита its716G(statepin)-тестово,
умное мигание встроенным светодиодом, в зависимости от напряжения АКБ и состояния АСС.
усреднение замеров по напряжению ACC и AKB, по 100 замерам.
информация на дисплее обновляется не постоянно, а каждые 350мс ( 0,35 с), чтобы не мельчешить.
Управление REM: если напруга батареи больше 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с, для машин с функцией подсветки пути домой. //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое.
________________________________________________________________
собственное потребление блока по 12 вольтам, без планшета
- при 10В +30 и +15 выключены = 0,02 А
- при 12В +30 и +15 включены = 0,092-0,1 А
- при 12В +30 включены +15 выключены (при питании батареи) = 0,06А
________________________________________________________________
поведение встроенного светодиода
низкое напряжение АКБ авто - коротко моргает
нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
нормальное напряжение, включено ACC, рабочий режим. - медленно моргает
ПРИМЕЧАЕНИЯ
-> strcpy(strokaIIold,strokaII); // strokaIIold = strokaII; так нельзя!!! надо так: strcpy(strokaIIold,strokaII); // копируем новую строку в старую
*/
//***************************************************************************************************************************************************
// Массив режимов работы светодиода
byte modes[] = {
0B00000000, //Светодиод выключен
0B11111111, //Горит постоянно
0B00111111, //Мигание по 0.8 сек
0B00000001, //Короткая вспышка раз в секунду
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)
};
uint32_t ms, ms1 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
//***************************************************************************************************************************************************
#include <Wire.h> // для экрана - I2C шина
#include <LiquidCrystal_I2C.h> // библиотека для экрана
#include <EEPROM.h> // для использования ЕЕПРОМ
//#include <avr/wdt.h> //Чтобы использовать функции Watchdog нужно подключить к проекту стандартную библиотеку ( https://geektimes.ru/post/255800/ )
char strokaI[32] = " ";// Массив для вывода 1 строки на дисплей , объявляем длиннее(32символа), чтобы не было глюков с отображением на экране
char strokaII[32] = " ";// Массив для вывода 2 строки на дисплей
// ЭТО нужно для вывода на 128*64 Adafruit_SSD1306 дисплей
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display2(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
// конец настройки для вывода на 128*64 Adafruit_SSD1306 дисплей
//LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка экрана для библиотеки LiquidCrystal_I2C2004V1
//Перед прошивкой скетча убедитесь в наличии нужных библиотек,например d:\777\Soft\arduino\arduino-1.6.11\libraries\LiquidCrystal_I2C\ https://github.com/marcoschwartz/LiquidCrystal_I2C например
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); // для newE описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347
float UakbONorOFF = 12.1;// в 258 строке == if ((15.5 > U_acc_real >= UaccONorOFF) && flagACC == 1) {UakbONorOFF = 11.5;} else {UakbONorOFF = 11.9;}
float UaccONorOFF = 11.4;//11.1 // напряжение порога сработки асс
float U_acc_real = 0; // реальное напряжение +ACC на входе делителя (A0)
float U_akb_real = 0; // реальное напряжение +30 на входе делителя (A1)
int Uacc = 0; //Читаем напругу с делителя ACC R4-R5 0-1024 analogRead(A0);
int Uakb = 0; ////Читаем напругу с делителя R2-R3 0-1024 analogRead(A1);
/*ноги ардуины*/
uint8_t PORTBregistr = 0; // Если у нас есть 8-битная переменная PORTBregistr, то мы можем присвоить её значение регистру PORTx, и тем самым установить ножки микроконтроллера в состояние, соответствующее значению переменной PORTBregistr
boolean SAMOZAPITKA = 0; // byte SAMOZAPITKApin = 9; /*управление самозапиткой блока питания IN4*///1 = есть самозапитка; 0 = нет самозапитки
boolean LED = 0; // Светодиод 1 = светит; 0 = не светит
boolean SLEEP=0; //byte SLEEPpin = 10; //1 = потух экран(есть масса на пине сна); 0 = штатная работа планшета (нет массы на пине сна)
boolean HUB = 0; //byte HUBpin = 11; /* PB3 управление транзюком питания хаба*/ // 0-хаб вЫключен, 1 - хаб включен
boolean OTG = 0; //byte OTGpin = 12; //1 = есть масса на OTG; 0 = нет массы на OTG
uint8_t PORTDregistr = 0; // 8-битная переменная PORTDregistr
boolean PlanshBAT = 0; //byte PlanshBATpin = 6; /* 10pin = PD6 = pin D6 PWM включить 1 канал KIW ..... управление питания БАТАРЕИ планшета через управляющую ногу IN2-5pin*/ //0 = нет питания; 1 = есть питание ( БАТАРЕИ планшета)
boolean REGISTRATOR = 0; //byte REGISTRATORpin = 4; /* 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)*/
boolean II_KIW_pin_POGO = 0; //byte II_KIW_pin_POGOpin = 2; /* 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка*/ //0 = нет 5V на POGO; 1 = есть 5V на POGO
boolean REM = 0; //byte REMpin = 7; /* 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3)*/ //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
//пины состояния ITS
boolean STATEpinI = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(питание KIW3312s-out2 и регистратор-out1) 0 = авария*/
boolean STATEpinII = 1; /*логический вход для отслеживания аварийной ситуации ITS716G(724G)(выход REM-out3 и самозапитка БП-out4 )1 = авар. сит.*/
/*логические переменные, используемые в коде*/
const boolean reset_HUB_on_power_on = 0; // передёргивать ли хаб при каждом включении зажигания, для решения проблемы с изикапом (STK1160) 1 - после ВКЛ АСС включить хаб, выключить на 0,5с и включить опять. 0 - просто включить хаб.
boolean flagACC = 0; /*признак включенного зажигания*/
byte flagAKB = 0; /* признак заряженной батареи*/
byte flagREM = 0; /* признак включенного выхода на усилитель звука (REM) 0 1 2*/
byte kalibrovkaNOW = 0; // признак того, что сейчас происходит калибровка встроенного вольтметра по АСС и АКБ.
byte kalibrovkaACC = EEPROM.read(0); // значение для калибровки для делителя АСС
byte kalibrovkaAKB = EEPROM.read(1); // значение для калибровки для делителя АКБ
boolean flagHALL = 0; /*флаг отработки морга экрана при холодном старте( flagHALL = 1 экран можно включать и выключать, датчик холла на планшете инициализировался)*/
/*счётчики времени*/
//НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!!______НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!! НАСТРОЙКИ ТАЙМИНГОВ!!!
const unsigned long timeUntilBATOff = 345600000; // время до выключения питания на батарею планшета после выключения зажигания., если прошло 48 часов, как выключили ACC // пауза (3600000 - 60мин) (60000 - 1 мин)(10800000=3ч) (1800000=5ч)
const unsigned long timeUntilALLOff = 172800000 + timeUntilBATOff; //время до полного выключение блока, после выключения зажигания (ACC)и после того, как выключится питание на батарею ) (2суток = 172800000)) (4суток = 345600000)
unsigned long timeBeforeRemOff = 1800000; /*1800000=30мин. Время, оставшееся до отключения выхода REM после включения зажигания и незаводки машины. ~209 строчка.*/
int timeAfterACC_starting = 7000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время кручения стартером
int timeAfterACC_accOFF = 2000; // не может быть меньше REM_timer_pri_vykl_ACC! //задержка перед началом процедуры выключения зажигания во время обычного выключения зажигания
int timeWhileAkbLow = 40000; //время, через которое начнётся полное выключение блока когда напряжение на АКБ очень низкое. /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
//тут настраиваем паузу при включении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
const unsigned long PlanshBAT_timer_pri_vkl_ACC = 1100;// пауза после включения ACC перед включением питания на батарею планшета
const unsigned long II_KIW_pin_POGO_timer_pri_vkl_ACC = 1400;// пауза после включения ACC перед включением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
const unsigned long OTG_timer_pri_vkl_ACC = 50;// пауза после включения ACC перед включением минуса на Y-OTG (включается определение ЮСБ перифирии планшетом.)
const unsigned long HUB_timer_pri_vkl_ACC = 2100;// пауза после включения ACC перед подачей питания на хаб. Значение должно быть больше либо равно II_KIW_pin_POGO_timer_pri_vkl_ACC.
const unsigned long REGISTRATOR_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на видеорегистратор
const unsigned long REM_timer_pri_vkl_ACC = 2500;// пауза после включения ACC перед включением питания +12В на REM (включение усилителя звука)
const unsigned long SLEEP_timer_pri_vkl_ACC = 3000; // пауза после включения ACC перед включением экрана
//тут настраиваем паузу при вЫключении зажигания ( АСС) и по истечении этого времени активируем/деактивируем
//соответствующий пин блока питания (время независимо друг от друга)
const unsigned long OTG_timer_pri_vykl_ACC = 2500; // пауза после вЫключения ACC перед вЫключением минуса на Y-OTG (вЫключается определение ЮСБ перифирии планшетом.)
const unsigned long II_KIW_pin_POGO_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед вЫключением +5V (POGO(USB) выхода для пина зарядки планшета (+5В пого или ЮСБ)
const unsigned long HUB_timer_pri_vykl_ACC = 5000; // пауза после вЫключения ACC перед убиранием питания с хаба. Значение должно быть меньше либо равно II_KIW_pin_POGO_timer_pri_vykl_ACC.
const unsigned long lcd_noBacklight_timer_pri_vykl_ACC = 7000; // пауза после вЫключения ACC перед убиранием подсветки I2C LSD дисплея (1602)
const unsigned long SLEEP_timer_pri_vykl_ACC = 0; // пауза после вЫключения ACC перед вЫключением экрана
const unsigned long REM_timer_pri_vykl_ACC = 1000;// не может быть больше timeAfterACC_accOFF и timeAfterACC_starting! Пауза после вЫключения ACC перед вЫключением питания +12В на REM (вЫключение усилителя звука), тут 1000 это на сколько раньше выключать выход REM перед остальными выключениями
//конец настроек таймингов.__________________________________________________________________________________________
unsigned long eventTime = 0;
unsigned long pauseTimeACC = millis(); // сброс времени для отсчета отключения самозапитки
unsigned long pauseTimeAKB = millis();
unsigned long pauseDisplay = 0; /* таймер для обновления информации на дисплее, чтобы не мерцал*/
unsigned long pauseTimeHALL = 140000; /* время паузы перед морганием-тушением экрана (для датчика холла)(равен времени загрузки планшета плюс секунд 10-20)= 2мин*/
unsigned long timeAfterACC = 5000; /* время после выключения зажигания, после истечения которого вырубается экран, хаб, y-otg*/
unsigned long TimerREM = 0; /* отсчет до выключения выхода REM при заглушенном авто и включенном зажигании.3600000 = час */
unsigned long TIMER = millis();
int 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
// PORTDregistr - обрабатывем регистры порта D атмеги
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 (II_KIW_pin_POGO == 1){ PORTDregistr |= (1 << 2); } else {PORTDregistr &= ~((1 << 2));} //bool II_KIW_pin_POGO = 0; //byte II_KIW_pin_POGOpin = 2; /* 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка*/ //0 = нет 5V на POGO; 1 = есть 5V на POGO
if (REM == 1){ PORTDregistr |= (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 ("PORTBregistr, BIN = " ); Serial.println (PORTBregistr, BIN); // вывели порт B атмеги на монитор порта
//Serial.print ("PORTDregistr, BIN = " ); Serial.println (PORTDregistr, BIN); // вывели порт D атмеги на монитор порта
PORTD = PORTDregistr; //прописали порту D атмеги в регистры команду на запись нулей и единиц.
PORTB = PORTBregistr; //прописали порту B атмеги в регистры команду на запись нулей и единиц.
}//конец UPRAVLENIE_PINAMI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup() //настройки
{
// wdt_disable(); //Отключение таймера watchdog
Serial.begin(115200);
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
if( kalibrovkaACC == 255 ){kalibrovkaACC=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию
if( kalibrovkaAKB == 255 ){kalibrovkaAKB=127;} // проверяем , прописана ни калибровка в еепром, если нет( 255), то берём значения по умолчанию =127
// настройки портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DDRD = 0b11010100; //работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*
pinMode(2, OUTPUT); //bool II_KIW_pin_POGO = 0; //byte II_KIW_pin_POGOpin = 2; 32pin = PD2 = pin D2 включить 2 канал KIW управление SS2 выходом питания +5V (2 канал kiw3312s) на пого пин(или USB), чтоб планшет думал, что идет зарядка //0 = нет 5V на POGO; 1 = есть 5V на POGO
pinMode(4, OUTPUT); //bool REGISTRATOR = 0; //byte REGISTRATORpin = 4; 2 pin = PD4 = pin D4 выход 12В для работы видеорегистратора (D4 -IN1)
pinMode(5, INPUT); //pinMode(STATEpinI, INPUT);
pinMode(6, OUTPUT); //pinMode(PlanshBATpin, OUTPUT); 16pin = PB4 = pin D12 MISO
pinMode(7, OUTPUT); //bool REM = 0; //byte REMpin = 7; 11pin = PD7 = pin D7 выход сигнала REM (+12v) (IN3) //0 = нет 12В на выходе REM; 1 = есть 12В на выходе REM
*/
//ПРИМЕР DDRB = 0b00100010;// pinMode(13, OUTPUT); pin9 =OUT //DDRx - регистр направления передачи данных светодиодик на плате ардуины
DDRB = 0b00111110; //работает!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*
pinMode(8, INPUT); //pinMode(STATEpinII, INPUT);
pinMode(9, OUTPUT); //pinMode(SAMOZAPITKApin, OUTPUT); 13pin = PB1 = pin D9
pinMode(10, OUTPUT); // pinMode(SLEEPpin, OUTPUT);
pinMode(11, OUTPUT); //byte HUBpin = 11; // PB3
pinMode(12, OUTPUT); //bool OTG = 0; //byte OTGpin = 12; 16pin = PB4 = pin D12 MISO управление транзюком OTG Q1 //1 = есть масса на OTG; 0 = нет массы на OTG
pinMode(13, OUTPUT); //светодиодик на плате ардуины
*/
//digitalWrite(5, 1); // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPinsdigitalWrite(ENC_PIN1, 1); // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
//digitalWrite(8, 1);
pinMode(A2, INPUT); // пин калибровки
digitalWrite(A2, 1); // подтяжка +5 пина калибровки
// конец настроек портов ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//настройки состояний при подаче питания на БП ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета
SAMOZAPITKA = 0; // digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на Y-OTG (8 pin PW1)
II_KIW_pin_POGO = 0; //digitalWrite(II_KIW_pin_POGOpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
// wdt_enable (WDTO_2S); // Запуск таймера watchdog: Для тестов не рекомендуется устанавливать значение менее 8 сек. Таймер будет считать ровно столько, сколько указано в константе. По истечении этого времени произойдет перезагрузка. /* Возможные значения для константы WDTO_15MS WDTO_30MS WDTO_60MS WDTO_120MS WDTO_250MS WDTO_500MS WDTO_1S WDTO_2S WDTO_4S WDTO_8S 2 s (WDTO_2S ATMega 8, 168, 328, 1280, 2560) ( wdt_enable (WDTO_8S);) https://geektimes.ru/post/255800/ https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer
//UPRAVLENIE_PINAMI(); //сделать пллавный пуск - определить нужное состояние пинов без их предварительного дергания --- настроили логику и отдали её в функцию UPRAVLENIE_PINAMI.
//конец настроек состояний при подаче питания на БП~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
}
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
void IntToCharI(int 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 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 выводим версию блока
// _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//вывод OTG HUB POGO HALL
strokaII[6]= OTG + '0';// вывод флага OTG 5 символ
strokaII[7]= HUB + '0';// вывод флага HUB 6 символ
strokaII[8]= II_KIW_pin_POGO + '0';// вывод флага II_KIW_pin_POGO (ПРИЗНАК ЗАРЯДКИ) 7 символ
strokaII[9]= !SLEEP + '0';// вывод флага flagHALL 8 символ (инверсно) 1-экран включен, 0 - выключен
FloatToCharIIIII (U_akb_real, &strokaII[11]); // вывод напряжения АКБ
//конец обработки 2й строки ______________________________________________________________________________________________________________________________________________________________________________
if (kalibrovkaNOW >= 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 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 analogReadU (byte averageFactor) //функция усреднённого чтения аналоговых входов (A0 A1)
{//void analogReadU
int newUacc = analogRead(A0); // замер для 5й версии
int newUakb = analogRead(A1); // замер для 5й версии
//int newUacc = analogRead(A1); // замер для 4й версии
//int newUakb = analogRead(A0); // замер для 4й версии
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(A2)== 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(A2)== 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) /но включаем его только на 1 час, если не заведены.*/
if (U_akb_real >= 11.8 && flagACC == 1 && flagREM == 0 ) {flagREM = 1; TimerREM = millis();} //если подзаряжен акб и включили зажигание - ВКЛЮЧАЕМ REM
if (U_akb_real >= 11.8 && flagACC == 1 && ( millis() - TimerREM >= timeBeforeRemOff )) {flagREM = 2 ;} // если кончилось время обратного отсчета - статус рем - 2.
//if (U_akb_real >= 13.7 && flagACC == 1){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= 11.8 && flagREM == 2 && flagACC == 0){ flagREM = 0;} // если восстановилось напряжение при выключенном зажигании - обнуляем статус РЕМ.
if (U_akb_real <= 11.8 && flagACC == 1){ flagREM = 2;} //если подсел акб при включенном зажигании - статус рем - 2.
if (U_akb_real >= 13.7 && flagACC == 1 ){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= 13.7 && flagREM == 3){ (flagREM = 1);TimerREM = millis();} // если завели машину, - ВКЛЮЧАЕМ REM, и постоянно обнуляем обратный отсчет вырубания РЕМ.
if (U_akb_real >= 15.5){flagREM = 2;}// проверка на перезаряд
if( flagREM == 0 || flagREM == 2){REM = 0;} // выключаем выход REM
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец отработки выхода REM~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}//void STATUS_REM()
void loop()
{while (1){//для ускорения void loop
analogReadU (5);//вызов функции усреднённого чтения аналоговых входов - прочитали сырые данные с АЦП A0 и А1, потом их усреднили(5)раз.
if (kalibrovkaNOW != 255 && digitalRead(A2)== 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;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ кусок кода ниже нужен для того, чтобы при включении и сразу выключении ACC при полностью выключенном планшете(холодный старт) экран мог тухнуть по сигналу датчика холла.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ( (millis() > pauseTimeHALL && flagHALL == 0 )|| ((millis() > 15000) && flagACC == 1))
{flagHALL = 1;} /*проверка отсчета при холодном старте при включении и сразу выключении ACC*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~проверка, выключили ли мы зажигание или просто стартуем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if ((U_akb_real - U_acc_real) >=5 )/*проверка, выключили ли мы зажигание или просто стартуем (1 - выключили заж, 0 - стартуем), нужно для того, чтобы не моргать экраном при стартере и быстро тушить экран при выключении зажигания.*/
{timeAfterACC = 2000;} //выключили зажигание /* 1000 1 - выключили зажигание. ЕСЛИ +15 ПРОПАДАЕТ ВО ВРЕМЯ СТАРТА, ТО ВМЕСТО 500 НАДО 5000 или вообще убрать этот блок if-else.*/
else {timeAfterACC = 7000; if (U_akb_real <=UakbONorOFF) {flagREM = 3;REM = 0;} }//стартуем /* 5000 0 - заводим машину (стартуем) или сел акб при включенном зажигании.*/ Логика работы REM в 537 строках
if (U_akb_real >= 15.5){timeAfterACC = 0;}
// ввести новую переменную int starting_mode = 1;//стартуем 0 = не_стартуем.
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// ------------========================== блок ACC ========================-----------------------------------------------------------------------------
// -----------------=========ВКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((15.5 > U_acc_real) && (U_acc_real >= UaccONorOFF) && flagACC == 0 && flagAKB == 1 ) //проверка напруги АСС и АКБ при флаге ACC = 0
{
flagACC = 1;
pauseTimeACC = millis();
pauseTimeAKB = millis();
//lcd.clear(); //очистка экрана не нужна со строковым выводом
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C); // display 2 or adres 0x3D для 1306 дисплея
lcd.begin(16, 2); //инициализация дисплея 1602 для newE библиотеки
display2.clearDisplay(); // для 1306 дисплея
display2.setTextColor(WHITE); // для 1306 дисплея
}
if (flagACC ==1 )
{// если flagACC == 1
if (millis() - pauseTimeACC >= PlanshBAT_timer_pri_vkl_ACC ) /* пауза 1.1c после включения ACC и потом делать следующ(пока включено ACC):*/
{
PlanshBAT = 1; //digitalWrite(PlanshBATpin, 1); /*включаем питание на батарею планшета = этим подаём 12В на DC-DC. На 1м канале dc-dc сразу появляется напряжение (3,8-4,2 - как настроено)*/
}
if (millis() - pauseTimeACC >= II_KIW_pin_POGO_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
II_KIW_pin_POGO = 1; //digitalWrite(II_KIW_pin_POGOpin, 1); /*включаем +5V (POGO(USB) нужно для распознавания планшетом признака зарядки. ( можно подавать на +5В USB кабеля (для тимуровской прошивки или если не используется датчик холла)*/
}
if (millis() - pauseTimeACC >= OTG_timer_pri_vkl_ACC ) /* пауза XXX после включения ACC и потом делать следующ(пока включено ACC):*/
{
OTG = 1; //digitalWrite(OTGpin, 1); /*включаем минус на Y-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 (millis() - pauseTimeACC >= SLEEP_timer_pri_vkl_ACC ) // пауза после включения ACC и потом делать следующ(пока включено ACC):
{
SLEEP = 0; //digitalWrite(SLEEPpin, 0); /*включаем экран*/
}
}// если flagACC == 1
STATUS_REM(); //зашли в функцию обработки статуса выхода REM
//-----------------=========ВЫКЛЮЧИЛИ ЗАЖИГАНИЕ=============----------------
if ((U_acc_real < UaccONorOFF) && flagACC == 1)
{
flagACC = 0; /*Выключили зажигание*/
pauseTimeACC = millis();
pauseTimeAKB = millis();
}
if (flagACC==0)
{// if (flagACC==0)
if (((millis() - pauseTimeACC) >= (timeAfterACC-REM_timer_pri_vykl_ACC)) ) // тут REM_timer_pri_vykl_ACC (1000)- это на сколько раньше выключать выход REM перед остальными выключениями
{
REM = 0; //digitalWrite(REMpin, 0); // сразу выключаем усилитель звука
flagREM = 0; /* выключаем флаг выхода REM*/ // обнуляем статус REM
}
/*пауза 7c или 2c после вЫключения ACC и потом делать следующ://через 5с после выключения зажигания вЫключаем минус на Y-OTG, ВЫключаем хаб, вЫключаем +5V (POGO(USB)), тушим экран (если прошло 2мин со старта БП)*/
if (((millis() - pauseTimeACC) >= (timeAfterACC+SLEEP_timer_pri_vykl_ACC)) )
{
if (flagHALL == 1)
{
SLEEP = 1;//digitalWrite(SLEEPpin, 1); /*тушим экран (если прошло 2 минуты с момента включения блока )*/
}
else
{SLEEP = 0;}//{digitalWrite(SLEEPpin, 0);}
}
if ( ((millis() - pauseTimeACC) >= (OTG_timer_pri_vykl_ACC+timeAfterACC)) ) /* 3000 пауза 3с чтобы не пукал усилитель*/
{
OTG = 0;//digitalWrite(OTGpin, 0); /*вЫключаем минус на Y-OTG (8 pin PW1)*/
}
if ( ((millis() - pauseTimeACC) >= (II_KIW_pin_POGO_timer_pri_vykl_ACC+timeAfterACC)) )
{
II_KIW_pin_POGO = 0;//digitalWrite(II_KIW_pin_POGOpin, 0); /*вЫключаем +5V зарядки. (POGO(USB))*/
}
if ( ((millis() - pauseTimeACC) >= (HUB_timer_pri_vykl_ACC+timeAfterACC)) )
{
HUB =0;//digitalWrite(HUBpin, 1); /* ВЫключаем хаб = подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб*/
}
if ( ((millis() - pauseTimeACC) >= (lcd_noBacklight_timer_pri_vykl_ACC+timeAfterACC)) )
{
lcd.noBacklight();/* тушим подсветку экрана для newE и для 0x27 // в 409 строке включение подсветки LCD дисплея*/
}
}// if (flagACC==0)
// -------------------------========================= блок АКБ ==========================-------------------------------------------------------------------------------
if (U_acc_real >= UaccONorOFF) {UakbONorOFF = 11.1;} else {UakbONorOFF = 11.9;} /*при включении зажигания напряжение самовырубания станет 11,5 вместо 11,9*/
if ((15.5 > 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 >15.5))/* ситуация, когда сел при работе ардуины аккумулятор, либо сел в процессе работы или простоя автомобиля, либо перезарядка > 15.5В*/
{
flagAKB = 0;//спустили флаг батареи
flagACC = 0;
pauseTimeACC = millis();
pauseTimeAKB = millis();
UakbONorOFF = 11.9;
//lcd.clear(); //очистка экрана
}
if ((millis() - pauseTimeAKB >= timeWhileAkbLow) && flagAKB == 0) /* если севший аккумулятор //через 40с вЫключаем питание на батарею планшета и вырубаем сам БП.*/
{
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); /*вЫключаем питание на батарею планшета */
OTG = 0; //digitalWrite(OTGpin, 0); /*вЫключаем минус на Y-OTG )*/
II_KIW_pin_POGO = 0; //digitalWrite(II_KIW_pin_POGOpin, 0); /*вЫключаем +5V (POGO(USB))*/
HUB = 0; //digitalWrite(HUBpin, 1); /* подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб*/
REM = 0; //digitalWrite(REMpin, 0); /* выключаем выход REM*/
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); /* выключаем питание на видеорегистратор*/
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); /*выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается*/
//delay (5000); /* задержка для аппаратного выключения*/
}
if (flagAKB == 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); /* задержка для аппаратного выключения*/
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец блока обработки напряжений АКБ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
// ******************************************отслеживания аварийной ситуации ITS716G (превышение по току по выходам out1-4)********************************************************************************************************************************************************************************
// *отслеживания аварийной ситуации ITS716G канал 1 (питание KIW3312s-out2 и регистратор-out1) 0 = норма 1 = авар. сит. //тогда моргаем 13 ногой код "1"
// *отслеживания аварийной ситуации ITS716G канал 2 (выход REM-out3 и самозапитка БП-out4 )0 = норма 1 = авар. сит. //тогда моргаем 13 ногой код "2"
if(SAMOZAPITKA==1 || PlanshBAT ==1 ||REM==1 || REGISTRATOR ==1) // если проц включал любой канал ITS
{
STATEpinI = digitalRead(5); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
STATEpinII = digitalRead(8);
if(STATEpinI == 0) { // и если пин защиты STATEpinI показал аварию
for (int i=0; i <= 300; i++) { //тогда моргаем 13 ногой код "1" 10 минут, если они прошли и асс ВКЛ, тогда еще раз и еще по кругу, пока неисправность не уйдёт
LED = 1; UPRAVLENIE_PINAMI(); delay(500); LED = 0; UPRAVLENIE_PINAMI(); delay(1493);
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета (in2)
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на Y-OTG (8 pin PW1)
II_KIW_pin_POGO = 0; //digitalWrite(II_KIW_pin_POGOpin, 0); //вЫключаем +5V (POGO(USB))
HUB = 0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
wdt_reset(); //Сброс таймера watchdog
}
} ;
if(STATEpinII == 0) { // и если пин защиты STATEpinII показал аварию
for (int i=0; i <= 150; i++) { //тогда моргаем 13 ногой ногой код "2" 10 минут, если они прошли и асс ВКЛ, тогда еще раз и еще по кругу, пока неисправность не уйдёт
LED = 1; UPRAVLENIE_PINAMI(); delay(500); LED = 0; UPRAVLENIE_PINAMI();delay(493); LED = 1; UPRAVLENIE_PINAMI(); delay(500); LED = 0; UPRAVLENIE_PINAMI(); delay(1493);
PlanshBAT = 0; //digitalWrite(PlanshBATpin, 0); //вЫключаем питание на батарею планшета (in2)
OTG = 0; //digitalWrite(OTGpin, 0); //вЫключаем минус на Y-OTG (8 pin PW1)
II_KIW_pin_POGO = 0; //digitalWrite(II_KIW_pin_POGOpin, 0); //вЫключаем +5V (POGO(USB))
HUB =0; //digitalWrite(HUBpin, 1); // подаем + на управляющий транзюк хаба, тот закрывается и не пускает +5В с KIW (2вых)на хаб = ВЫключаем хаб
REM = 0; //digitalWrite(REMpin, 0); // // выключаем выход REM
REGISTRATOR = 0; //digitalWrite(REGISTRATORpin, 0); // выключаем питание на видеорегистратор
SAMOZAPITKA =0; //digitalWrite(SAMOZAPITKApin, 0); //выключаем SAMOZAPITKApin, при этом пропадает управление на IN4, система ПОЛНОСТЬЮ обесточивается
wdt_reset(); //Сброс таймера watchdog
}
} ;
}
// **************************************************************************************************************************************************************************************************************************
*/
/******************************************индикация светодиодом и задержка вывода на дисплей********************************************************************************************************************************************************************************/
ms = millis();
// Событие срабатывающее каждые 125 мс
if ( ( ms - ms1 ) > 125 || ms < ms1 ) {
ms1 = ms;
// Режим светодиода ищем по битовой маске
if ( blink_mode & 1 << (blink_loop & 0x07) ) {LED = 1;}
else { LED = 0;}
blink_loop++;
}
// Событие срабатывающее каждые 350 мс
if ( ( ms - pauseDisplay ) > 350 || ms < pauseDisplay )
{
pauseDisplay = ms;
printDISPLAY(); // выводим на дисплей раз в 350( запуская фушкцию)
}
/*настраиваем режимы моргания встроенного светодиода ардуины*/
if (blink_mode != modes[5] || blink_mode != modes[5])
{
if (flagAKB == 0 ){blink_mode = modes[3];} // индикация напруги батареи на ардуинине.- низкое напряжение АКБ авто - коротко моргает
if (flagAKB == 1 && flagACC == 0) {blink_mode = modes[6];} //- нормальное напряжение АКБ авто, ACC выключено. - быстро моргает
if (flagAKB == 1 && flagACC == 1) {blink_mode = modes[2];} //- нормальное напряжение, включено ACC, рабочий режим. - медленно моргает
if (kalibrovkaNOW >= 1) {blink_mode = modes[1];} // режим калибровки
}
/* ***********************данные для справки****************************************************************
0B00000000, //Светодиод выключен blink_mode = modes[0];
0B11111111, //Горит постоянно blink_mode = modes[1];
0B00111111, //Мигание по 0.8 сек blink_mode = modes[2]; - нормальное напряжение, включено ACC, рабочий режим.
0B00000001, //Короткая вспышка раз в секунду = modes[3]; - низкое напряжение АКБ авто
0B00000101, //Две короткие вспышки раз в секунду
0B00010101, //Три короткие вспышки раз в секунду
0B01010101 //Частые короткие вспышки (4 раза в секунду)= blink_mode = modes[6]; - нормальное напряжение АКБ авто, ACC выключено.
*/
//**********************************************************************************************************
UPRAVLENIE_PINAMI();
//wdt_reset(); /*Сброс таймера watchdog*/
}} /*конец цикла void loop() и конец while (1)*/
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
//===========================================================================================================================================================================================================================================================================
|