#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal _lcd1(12, 11, 8, 7, 6, 5);
int _dispTempLength1=0;
boolean _isNeedClearDisp1;
float _gtv1;
bool _gtv2;
float _gtv3;
bool _gtv4;
float _gtv5 = 0;
bool _trgs2 = 0;
int _disp3oldLength = 0;
int _disp11oldLength = 0;
int _disp12oldLength = 0;
int _disp13oldLength = 0;
int _disp4oldLength = 0;
bool _gen2I = 0;
bool _gen2O = 0;
unsigned long _gen2P = 0UL;
int _disp5oldLength = 0;
bool _SEEPR4OSN = 0;
bool _bounseInputD17S = 0;
bool _bounseInputD17O = 0;
unsigned long _bounseInputD17P = 0UL;
bool _tim2I = 0;
bool _tim2O = 0;
unsigned long _tim2P = 0UL;
bool _gen5I = 0;
bool _gen5O = 0;
unsigned long _gen5P = 0UL;
bool _gen1I = 0;
bool _gen1O = 0;
unsigned long _gen1P = 0UL;
int _disp9oldLength = 0;
int _disp1oldLength = 0;
int _disp7oldLength = 0;
int _disp8oldLength = 0;
int _disp2oldLength = 0;
int _disp10oldLength = 0;
bool _bounseInputD16S = 0;
bool _bounseInputD16O = 0;
unsigned long _bounseInputD16P = 0UL;
bool _count3I = 0;
int _count3_Value = 0;
bool _count3MaxLO = 0;
bool _bounseInputD18S = 0;
bool _bounseInputD18O = 0;
unsigned long _bounseInputD18P = 0UL;
bool _gen3I = 0;
bool _gen3O = 0;
unsigned long _gen3P = 0UL;
bool _count1I = 0;
bool _count1_SCST = 0;
int _count1_Value = 0;
bool _count1MaxLO = 0;
int _disp6oldLength = 0;
void setup()
{
    pinMode(16, INPUT_PULLUP);
    pinMode(17, INPUT_PULLUP);
    pinMode(18, INPUT_PULLUP);
    pinMode(9, OUTPUT);
    digitalWrite(9, 0);
    pinMode(1, OUTPUT);
    digitalWrite(1, 0);
    pinMode(4, OUTPUT);
    digitalWrite(4, 0);
    _lcd1.begin(16, 4);
    _bounseInputD18O =  digitalRead(18);
    _bounseInputD16O =  digitalRead(16);
    _bounseInputD17O =  digitalRead(17);
}
void loop()
{
    if (_isNeedClearDisp1) 
    {
        _lcd1.clear();
        _isNeedClearDisp1= 0;
    }
    bool  _bounceInputTmpD17 =  (digitalRead (17));
    if (_bounseInputD17S)
    {
        if (millis() >= (_bounseInputD17P + 40))
        {
            _bounseInputD17O= _bounceInputTmpD17;
            _bounseInputD17S=0;
        }
    }
    else
    {
        if (_bounceInputTmpD17 != _bounseInputD17O)
        {
            _bounseInputD17S=1;
            _bounseInputD17P = millis();
        }
    }
    bool  _bounceInputTmpD16 =  (digitalRead (16));
    if (_bounseInputD16S)
    {
        if (millis() >= (_bounseInputD16P + 40))
        {
            _bounseInputD16O= _bounceInputTmpD16;
            _bounseInputD16S=0;
        }
    }
    else
    {
        if (_bounceInputTmpD16 != _bounseInputD16O)
        {
            _bounseInputD16S=1;
            _bounseInputD16P = millis();
        }
    }
    bool  _bounceInputTmpD18 =  (digitalRead (18));
    if (_bounseInputD18S)
    {
        if (millis() >= (_bounseInputD18P + 40))
        {
            _bounseInputD18O= _bounceInputTmpD18;
            _bounseInputD18S=0;
        }
    }
    else
    {
        if (_bounceInputTmpD18 != _bounseInputD18O)
        {
            _bounseInputD18S=1;
            _bounseInputD18P = millis();
        }
    }
    //Плата:1
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz(_gtv3,0))) + (String(" CYCLES"))))).length();
        if (_disp4oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp4oldLength = _dispTempLength1;
        _lcd1.setCursor(0, 1);
        _lcd1.print(((((_floatToStringWitRaz(_gtv3,0))) + (String(" CYCLES")))));
    }
     else 
    {
        if (_disp4oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp4oldLength = 0;
        }
    }
    if (1) 
    {
        _dispTempLength1 = ((String("U="))).length();
        if (_disp1oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp1oldLength = _dispTempLength1;
        _lcd1.setCursor(0, 0);
        _lcd1.print((String("U=")));
    }
     else 
    {
        if (_disp1oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp1oldLength = 0;
        }
    }
    if (!(_bounseInputD16O)) 
    {
         if (! _gen2I) 
        {
            _gen2I = 1;
            _gen2O = 1;
            _gen2P = millis();
        }
    }
     else 
    {
        _gen2I = 0 ;
        _gen2O= 0;
    }
    if (_gen2I) 
    {
          if (_isTimer (_gen2P , 1000)) 
        {
             _gen2P = millis();
            _gen2O = ! _gen2O;
        }
    }
    if (!(_bounseInputD17O)) 
    {
         if (! _gen3I) 
        {
            _gen3I = 1;
            _gen3O = 1;
            _gen3P = millis();
        }
    }
     else 
    {
        _gen3I = 0 ;
        _gen3O= 0;
    }
    if (_gen3I) 
    {
          if (_isTimer (_gen3P , 1000)) 
        {
             _gen3P = millis();
            _gen3O = ! _gen3O;
        }
    }
    if (_gtv4)
    {
        _count1_Value = 0;
    }
     else 
    {
        if (_gen2O)
        {
            if (! _count1I) 
            {
                _count1I = 1;
                _count1_Value = _count1_Value + 1;
            }
        }
         else 
        {
            _count1I = 0;
        }
        if (_gen3O)
        {
            if (! _count1_SCST) 
            {
                _count1_SCST = 1;
                _count1_Value = _count1_Value - 1;
            }
        }
         else 
        {
            _count1_SCST = 0;
        }
    }
    _count1MaxLO = _count1_Value >= 30;
    _gtv5 = _count1_Value;
    _gtv4 = _count1MaxLO;
    if(((!(_bounseInputD16O)) || (!(_bounseInputD17O)))) 
    {
        _tim2O = 1;
        _tim2I = 1;
    }
     else 
    {
         if(_tim2I) 
        {
            _tim2I = 0;
            _tim2P = millis();
        }
         else 
        {
             if (_tim2O) 
            {
                if (_isTimer(_tim2P, 3000)) _tim2O = 0;
            }
        }
    }
    if (_tim2O) 
    {
        _dispTempLength1 = (((_floatToStringWitRaz(_gtv5,0)))).length();
        if (_disp5oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp5oldLength = _dispTempLength1;
        _lcd1.setCursor(7, 1);
        _lcd1.print(((_floatToStringWitRaz(_gtv5,0))));
    }
     else 
    {
        if (_disp5oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp5oldLength = 0;
        }
    }
    if(!(_bounseInputD18O))
    {
         if(!_SEEPR4OSN)
        {
            (updateFloatToEEPROM(0, 0, 0x0, (_gtv5)));
            _SEEPR4OSN=1;
        }
    }
    else
    {
         if(_SEEPR4OSN)
        {
            _SEEPR4OSN=0;
        }
    }
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz(((analogRead (6)))/(73.07),1))) + (String("V"))))).length();
        if (_disp11oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp11oldLength = _dispTempLength1;
        _lcd1.setCursor(5, 3);
        _lcd1.print(((((_floatToStringWitRaz(((analogRead (6)))/(73.07),1))) + (String("V")))));
    }
     else 
    {
        if (_disp11oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp11oldLength = 0;
        }
    }
    if (((analogRead (0))) <= ((analogRead (6)))) 
    {
        if (! _gen5I)
        {
            _gen5I = 1;
            _gen5O = 1;
            _gen5P = millis();
        }
    }
     else 
    {
        _gen5I = 0 ;
        _gen5O= 0;
    }
     if (_gen5I &&  _gen5O)   _gen5O = !(_isTimer(_gen5P , 10));
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz(((analogRead (5)))/(73.07),1))) + (String("V"))))).length();
        if (_disp8oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp8oldLength = _dispTempLength1;
        _lcd1.setCursor(5, 2);
        _lcd1.print(((((_floatToStringWitRaz(((analogRead (5)))/(73.07),1))) + (String("V")))));
    }
     else 
    {
        if (_disp8oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp8oldLength = 0;
        }
    }
    if (((analogRead (0))) >= ((analogRead (5)))) 
    {
        if (! _gen1I)
        {
            _gen1I = 1;
            _gen1O = 1;
            _gen1P = millis();
        }
    }
     else 
    {
        _gen1I = 0 ;
        _gen1O= 0;
    }
     if (_gen1I &&  _gen1O)   _gen1O = !(_isTimer(_gen1P , 10));
    if(_gen5O) _trgs2 = 1;
    if(_gen1O) _trgs2 = 0;
    if (_gtv2)
    {
        _count3_Value = 0;
    }
     else 
    {
        if (_trgs2)
        {
            if (! _count3I) 
            {
                _count3I = 1;
                _count3_Value = _count3_Value + 1;
            }
        }
         else 
        {
            _count3I = 0;
        }
    }
    _count3MaxLO = _count3_Value >= 35;
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz((readFloatFromEEPROM(0, 0, 0x0)),0))) + (String(" MAX"))))).length();
        if (_disp6oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp6oldLength = _dispTempLength1;
        _lcd1.setCursor(10, 1);
        _lcd1.print(((((_floatToStringWitRaz((readFloatFromEEPROM(0, 0, 0x0)),0))) + (String(" MAX")))));
    }
     else 
    {
        if (_disp6oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp6oldLength = 0;
        }
    }
    digitalWrite(4, (_count3_Value) >= ((readFloatFromEEPROM(0, 0, 0x0))));
    if (!(((_trgs2) || ((_count3_Value) >= ((readFloatFromEEPROM(0, 0, 0x0))))))) 
    {
        _dispTempLength1 = ((String("DISCH"))).length();
        if (_disp13oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp13oldLength = _dispTempLength1;
        _lcd1.setCursor(11, 2);
        _lcd1.print((String("DISCH")));
    }
     else 
    {
        if (_disp13oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp13oldLength = 0;
        }
    }
    if (((_trgs2) || ((_count3_Value) >= ((readFloatFromEEPROM(0, 0, 0x0)))))) 
    {
        _dispTempLength1 = ((String("CHARG"))).length();
        if (_disp12oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp12oldLength = _dispTempLength1;
        _lcd1.setCursor(11, 2);
        _lcd1.print((String("CHARG")));
    }
     else 
    {
        if (_disp12oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp12oldLength = 0;
        }
    }
    digitalWrite(9, ((_trgs2) || ((_count3_Value) >= ((readFloatFromEEPROM(0, 0, 0x0))))));
    _gtv3 = _count3_Value;
    _gtv2 = _count3MaxLO;
    digitalWrite(1, !(_trgs2));
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz(((analogRead (0)))/(73.07),1))) + (String("V"))))).length();
        if (_disp9oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp9oldLength = _dispTempLength1;
        _lcd1.setCursor(2, 0);
        _lcd1.print(((((_floatToStringWitRaz(((analogRead (0)))/(73.07),1))) + (String("V")))));
    }
     else 
    {
        if (_disp9oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp9oldLength = 0;
        }
    }
    _gtv1 = ((map(((analogRead (1))), (512), (920), (0), (1023))))/(102.3);
    if (1) 
    {
        _dispTempLength1 = ((String("I="))).length();
        if (_disp2oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp2oldLength = _dispTempLength1;
        _lcd1.setCursor(8, 0);
        _lcd1.print((String("I=")));
    }
     else 
    {
        if (_disp2oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp2oldLength = 0;
        }
    }
    if (1) 
    {
        _dispTempLength1 = (((((_floatToStringWitRaz(_gtv1,1))) + (String("A"))))).length();
        if (_disp3oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp3oldLength = _dispTempLength1;
        _lcd1.setCursor(11, 0);
        _lcd1.print(((((_floatToStringWitRaz(_gtv1,1))) + (String("A")))));
    }
     else 
    {
        if (_disp3oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp3oldLength = 0;
        }
    }
    if (1) 
    {
        _dispTempLength1 = ((String("Umax="))).length();
        if (_disp7oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp7oldLength = _dispTempLength1;
        _lcd1.setCursor(0, 2);
        _lcd1.print((String("Umax=")));
    }
     else 
    {
        if (_disp7oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp7oldLength = 0;
        }
    }
    if (1) 
    {
        _dispTempLength1 = ((String("Umin="))).length();
        if (_disp10oldLength > _dispTempLength1) 
        {
            _isNeedClearDisp1 = 1;
        }
        _disp10oldLength = _dispTempLength1;
        _lcd1.setCursor(0, 3);
        _lcd1.print((String("Umin=")));
    }
     else 
    {
        if (_disp10oldLength > 0) 
        {
            _isNeedClearDisp1 = 1;
            _disp10oldLength = 0;
        }
    }
}
String  _floatToStringWitRaz(float value, int raz)
{
    return String(value,raz);
}
bool _isTimer(unsigned long startTime, unsigned long period)
{
    unsigned long currentTime;
    currentTime = millis();
    if (currentTime>= startTime) 
    {
        return (currentTime>=(startTime + period));
    }
     else 
    {
        return (currentTime >=(4294967295-startTime+period));
    }
}
byte readByteFromEEPROM(int addres, byte bitAddres, byte chipAddres)
{
    return EEPROM.read(addres);
}
void updateByteToEEPROM(int addres, byte bitAddres, byte chipAddres, byte value)
{
    return EEPROM.update(addres, value);
}
float readFloatFromEEPROM(int addres, byte bitAddres, byte chipAddres)
{
    byte x[4];
    for(byte i = 0; i < 4; i++) 
    {
         x[i] = readByteFromEEPROM((addres+i),  bitAddres,  chipAddres);
    }
    float *y = (float *)&x;
    return y[0];
}
void updateFloatToEEPROM(int addres, byte bitAddres, byte chipAddres, float value)
{
    byte *x = (byte *)&value;
    for(byte i = 0; i < 4; i++) 
    {
        updateByteToEEPROM((addres+i),  bitAddres,  chipAddres, x[i]);
    }
}
