//Project : Base station Aqua stop
//Date    : 09.04.2012
//Author  : Mike N. Vinogradov (Tech)           


//Chip type           : AVRmega16
//Clock frequency     : 8,000000 MHz  CKDIV8 off (Division=8)

#include <util/delay.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>
#include <avr/io.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdio.h>
#include <avr/sleep.h>
#include <avr/wdt.h>

#define F_OSC 8000000;
#define F_CPU 8000000UL  // 8 MHz

#define in1 ((PINB & (1<<0))?1:0) // читаем вход PINB0
#define in2 ((PINB & (1<<1))?1:0) // читаем вход PINB1
#define in3 ((PINB & (1<<2))?1:0) // читаем вход PINB2
#define in4 ((PINB & (1<<3))?1:0) // читаем вход PINB3
#define in5 ((PINB & (1<<4))?1:0) // читаем вход PINB4
#define in6 ((PINB & (1<<5))?1:0) // читаем вход PINB5
#define in7 ((PINB & (1<<6))?1:0) // читаем вход PINB6
#define in8 ((PINB & (1<<7))?1:0) // читаем вход PINB7

#define reset_botton ((PIND & (1<<2))?1:0) // читаем вход PIND2
#define set_botton ((PIND & (1<<3))?1:0) // читаем вход PIND3
#define hot_tap_botton ((PIND & (1<<7))?1:0) // читаем вход PIND7
#define cold_tap_botton ((PINC & (1<<0))?1:0) // читаем вход PINC0

//#define cold_tap ((PINC & (1<<0))?1:0) // читаем вход PINC0
//#define hot_tap ((PIND & (1<<7))?1:0) // читаем вход PIND7

#define cold_tap_on (PORTD|=(1<<6)) // ставим PINC0 в 1 (закрываем кран)
#define cold_tap_off (PORTD&=(~(1<<6))) // ставим PINC1 в 0 (открываем кран)

#define hot_tap_on (PORTD|=(1<<5)) // ставим PIND5 в 1 (закрываем кран)
#define hot_tap_off (PORTD&=(~(1<<5))) // ставим PIND5 в 0 (открываем кран)

#define beep_on (PORTD|=(1<<4)) // ставим PIND4 в 1 
#define beep_off (PORTD&=(~(1<<4))) // ставим PIND4 в 0 

#define gsm_on (PORTC|=(1<<1)) // ставим PINC1 в 1 
#define gsm_off (PORTC&=(~(1<<1))) // ставим PINC1 в 0 

#define max_in 8 //кол-во входов для датчиков протечек
unsigned char  In_status[max_in]={1,1,1,1,1,1,1,1}; // массив для хранения настроек входов с датчиков протечек
// "0"- вход выключен (не мониторится).
// "1"- вход включен (мониторится).
// Больше "1" - вход не сконфигурирован, считаем, что вход включен.

volatile unsigned char  tap_status[2]={0,0}; // массив для хранения состояния выходов управления шаровыми кранами {cold_tap,hot_tap}
// "0"- кран открыт.
// "1"- кран закрыт.
// Больше "1" -считаем, что кран закрыт

#define max_led 8 //кол-во светодиодов для отображения в матрице для состояния входов 
//unsigned char  led_status[max_led]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // массив для хранения состояния светодиодов
unsigned char  led_status[max_led]={0,0,0,0,0,0,0,0}; // массив для хранения состояния светодиодов
// "0"- светодиод погашен
// "1"- светодиод горит зеленым
// "2"- светодиод горит красным
// "3"- светодиод мигает

unsigned char  set_status=0; // загружено ли из eeprom настройки входов: 0 - нечего загружать, 1- загружено
volatile unsigned char  beep_count=0; // кол-во бипов из динамика, если ноль то не пищать
unsigned char  alarm=0; // флаг возникновения протечки на одном из мониторищихся датчиков (0- нет протечки, 1- есть протечка)

volatile unsigned char stolb = 0; // счетчик столбюцов для динамической индикации
#define stolb_number 3 // кол-во столбцов в матрице светодиодов (начиная с нулевого)
volatile unsigned char stolbec[stolb_number]; //состояние строк матрицы светодиодов в зависимости от столбца

volatile unsigned int reset_key=0; // счетчик времени нажатия на кнопку RESET
volatile unsigned int set_key=0; // счетчик времени нажатия на кнопку SET
volatile unsigned int hot_tap_key=0; // счетчик времени нажатия на кнопку вкл/выкл горячей воды
volatile unsigned int cold_tap_key=0; // счетчик времени нажатия на кнопку вкл/выкл холодной воды

volatile unsigned char botton_ready=0; // флаг необходимости обработки нажатия нопок (0- нечего обрабатывать, 1- кнопки отпущены и нужно обработать)

#define long_press 366// длительность долгого нажатия на клавишу в тиках таймера
#define quick_press 61 // длительность короткого нажатия на клавишу в тиках таймера

void USART_Init(unsigned int baud )
{
#define UBRRVAL ((F_CPU/(baud*16UL))-1)
//Set baud rate
UBRRL=UBRRVAL;		//low byte
UBRRH=(UBRRVAL>>8);	//high byte
//Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|	(0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);
//Enable Transmitter and Receiver
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}

//функция выдает в порт RS232 один символ
void USART_Send( unsigned int Txt )
{
  while (!(UCSRA&(1<<UDRE))){};
  UDR=Txt;		//send number to USART
}

//функция выдает в порт RS232 строку из сомволов
void USART_Send_srt(char* pTxT)
{
//unsigned char i=0;
 USART_Send(10);
 while( 1 )
 {
  if (! (*pTxT) )
  {
   USART_Send(10);
   USART_Send(13);
   break;
  }
   USART_Send((int)(*pTxT));
   ++pTxT;
 }
}

void load_settings(void){
//загружаем настройки входов и кранов из eeprom
unsigned int i;	

USART_Send_srt("load_settings");

if (eeprom_read_byte((uint8_t*)9)!=0xFF) { //проверяем есть ли сохраненные настройки входов в eeprom
 set_status=1; //есть
} else{
 set_status=0; //нет
 beep_count=1; // пищам один раз при включении
}
if (set_status!=0){ //читаем настройких входов из eeprom
 for (i=0;i<max_in;i++){
  In_status[i]=eeprom_read_byte((uint8_t*)i+10); //читаем значение входов из eeprom в массив
 }

 for (i=0;i<2;i++){ // читаем настройки кранов из eeprom
  tap_status[i]=eeprom_read_byte((uint8_t*)i+20); //читаем значение кранов из eeprom в массив
 }

}
}

void tap_setting(void){
// установка статусов кранов в зависимости от состояния массива

if (tap_status[0]==1){
 cold_tap_on; // (закрываем кран)
}else{
 cold_tap_off; // (открываем кран)
}

if (tap_status[1]==1){
 hot_tap_on; // (закрываем кран)
}else{
 hot_tap_off; // (открываем кран)
} 

}

void input_check(void){
// проверяем состояние входов, поднимаем аварию и изменяем состояние светодидов
unsigned int i;	
for (i=0;i<max_in;i++){ // перебираем массив с настройками входов
 if ((In_status[i]==1)) { //вход мониторится 
  switch (i){
   case 0: if ((in1==0) && (led_status[i]<2)) { // по входу обнаружена протечка и по нему не было протечек ранее (т.е. два раза не реагируем на один и тот же датчик)
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN1 ALARM");
		   }else if ((in1==1) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN1 BLINK ALARM");
		   }
		   break;
   case 1: if ((in2==0) && (led_status[i]<2)) {
            beep_count=60; 
			led_status[i]=2;
			alarm=1;
		    USART_Send_srt("IN2 ALARM");
		   }else if ((in1==2) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN2 BLINK ALARM");
		   }
		   break;// проверяем что на входе2 низкий уровень и выставляем пищалку и меняем состояние входа светодидода
   case 2: if ((in3==0) && (led_status[i]<2)) {
            beep_count=60; 
			led_status[i]=2;
			alarm=1;
		    USART_Send_srt("IN3 ALARM");
		   }else if ((in3==2) && (led_status[i]==2)){  // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN3 BLINK ALARM");
		   }
		   break;// проверяем что на входе3 низкий уровень и выставляем пищалку и меняем состояние входа светодидода
   case 3: if ((in4==0) && (led_status[i]<2)) {
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN4 ALARM");
		   }else if ((in4==2) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN4 BLINK ALARM");
		   }
		   break;
   case 4: if ((in5==0) && (led_status[i]<2)) {
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN5 ALARM");
		   }else if ((in5==1) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN5 BLINK ALARM");
		   }
		   break;
   case 5: if ((in6==0) && (led_status[i]<2)) {
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN6 ALARM");
		   }else if ((in6==2) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN6 BLINK ALARM");
		   }
		   break;
   case 6: if ((in7==0) && (led_status[i]<2)) {
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN7 ALARM");
		   }else if ((in7==2) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN7 BLINK ALARM");
		   }
		   break;
   case 7: if ((in8==0) && (led_status[i]<2)) {
            beep_count=60; // выставляем пищалку 
			led_status[i]=2; // и меняем состояние входа светодидода
			alarm=1; // поднимаем флаг аварии
		    USART_Send_srt("IN8 ALARM");
		   }else if ((in8==2) && (led_status[i]==2)){ // по входу протечка исчезла, начинаем мигать светодиодом
		    led_status[i]=3;
		    USART_Send_srt("IN8 BLINK ALARM");
		   }
		   break;
  }
  
 }
}

if (alarm==1){tap_status[0]=1;tap_status[1]=1;gsm_on;} //закрываем краны так как сработал один из входов датчиков протечек
}

void alarm_reset(void){
// сбрасываем флаг аварии если бипер отпищал

 if ((beep_count==0) && (alarm==1)){
  alarm=0; //сбасываем флаг аварии, так как нужные входы замигали
  gsm_off; // поднимаем на выходе в GSM сигнализации лог.1 (нет протечки)
  USART_Send_srt("ALARM AUTO RESET, SPEAKET OFF");
 }
}


SIGNAL(SIG_OVERFLOW0){
// прерывание от таймера0 с частотой 122гц или 0,008192 секунды
static unsigned char beep_flag=0; // флаг для генерации сигнала через бипер

 if (beep_count>0) {
  if (beep_count % 2==0){ // проверяем четное ли значение в beep_count
   if (beep_flag!=0){ // генерируем на порте сигнал
    beep_on;
    beep_flag=0;
   }else{
    beep_off;
    beep_flag=1;
   }

  }else{
   beep_off; // нечетное
  }
 }

// накапливаем в счетчиках время нажатия клавиш
if ((reset_botton==0) && (reset_key<long_press+2)) {reset_key++;} // счетчик времени нажатия на кнопку RESET
if ((set_botton==0) && (set_key<long_press+2)) {set_key++;} // счетчик времени нажатия на кнопку SET
if ((hot_tap_botton==0) && (hot_tap_key<long_press+2)) {hot_tap_key++;} // счетчик времени нажатия на кнопку вкл/выкл горячей воды
if ((cold_tap_botton==0) && (cold_tap_key<long_press+2)) {cold_tap_key++;} // счетчик времени нажатия на кнопку вкл/выкл холодной воды

if ( (botton_ready==0) && (reset_botton==1) && (set_botton==1) && (hot_tap_botton==1) && (cold_tap_botton==1) 
     && ( (reset_key>0) || (set_key>0) || (hot_tap_key>0) || (cold_tap_key>0) )) {
 // кнопки отпущены и были ранее нажаты
 // выставляем флаг необходимости обработки нажатия кнопок
 botton_ready=1;
 USART_Send_srt("BOTTON OUT");
}

// переходим к динамической индикации

 PORTC &=~(1<<7);// гасим все столбцы
 PORTC &=~(1<<6);// гасим все столбцы
 PORTC &=~(1<<5);// гасим все столбцы
 if(stolb >= stolb_number) {stolb = 0;} // если перебрали все столбцы, то сбрасываем счетчик столбцов в начало
 PORTA = stolbec[stolb]; // выводим в порт состояние строк
 ++stolb; // переключаем матрицу на следующий столбец
}

SIGNAL(SIG_OVERFLOW1){
// прерывание от таймера1 с частотой 0,12гц или 8,4 секунды
 if (beep_count>0) {
  beep_count--;
 }
TCNT1=65635-7801; // задаем отсчет чтобы вызвать прерывание на частоте 1Гц.
}

void set_leds(void){
// устанавливаем массив для отображения в матрице светодиодов в значения из массива состояния светодидодов (мэппинг)
unsigned int i;	
 for (i=0;i<stolb_number;i++){ // перебираем массив столбцов
  switch(stolb){
   case 0: {PORTC|=(1<<7);
            stolbec[0]=0;
            if (led_status[1]==1) {stolbec[0]|=(1<<0);}
	  	    if (led_status[0]==1) {stolbec[0]|=(1<<1);}
	 	    if (led_status[7]==1) {stolbec[0]|=(1<<2);}
	 	    if (led_status[6]==1) {stolbec[0]|=(1<<3);}
		    if (led_status[13]==1) {stolbec[0]|=(1<<4);}
		    if (led_status[12]==1) {stolbec[0]|=(1<<5);}
		    if (led_status[19]==1) {stolbec[0]|=(1<<6);}
		    if (led_status[18]==1) {stolbec[0]|=(1<<7);}
		    break;
		   }
   case 1: {PORTC|=(1<<6);
            stolbec[1]=0;
            if (led_status[3]==1) {stolbec[1]|=(1<<0);}
		    if (led_status[2]==1) {stolbec[1]|=(1<<1);}
		    if (led_status[9]==1) {stolbec[1]|=(1<<2);}
		    if (led_status[8]==1) {stolbec[1]|=(1<<3);}
		    if (led_status[15]==1) {stolbec[1]|=(1<<4);}
		    if (led_status[14]==1) {stolbec[1]|=(1<<5);}
		    if (led_status[21]==1) {stolbec[1]|=(1<<6);}
		    if (led_status[20]==1) {stolbec[1]|=(1<<7);}
		    break;
		   }
   case 2: {PORTC|=(1<<5);
            stolbec[2]=0;
            if (led_status[5]==1) {stolbec[2]|=(1<<0);}
		    if (led_status[4]==1) {stolbec[2]|=(1<<1);}
		    if (led_status[11]==1) {stolbec[2]|=(1<<2);}
		    if (led_status[10]==1) {stolbec[2]|=(1<<3);}
		    if (led_status[17]==1) {stolbec[2]|=(1<<4);}
		    if (led_status[16]==1) {stolbec[2]|=(1<<5);}
		    // if (led_status[21]==1) {stolbec[1]|=(1<<6);} // эти светодиоды не подключены
		    // if (led_status[20]==1) {stolbec[1]|=(1<<7);} // эти светодиоды не подключены
            break;
		   }
  }
 }
}
void save_eeprom_data(unsigned int eeprom_cell,unsigned int data){
//  сохраняем в EEPROM значение data в ячейку eeprom_cell
 while (eeprom_is_ready()!=1){};
  eeprom_write_byte((uint8_t*)eeprom_cell,data); // сохраняем в EEPROM
}

void save_settings(void){
//сохраняем настройки входов eeprom
// "0"- вход выключен (не мониторится).
// "1"- вход включен (мониторится).
// Если при этом на входе сработал датчик протечки или просто к входу не подключен датчик, то такой вход исключается из мониторинга: 
//  Если при нажатии кнопки SET вход имел высокий логический уровень (+12в) то считается что этот вход нужно мониторить, 
//  светодиод такого входа будет гореть зеленым. Если на входе был низкий уровень, то такой вход исключается из мониторинга и светодиод входа гаснет.

USART_Send_srt("save_settings");

while (eeprom_is_ready()!=1){};
eeprom_write_byte((uint8_t*)9,1); // сохраняем в EEPROM флаг сохраненных настроек

if (in1==1) { // датчик по входу1 подключен и не сработал
 save_eeprom_data(10,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(10,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in2==1) { // датчик по входу2 подключен и не сработал
 save_eeprom_data(11,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(11,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in3==1) { // датчик по входу3 подключен и не сработал
 save_eeprom_data(12,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(12,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in4==1) { // датчик по входу4 подключен и не сработал
 save_eeprom_data(13,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(13,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in5==1) { // датчик по входу5 подключен и не сработал
 save_eeprom_data(14,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(14,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in6==1) { // датчик по входу6 подключен и не сработал
 save_eeprom_data(15,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(15,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in7==1) { // датчик по входу7 подключен и не сработал
 save_eeprom_data(16,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(16,0); // сохраняем в EEPROM состояние мониторинга входа1
}
if (in8==1) { // датчик по входу8 подключен и не сработал
 save_eeprom_data(17,1); // сохраняем в EEPROM состояние мониторинга входа1
} else {
 save_eeprom_data(17,0); // сохраняем в EEPROM состояние мониторинга входа1
}
beep_count=1; // пищим два раза после сохранения

}

void main_init(void){
// настраиваем порты(ножки)
DDRB=0b00000000; //делаем входами все порты PINB.
PINB=0b00000000; //выводим на все входы PORTB 0, кроме 0
PORTB=0b00000000; // и подягиваем на +питания.

DDRA=0b11111111; //делаем выходами все порты PINA.
PINA=0b00000000; //выводим на все выходы PORTA 0
PORTA=0b00000000; // и подягиваем на +питания.

DDRD=0b01110000; //делаем входами с PIND0 по PIND3 и PIND7, с PIND4 по PIND6 делаем выходами.
PIND=0b00000000; //выводим на все выходы PORTD 0
PORTD=0b00000000; // и подягиваем на +питания.


DDRC=0b11111110; //делаем выходами все порты PINC, кроме PINC0
PINC=0b00000000; //выводим на все выходы PORTC 0
PORTC=0b00000000; // и подягиваем на +питания.

// настраиваем watchdog
// WDTCR=(1<<WDE); //Watchdog Enable
// WDTCR=|(1<<WDP2)|(1<<WDP1)|(0<<WDP0); //Watchdog Timer Prescale Select=1.0 s
// WDTCR = 0x00; /* Turn off WDT */

// настраиваем таймер0 для динамической индикации
TIMSK=(1<<TOIE0); // Timer/Counter0 Overflow Interrupt Enable
TCCR0=(1<<CS02); // Clock Select Bit Description=clkI/O/256 (From prescaler)

// настраиваем таймер1 для отсчета месяца и длительности бипера
TIMSK|=(1<<TOIE1); // Timer/Counter1, Overflow Interrupt Enable
TCCR1B=(1<<CS12)|(0<<CS11)|(1<<CS10); // clkI/O/1024 (From prescaler)
TCNT1=65635-7801; // задаем отсчет чтобы вызвать прерывание на частоте 1Гц.

//настраиваем UART
USART_Init(9600);
//настроили UART

USART_Send_srt("START");

sei(); // разрешаем прерывания глобально
}

/****************** ЛОВИМ ПРЕРЫВАНИЕ НА INT0 ПО НИЗКОМУ ПОТЕНЦИАЛУ (ДЛЯ ВЫХОДА ИЗ POWER-DOWN) ********************/
SIGNAL(INT0_vect){
}

void go_sleep(void){
 // вгоняем МК в POWER-DOWN
 USART_Send_srt("SLEEP ON");
 TCCR0=0; // выключаем таймер0
 TCCR1B =0; // выключаем таймер1
 cli(); // зарещаем прерывания глобально
 GICR|=(1<<INT0); // External Interrupt Request 0 Enable
 GIFR|=(1<<INTF0); // External Interrupt Flag 0
 DDRA=0b00000000; //делаем входами все порты PINA
 PINA=0b00000000; //выводим на все входы PORTA 0
 DDRB=0b00000000; //делаем входами все порты PINB
 PINB=0b00000000; //выводим на все входы PORTB 0
 DDRC=0b00000000; //делаем входами все порты PINC
 PINC=0b00000000; //выводим на все входы PORTC 0
 DDRD=0b00000000; //делаем входами все порты PIND
 PIND=0b00000000; //выводим на все входы PORTD 0
 //_delay_ms(100);
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sei(); // разрешаем прерывания глобально
 sleep_mode();
 _delay_ms(20);
 //cli(); // зарещаем прерывания глобально
 GICR=0;  //Disable Pin Change Interrupt
 GIFR=0;
 main_init();
 USART_Send_srt("SLEEP OFF");
}

void clean_and_reset(void){
unsigned int i;	
USART_Send_srt("clean_and_reset");
 for (i=9;i<22;i++){ //очищаем eeprom
  save_eeprom_data(i,0xFF);
 }

// включаем WD
wdt_enable(WDTO_15MS);

// ждем сброса
_delay_ms(1000);
}

void scan_botton(void){
// проверяем нажатие на кнопки и выполняем соответствующие действия
unsigned int i;	
USART_Send_srt("processing of buttons");
 if ((set_key>long_press) && (reset_key>long_press)){ // Долго вместе нажаты кнопки SET и RESET - сброс настроек устройства и сохранение их в EEPROM.
  clean_and_reset(); 
 } else if (set_key>long_press){ // Долго нажата кнопка SET - запоминается состояние входов  и сохраняется в EEPROM.
         save_settings();
        } else if (reset_key>long_press){ // Долго нажата кнопка RESET - переход устройства в POWERDOWN или выход из него с задержкой включения 3 секунды.
		       go_sleep();
			   _delay_ms(2000);
			   } else if (reset_key>quick_press) { // Быстро нажата кнопка RESET
			             // прекращается мигание светодиодов входов (на светодиодах отображается текущее состояние входов)
					   for (i=0;i<max_in;i++){ // перебираем массив с настройками входов
                        led_status[i]=0; // обнуляем состояние светодиодов
                       }
                       beep_count=0;
					   alarm=0;
					   USART_Send_srt("ALARM RESET AND LEDS RESET AND SPEAKET OFF");
					  }else if (hot_tap_key>quick_press){ // Быстро нажата кнопка "вкл/выкл гор. воды" - на сигнал управления краном горячей воды подается низкий уровень и кран закрывается, светодиод состояния крана горит красным. Повторное нажатие открывает кран, и светодиод состояния крана горит зеленым.
					         if (tap_status[1]==0){tap_status[1]=1;}else{tap_status[1]=0;};
							 USART_Send_srt("HOT TAP INVERT");
							} else if (cold_tap_key>quick_press){ // Быстро нажата кнопка "вкл/выкл хол. воды" - на сигнал управления краном холодной воды подается низкий уровень и кран закрывается, светодиод состояния крана горит красным. Повторное нажатие открывает кран, и светодиод состояния крана горит зеленым.
							        if (tap_status[0]==0){tap_status[0]=1;}else{tap_status[0]=0;};
									USART_Send_srt("COLD TAP INVERT");
								   }
botton_ready=0; // сбрасываем флаг необходимости обработки нажатия кнопок
reset_key=0; // обнуляем счетчик времени нажатия на кнопку RESET
set_key=0; // обнуляем счетчик времени нажатия на кнопку SET
hot_tap_key=0; // обнуляем счетчик времени нажатия на кнопку вкл/выкл горячей воды
cold_tap_key=0; // обнуляем счетчик времени нажатия на кнопку вкл/выкл холодной воды
}

int main(void)
{
main_init(); // инициализируем ножки, таймеры и перефирию
_delay_ms(3000);
load_settings(); //загружаем настройки из eeprom
tap_setting(); //устанавливаем краны в зависимости от начения в массиве
set_leds(); // устанавливаем светодиоды в матрице в зависимости от массива их состояния (меппинг)
while(1)
 { //начало бесконечного цикла
  input_check(); // проверяем состояние входов, поднимаем аварию и изменяем состояние светодидов
  tap_setting(); // устанавливаем краны в зависимости от начения в массиве
  set_leds(); // устанавливаем светодиоды в матрице в зависимости от массива их состояния (меппинг)
  alarm_reset(); // сбрасываем флаг аварии и переключаем светодиоды входов на мигание
  if (botton_ready==1) {scan_botton();} // проверяем нажатие кнопок
 };// конец бесконечного цикла
}// конец main
