Часы на TM 1638 + Arduino/

uvlich
Offline
Зарегистрирован: 10.10.2016

Прикупил я на АЛИ платку с восьмёрочками и кнопочками, и была у меня PRO MINI 5V.

Ну и вспомнилось пионерское детство. 

В итоге получились часы с будильниками и таймером.

Постарался задействовать все кнопочки и светодиодики. кнопочки иногда задумчивы и их нужно чуть придерживать в нажатом положении.

Будильники и таймер могут пикать и/или дёргать ножки.

Есть параметр ajustment, значение которого (в секундах) прибавляется в полночь.

Постарался почистить чудеса, но может ещё остались.


#include <Time.h>
#include <TimeLib.h>

#include <TM1638.h>
TM1638 module(3, 4, 2);

const unsigned long firstStartTime = 1483228800;
const byte timerPort = 9;
const byte beepPort = 12;
const byte alarm_1Port = 10;
const byte alarm_2Port = 11;
const byte sunday = 1;
const byte saturday = 7;
const byte allWorkDays = 8;
const byte allWeekEnd = 9;
const byte allDays = 10;

unsigned int escToTimeShowMode;
byte btn;
byte showMode = 1;
byte lastShowMode = 1; 
int adjustmentTime;
boolean flag;
boolean flag_esc;
time_t tempForTimer = 300;
time_t timer  = 300;
time_t tempForAlarm_1 = 25200;
time_t alarm_1 = 25200;
time_t tempForAlarm_2 = 32400;
time_t alarm_2 = 32400;
time_t alarm_1PortIsUp;
time_t alarm_2PortIsUp;
byte alarm_1WeekDay = allWorkDays;
byte alarm_2WeekDay = allWeekEnd;
boolean beepIsOn;
boolean beepCaller;
boolean timerIsOn;
boolean alarm_1IsOn;
boolean alarm_2IsOn;
boolean alarm_1PortIsOn;
boolean alarm_2PortIsOn;
byte timerMode = 1;
byte alarm_1Mode = 1;
byte alarm_2Mode = 1;

const char strHour[] = "HOUr  ";
const char strMinute[] = "MIN   ";
const char strSec[] = "SEC   ";
const char strDay[] = "dAY   ";
const char strMonth[] = "MontH ";
const char strYear[] = "YEAr20";
const char strAdjustment[] = "AdJUS ";
const char strTimer[] = "tI M E r";
const char strAlarm_1[] = "ALArM  1";
const char strAlarm_2[] = "ALArM  2";
const char strBeep[] = "bEEP ";
const char strRelay[] = "rEL  ";
const char strOn[] = "ON";
const char strOff[] = "OFF";
const char strYes[] = "YES";
const char strNo[] = " NO";

void show (byte showMode);
int getValueForCorrect (const char str[], int value, int minValue, byte maxValue);
void setTimeDate();
void adjustTimeEveryDay ();
void setTimer();
byte restOfTimerTime();
void timerRun ();
void doBeep (boolean caller);
void showStrTimerAlarm (const char str_[]);
void doPause (unsigned int pause_);
void setAlarm_1();
void alarm_1Run ();
void setAlarm_2();
void alarm_2Run ();

void show(byte sMode)
{
  byte n;
  byte m;
  int left;
  int middle;
  int right;
  char* separator[] = {"-", "_", "~", "*", "o"};
  flag_esc = false;
  switch (sMode)
    {
      case 1:
      {
        left = hour();
        middle = minute();
        right = second();
        n = 0; m = 0;
        if (alarm_1IsOn) n = 3;
        if (alarm_2IsOn) m = 4;
                
        if ((lastShowMode != 1 ) || (! timerIsOn))
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        
        if (timerIsOn)
        {
          for (byte i=0; i < restOfTimerTime(); i++)
          {
            module.setLED (TM1638_COLOR_RED,i);
          }
        } 
        lastShowMode = 1; 
      }
      break;
      
      case 2:
      {
        left = hour(alarm_1);
        middle = minute(alarm_1);
        right = second(alarm_1);
        n = 3; m = 3;
        if (alarm_1IsOn) m = 0;
        if (lastShowMode != 2) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        if (alarm_1WeekDay < 8) module.setLED (TM1638_COLOR_RED, alarm_1WeekDay - 1);
        if (alarm_1WeekDay == 8)
        {
          for (byte i=1; i < 6; i++)
          {  
           module.setLED (1,i);
          }
        }
        if (alarm_1WeekDay == 9)
        {
         module.setLED (TM1638_COLOR_RED, 6); 
         module.setLED (TM1638_COLOR_RED, 0);
        }
        if (alarm_1WeekDay == 10)
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (1,i);
          }
        }
        lastShowMode = 2;
      }
      break;
      
      case 3:
      {
        left = day();
        middle = month();
        right = year() - 2000;
        n = 1; m = 1;
        if (lastShowMode != 3) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        module.setLED (TM1638_COLOR_RED, weekday ()-1);
        lastShowMode = 3;
      }
      break;

      case 4:
      {
        left = hour(alarm_2);
        middle = minute(alarm_2);
        right = second(alarm_2);
        n = 4; m = 4;
        if (alarm_2IsOn) n = 0;
        if (lastShowMode != 4) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        if (alarm_2WeekDay < 8) module.setLED (TM1638_COLOR_RED, alarm_2WeekDay - 1);
        if (alarm_2WeekDay == 8)
        {
          for (byte i=1; i < 6; i++)
          {  
           module.setLED (1,i);
          }
        }
        if (alarm_2WeekDay == 9)
        {
         module.setLED (TM1638_COLOR_RED, 6); 
         module.setLED (TM1638_COLOR_RED, 0);
        }
        if (alarm_2WeekDay == 10)
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (1,i);
          }
        }
        lastShowMode = 4;
      }
      break;

      case 8:
      {
        left = hour(timer);
        middle = minute(timer);
        right = second(timer);
        n = 2; m = 2;
        if (lastShowMode != 8)
         {
          for (byte i=0; i < 8; i++)
           {  
            module.setLED (0,i);
           } 
         }
        lastShowMode = 8;
      }
      break;
   }
  
  module.setDisplayDigit(byte ((left - (left % 10)) / 10), byte (0), false);
  module.setDisplayDigit(byte (left % 10), byte (1), false);
  module.setDisplayDigit(byte ((middle - (middle % 10)) / 10), byte (3), false);
  module.setDisplayDigit(byte (middle % 10), byte(4), false);
  module.setDisplayDigit(byte ((right - (right % 10)) / 10), byte (6), false);
  module.setDisplayDigit(byte (right % 10), byte (7), false);
  module.setDisplayToString(separator[n], false, 2);
  module.setDisplayToString(separator[m], false, 5);
  
  byte b = module.getButtons();
  if(lastShowMode == 8 && b == 128) timerIsOn = true;
  if(lastShowMode == 2 && b == 128) alarm_1IsOn = true;
  if(lastShowMode == 4 && b == 128) alarm_2IsOn = true;
}

void doPause(unsigned int pause_)
{
 unsigned long pause = millis(); 
 if (millis () < pause) pause = millis();
      while (millis () - pause < pause_)
       {}
      pause = millis();
}

int getValueForCorrect (const char str[], int value, int minValue, byte maxValue)
 { 
   byte flagForOut;
   byte buttn;
      
  do
    {
     doPause (400);
     buttn = module.getButtons();
     
     if (buttn == 0) flagForOut++;
       if (flagForOut > 200)
        {
        flag_esc = true;
        flag = true;
        return value;
        }
               
     switch (buttn)
     {
       case 1:
       case 2:
       case 4:
       case 8:
       {
        flag_esc = true;
        flag = true;
        return value;
       }
       break;       
       case 32:
       {
        flagForOut = 0;
        value++;
        if (value >= maxValue) value = maxValue;
       }
       break;
      
       case 64:
       {
        flagForOut = 0;
        value--;
        if (value <= minValue) value = minValue;
       }
       break;

       case 128:
       {
        flag = true;
        return value;
       }
       break;
     }
     
      if (value < 0 ) 
      {
      module.setDisplayToString (str);  
      module.setDisplayToString("-", false, 5);  
      module.setDisplayDigit (( (value % 10) - value) / 10, byte (6), false);
      module.setDisplayDigit ( -value % 10, byte (7), false);
      }
      
      if ((maxValue == 1) && (value == 1))
      {
      module.setDisplayToString (str);
      module.setDisplayToString(strYes, false, 5); 
      }
        if ((maxValue == 1) && (value == 0))
        {
        module.setDisplayToString (str);
        module.setDisplayToString(strNo, false, 5);   
        }
        if (maxValue > 1 && value >= 0)
        {
        module.setDisplayToString (str);  
        module.setDisplayDigit ((value - (value % 10)) / 10, byte (6), false);
        module.setDisplayDigit ( value % 10, byte (7), false);
        }
       
    }
  while (buttn != 16);
  
  return value;
 }

void setTimeDate()
{ 
  int copyAdjustmentTime = adjustmentTime;
  flag = false;
  flag_esc = false;
    
  time_t timeForSet = now (); 
  int setHour = hour (timeForSet);
  int setMinute = minute (timeForSet);
  const byte setSecond = 0;
  int setDay = day (timeForSet);
  int setMonth = month (timeForSet);
  int setYear = year (timeForSet) - 2000;
    
  for (byte i=0; i < 8; i++)
    {  
      module.setLED (0,i);
    }
  do
  {
   setHour = getValueForCorrect(strHour, setHour, 0, 23);
   if (flag) continue;  
   
   setMinute = getValueForCorrect(strMinute, setMinute, 0, 59);
   if (flag) continue;  

   setDay = getValueForCorrect(strDay, setDay, 1, 31);
   if (flag) continue;  

   setMonth = getValueForCorrect(strMonth, setMonth, 1, 12);
   if (flag) continue;  

   setYear = getValueForCorrect(strYear, setYear, 15, 99);
   if (flag) continue;  

   adjustmentTime = getValueForCorrect(strAdjustment, adjustmentTime, -60, 60);
   if (flag) continue;
  }
  while (!flag);
  
  if (!flag_esc) setTime (setHour, setMinute, setSecond, setDay, setMonth, setYear);
    else adjustmentTime = copyAdjustmentTime;
}


byte restOfTimerTime()
{
  return byte((tempForTimer + 0.03 * tempForTimer - timer) / (tempForTimer / 8));
}

void setTimer()
{
  byte copyTimerMode = timerMode;
  int timerMode_1 = int(timerMode)  & 0b00000001;
  int timerMode_2 = ((int(timerMode) - timerMode_1) & 0b00000010) / 2;
  byte hour_ = hour (timer);
  byte min_ = minute (timer);
  byte sec_ = second (timer);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strTimer);

  do
  {
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 

   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue; 

   timerMode_1 = getValueForCorrect(strBeep, timerMode_1, 0, 1);
   if (flag) continue;

   timerMode_2 = getValueForCorrect(strRelay, timerMode_2, 0, 1);
   timerMode = byte(timerMode_1) + 2 * byte(timerMode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   if ((min_ == 0) && (hour_ == 0) && (sec_ == 0)) sec_ = 3; 
   timer = hour_ * 3600 + min_ * 60 + sec_;
   timerIsOn = true;
  }
  else 
  {
  timer = tempForTimer;
  timerMode = copyTimerMode;
  timerIsOn = false;
  }
}

void showStrTimerAlarm (const char str_[])
{ 
  module.setDisplayToString (str_);
  doPause (800);    
}        

void timerRun ()
{ if (timerMode ==2 || timerMode ==3) digitalWrite (timerPort, HIGH);
  static byte seconds = second();
  if (seconds != second())
  {
  timer --;
  seconds = second();
  }
  if (timer == 0)
  {
   timerIsOn = false;
   timer = tempForTimer;
   digitalWrite (timerPort, LOW); 
   if (timerMode == 1 || timerMode == 3)
   {
   beepIsOn = true;
   beepCaller = false;
   doBeep (beepCaller);
   }
  }
}

void alarm_1Run ()
{
 byte dayOfWeek = byte(weekday());
 byte hourNow = byte(hour());
 byte minuteNow = byte(minute());
 byte secondNow = byte(second());
 bool flagIs;
 if (hourNow == 0 && adjustmentTime > 0 && alarm_1 < adjustmentTime) alarm_1 = adjustmentTime + 15; 
 if (dayOfWeek == alarm_1WeekDay) flagIs = true;
 else if (dayOfWeek > sunday && dayOfWeek < saturday && alarm_1WeekDay == allWorkDays) flagIs = true;
   else  if ((dayOfWeek == sunday || dayOfWeek == saturday) && alarm_1WeekDay == allWeekEnd) flagIs = true;
     else if (alarm_1WeekDay == allDays) flagIs = true;
       else flagIs = false;
 if (flagIs && (hourNow == hour (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (minuteNow == minute (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (secondNow == second (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (alarm_1Mode == 1 || alarm_1Mode == 3))
   {
   if(alarm_1WeekDay < allWorkDays) alarm_1IsOn = false; 
   beepCaller = true;
   beepIsOn = true;
   doBeep (beepCaller);
   }
  if (flagIs && (alarm_1Mode == 2 || alarm_1Mode == 3))
  {
  if(alarm_1WeekDay < allWorkDays) alarm_1IsOn = false;
  alarm_1PortIsUp = now();
  alarm_1PortIsOn = true;  
  }
}

void alarm_2Run ()
{
 byte dayOfWeek = weekday();
 byte hourNow = hour();
 byte minuteNow = minute();
 byte secondNow = second();
 bool flagIs;
 if (hourNow == 0 && adjustmentTime > 0 && alarm_2 < adjustmentTime) alarm_2 = adjustmentTime + 15; 
 if (dayOfWeek == alarm_2WeekDay) flagIs = true;
 else if (dayOfWeek > sunday && dayOfWeek < saturday && alarm_2WeekDay == allWorkDays) flagIs = true;
   else  if ((dayOfWeek == sunday || dayOfWeek == saturday) && alarm_2WeekDay == allWeekEnd) flagIs = true;
     else if (alarm_2WeekDay == allDays) flagIs = true;
       else flagIs = false;
 if (flagIs && (hourNow == hour (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (minuteNow == minute (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (secondNow == second (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (alarm_2Mode == 1 || alarm_2Mode == 3))
   {
   if(alarm_2WeekDay < allWorkDays) alarm_2IsOn = false; 
   beepCaller = true;
   beepIsOn = true;
   doBeep (beepCaller);
   }
  if (flagIs && ((alarm_2Mode == 2) || (alarm_2Mode == 3)))
  {
  if(alarm_2WeekDay < allWorkDays) alarm_2IsOn = false;
  alarm_2PortIsUp = now();
  alarm_2PortIsOn = true;  
  } 
}

void doBeep (bool caller)
{
 static byte beepTimes; 
 if (beepIsOn)
 {
  tone (beepPort, 900);
  doPause (700);
      
  noTone(beepPort);
  doPause (300);
      
  beepTimes ++;
  if ((beepTimes > 15) && (!caller))
  {
  beepTimes = 0;  
  beepIsOn = false;
  }
  if ((beepTimes > 63) && caller)
  {
  beepTimes = 0;  
  beepIsOn = false;
  } 
  if (btn > 0)
  {
  beepIsOn = false;
  beepTimes = 0;
  }
 }
}

void adjustTimeEveryDay ()
{
  static time_t timeForAdjust;
  static boolean flag_t;
  if (hour (timeForAdjust)== 23 &&  hour () == 0 && flag_t)
    {
    adjustTime (long(adjustmentTime));
    flag_t = false;
    }
  if (hour() == 22) flag_t = true;
  timeForAdjust = now (); 
}

void setAlarm_1()
{
  byte copyAlarm_1WeekDay = alarm_1WeekDay;
  byte copyAlarm_1Mode = alarm_1Mode;
  int alarm_1Mode_1 = int(alarm_1Mode)  & 0b00000001;
  int alarm_1Mode_2 = ((int(alarm_1Mode) - alarm_1Mode_1) & 0b00000010) / 2;
  byte hour_ = hour (alarm_1);
  byte min_ = minute (alarm_1);
  byte sec_ = second (alarm_1);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strAlarm_1);

  do
  {
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 
   
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue;

   alarm_1WeekDay = getValueForCorrect(strDay, alarm_1WeekDay, 1, 10);
   if (flag) continue;

   alarm_1Mode_1 = getValueForCorrect(strBeep, alarm_1Mode_1, 0, 1);
   if (flag) continue;

   alarm_1Mode_2 = getValueForCorrect(strRelay, alarm_1Mode_2, 0, 1);
   alarm_1Mode = byte(alarm_1Mode_1) + 2 * byte(alarm_1Mode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   alarm_1 = hour_ * 3600 + min_ * 60 + sec_;
   alarm_1IsOn = true;
  }
  else 
  {
  alarm_1 = tempForAlarm_1;
  alarm_1Mode = copyAlarm_1Mode;
  alarm_1WeekDay = copyAlarm_1WeekDay;
  alarm_1IsOn = false;
  alarm_1PortIsOn = false;
  }
}

void setAlarm_2()
{
  byte copyAlarm_2WeekDay = alarm_2WeekDay;
  byte copyAlarm_2Mode = alarm_2Mode;
  int alarm_2Mode_1 = int(alarm_2Mode)  & 0b00000001;
  int alarm_2Mode_2 = ((int(alarm_2Mode) - alarm_2Mode_1) & 0b00000010) / 2;
  byte hour_ = hour (alarm_2);
  byte min_ = minute (alarm_2);
  byte sec_ = second (alarm_2);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strAlarm_2);

  do
  {
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 
   
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue;

   alarm_2WeekDay = getValueForCorrect(strDay, alarm_2WeekDay, 1, 10);
   if (flag) continue;

   alarm_2Mode_1 = getValueForCorrect(strBeep, alarm_2Mode_1, 0, 1);
   if (flag) continue;

   alarm_2Mode_2 = getValueForCorrect(strRelay, alarm_2Mode_2, 0, 1);
   alarm_2Mode = byte(alarm_2Mode_1) + 2 * byte(alarm_2Mode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   alarm_2 = hour_ * 3600 + min_ * 60 + sec_;
   alarm_2IsOn = true;
  }
  else 
  {
  alarm_2 = tempForAlarm_2;
  alarm_2Mode = copyAlarm_2Mode;
  alarm_2WeekDay = copyAlarm_2WeekDay;
  alarm_2IsOn = false;
  alarm_2PortIsOn = false;
  }
}

void setup()
{
 setTime (firstStartTime);
 pinMode (timerPort, OUTPUT);
 pinMode (beepPort, OUTPUT);
 pinMode (alarm_1Port, OUTPUT);
 pinMode (alarm_2Port, OUTPUT);
}

void loop()
{
 if (hour() == 22 || hour() == 23 || hour() == 0) adjustTimeEveryDay ();
 if (timerIsOn) timerRun();
 if (alarm_1IsOn) alarm_1Run();
 if (alarm_2IsOn) alarm_2Run();
 if (beepIsOn) doBeep (beepCaller);
 if (alarm_1PortIsOn && (now() - alarm_1PortIsUp) < 60 && btn == 0) digitalWrite (alarm_1Port, HIGH);
 else
 {
 alarm_1PortIsOn = false; 
 digitalWrite (alarm_1Port, LOW); 
 }
 if (alarm_2PortIsOn && (now() - alarm_2PortIsUp) < 60 && btn == 0) digitalWrite (alarm_2Port, HIGH);
 else
 {
 alarm_2PortIsOn = false; 
 digitalWrite (alarm_2Port, LOW); 
 }
 btn = module.getButtons(); 
 switch (btn)
 {
    case 1: 
    {
     escToTimeShowMode = 0; 
     showMode = 3;
     show (showMode);
    }  
    break;

    case 2: 
    {
     escToTimeShowMode = 0; 
     showMode = 2;
     show (showMode);
    }  
    break;

    case 4: 
    {
     escToTimeShowMode = 0; 
     showMode = 4;
     show (showMode);
    }  
    break;

    case 8:
    {
     escToTimeShowMode = 0; 
     showMode = 8;
     show (showMode);
    }
    break;
    
    case 16:
    {
     
     if (showMode == 1 || showMode == 3) setTimeDate();
     
     if (showMode == 8)
     {
     setTimer();
     tempForTimer = timer;
     }

     if (showMode == 2)
     {
     lastShowMode = 16; 
     setAlarm_1();
     tempForAlarm_1 = alarm_1;
     }

     if (showMode == 4)
     {
     lastShowMode = 16; 
     setAlarm_2();
     tempForAlarm_2 = alarm_2;
     }
    }
    break;
      
    default : 
    {
     if (showMode == 1 || showMode == 3) showMode = 1; 
     if (showMode == 2)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 20000)
       {
       showMode = 1;
       }
       else showMode = 2;
     }
     if (showMode == 4)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 20000)
       {
       showMode = 1;
       }
       else showMode = 4;
     }
     if (showMode == 8 && !timerIsOn)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 50000)
       {
       showMode = 1;
       }
       else showMode = 8;
     }
     show (showMode); 
    }
    break;
 }
}       






uvlich
Offline
Зарегистрирован: 10.10.2016

Приделал RTC и сделал сохранение настроек в EEPROM.

Описание:

Самая левая кнопка (1) - часы, (отмена), дата:

Кнопка 2 - будильник - 1,(отмена),;

Кнопка 3 - будильник - 2,(отмена),;

Кнопка 4- таймер,(отмена),;

Кнопка 5 - setup;

Кнопка 6 - +;

Кнопка 7 - -;

Кнопка 8 - enter;

При работе таймера в режиме "Часы" светодиодики показывают пропорционально прошедшее время.

Индикация информативна.

#include <Time.h>
#include <TimeLib.h>
#include <elapsedMillis.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <EEPROM.h>
#include <TM1638.h>
TM1638 module(3, 4, 2);

const unsigned long firstStartTime = 1483228800;
const byte timerPort = 9;
const byte beepPort = 12;
const byte alarm_1Port = 10;
const byte alarm_2Port = 11;
const byte sunday = 1;
const byte saturday = 7;
const byte allWorkDays = 8;
const byte allWeekEnd = 9;
const byte allDays = 10;
const int eeTimerAddress = 0;
const int eeTimerIsReSetAddress = 8;
const int eeAlarm_1Address = 9;
const int eeAlarm_1IsReSetAddress = 20;
const int eeAlarm_2Address = 21;
const int eeAlarm_2IsReSetAddress = 32;
const int eeAdjustmentTimeAddress = 33; //last used EEPROM address is 34
unsigned int escToTimeShowMode;
byte btn;
byte showMode = 1;
byte lastShowMode = 1; 
int adjustmentTime;
boolean flag;
boolean flag_esc;

time_t timer  = 300;
time_t tempForTimer = timer;
time_t alarm_1 = 25200;
time_t tempForAlarm_1 = alarm_1;
time_t alarm_2 = 32400;
time_t tempForAlarm_2 = alarm_2;
time_t alarm_1PortIsUp;
time_t alarm_2PortIsUp;
byte alarm_1WeekDay = allWorkDays;
byte alarm_2WeekDay = allWeekEnd;
byte timerIsReSet;
byte alarm_1IsReSet;
byte alarm_2IsReSet;
boolean beepIsOn;
boolean beepCaller;
boolean timerIsOn;
boolean alarm_1IsOn;
boolean alarm_2IsOn;
boolean alarm_1PortIsOn;
boolean alarm_2PortIsOn;
byte timerMode = 1;
byte alarm_1Mode = 1;
byte alarm_2Mode = 1;
elapsedMillis timeElapsed;

const char strHour[] = "HOUr  ";
const char strMinute[] = "MIN   ";
const char strSec[] = "SEC   ";
const char strDay[] = "dAY   ";
const char strMonth[] = "MontH ";
const char strYear[] = "YEAr20";
const char strAdjustment[] = "AdJUS ";
const char strTimer[] = "tI M E r";
const char strAlarm_1[] = "ALArM  1";
const char strAlarm_2[] = "ALArM  2";
const char strBeep[] = "bEEP ";
const char strRelay[] = "rEL  ";
const char strYes[] = "YES";
const char strNo[] = " NO";

void show (byte showMode);
int getValueForCorrect (const char str[], int value, int minValue, byte maxValue);
void setTimeDate();
void adjustTimeEveryDay ();
void setTimer();
byte restOfTimerTime();
void timerRun ();
void doBeep (boolean caller);
void showStrTimerAlarm (const char str_[]);
bool doPause (unsigned int pause_, bool mode);
void setAlarm_1();
void alarm_1Run ();
void setAlarm_2();
void alarm_2Run ();


void setup()
{
 setSyncProvider(RTC.get);   // the function to get the time from the RTC
 if (timeStatus() != timeSet) setTime (firstStartTime);
 pinMode (timerPort, OUTPUT);
 pinMode (beepPort, OUTPUT);
 pinMode (alarm_1Port, OUTPUT);
 pinMode (alarm_2Port, OUTPUT);
 timerIsReSet = EEPROM.read (eeTimerIsReSetAddress);
  if (timerIsReSet == 1) 
  {
    EEPROM .get(0, timer);
    tempForTimer = timer;
  }
 alarm_1IsReSet = EEPROM.read (eeAlarm_1IsReSetAddress);
  if (alarm_1IsReSet == 1) 
  {
    EEPROM .get(eeAlarm_1Address, alarm_1);
    tempForAlarm_1 = alarm_1;
    alarm_1WeekDay = EEPROM.read (17);
    alarm_1Mode = EEPROM.read (18);
    alarm_1IsOn = EEPROM.read (19);
  }
  alarm_2IsReSet = EEPROM.read (eeAlarm_2IsReSetAddress);
  if (alarm_2IsReSet == 1) 
  {
    EEPROM .get(eeAlarm_2Address, alarm_2);
    tempForAlarm_2 = alarm_2;
    alarm_2WeekDay = EEPROM.read (29);
    alarm_2Mode = EEPROM.read (30);
    alarm_2IsOn = EEPROM.read (31);
  }
  EEPROM.get(eeAdjustmentTimeAddress, adjustmentTime);
  if (adjustmentTime < 60 || adjustmentTime > 60) adjustmentTime = 0;
}

void loop()
{
 if (hour() == 22 || hour() == 23 || hour() == 0) adjustTimeEveryDay ();
 if (timerIsOn) timerRun();
 if (alarm_1IsOn) alarm_1Run();
 if (alarm_2IsOn) alarm_2Run();
 if (beepIsOn) doBeep (beepCaller);
 if (alarm_1PortIsOn && (now() - alarm_1PortIsUp) < 60 && btn == 0) digitalWrite (alarm_1Port, HIGH);
 else
 {
 alarm_1PortIsOn = false; 
 digitalWrite (alarm_1Port, LOW); 
 }
 if (alarm_2PortIsOn && (now() - alarm_2PortIsUp) < 60 && btn == 0) digitalWrite (alarm_2Port, HIGH);
 else
 {
 alarm_2PortIsOn = false; 
 digitalWrite (alarm_2Port, LOW); 
 }
 btn = module.getButtons(); 
 switch (btn)
 {
    case 1: 
    {
     escToTimeShowMode = 0; 
     showMode = 3;
     show (showMode);
    }  
    break;

    case 2: 
    {
     escToTimeShowMode = 0; 
     showMode = 2;
     show (showMode);
    }  
    break;

    case 4: 
    {
     escToTimeShowMode = 0; 
     showMode = 4;
     show (showMode);
    }  
    break;

    case 8:
    {
     escToTimeShowMode = 0; 
     showMode = 8;
     show (showMode);
    }
    break;
    
    case 16:
    {
     
     if (showMode == 1 || showMode == 3) setTimeDate();
     
     if (showMode == 8)
     {
     setTimer();
     tempForTimer = timer;
     }

     if (showMode == 2)
     {
     lastShowMode = 16; 
     setAlarm_1();
     tempForAlarm_1 = alarm_1;
     }

     if (showMode == 4)
     {
     lastShowMode = 16; 
     setAlarm_2();
     tempForAlarm_2 = alarm_2;
     }
    }
    break;
      
    default : 
    {
     if (showMode == 1 || showMode == 3) showMode = 1; 
     if (showMode == 2)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 20000)
       {
       showMode = 1;
       }
       else showMode = 2;
     }
     if (showMode == 4)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 20000)
       {
       showMode = 1;
       }
       else showMode = 4;
     }
     if (showMode == 8 && !timerIsOn)
     {
       escToTimeShowMode ++;
       if (escToTimeShowMode > 50000)
       {
       showMode = 1;
       }
       else showMode = 8;
     }
     show (showMode); 
    }
    break;
 }
}       

void adjustTimeEveryDay ()
{
  static time_t timeForAdjust;
  static boolean flag_t;
  if (hour (timeForAdjust)== 23 &&  hour () == 0 && flag_t)
    {
    adjustTime (long(adjustmentTime));
    flag_t = false;
    }
  if (hour() == 22) flag_t = true;
  timeForAdjust = now (); 
}

void alarm_1Run ()
{
 byte dayOfWeek = weekday();
 byte hourNow = hour();
 byte minuteNow = minute();
 byte secondNow = second();
 bool flagIs;
 if (hourNow == 0 && adjustmentTime > 0 && alarm_1 < adjustmentTime) alarm_1 = adjustmentTime + 15; 
 if (dayOfWeek == alarm_1WeekDay) flagIs = true;
 else if (dayOfWeek > sunday && dayOfWeek < saturday && alarm_1WeekDay == allWorkDays) flagIs = true;
   else  if ((dayOfWeek == sunday || dayOfWeek == saturday) && alarm_1WeekDay == allWeekEnd) flagIs = true;
     else if (alarm_1WeekDay == allDays) flagIs = true;
       else flagIs = false;
 if (flagIs && (hourNow == hour (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (minuteNow == minute (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (secondNow == second (alarm_1))) flagIs = true;
   else flagIs = false;
 if (flagIs && (alarm_1Mode == 1 || alarm_1Mode == 3))
   {
   if(alarm_1WeekDay < allWorkDays) alarm_1IsOn = false; 
   beepCaller = true;
   beepIsOn = true;
   doBeep (beepCaller);
   }
  if (flagIs && (alarm_1Mode == 2 || alarm_1Mode == 3))
  {
  if(alarm_1WeekDay < allWorkDays) alarm_1IsOn = false;
  alarm_1PortIsUp = now();
  alarm_1PortIsOn = true;  
  }
}

void alarm_2Run ()
{
 byte dayOfWeek = weekday();
 byte hourNow = hour();
 byte minuteNow = minute();
 byte secondNow = second();
 bool flagIs;
 if (hourNow == 0 && adjustmentTime > 0 && alarm_2 < adjustmentTime) alarm_2 = adjustmentTime + 15; 
 if (dayOfWeek == alarm_2WeekDay) flagIs = true;
 else if (dayOfWeek > sunday && dayOfWeek < saturday && alarm_2WeekDay == allWorkDays) flagIs = true;
   else  if ((dayOfWeek == sunday || dayOfWeek == saturday) && alarm_2WeekDay == allWeekEnd) flagIs = true;
     else if (alarm_2WeekDay == allDays) flagIs = true;
       else flagIs = false;
 if (flagIs && (hourNow == hour (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (minuteNow == minute (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (secondNow == second (alarm_2))) flagIs = true;
   else flagIs = false;
 if (flagIs && (alarm_2Mode == 1 || alarm_2Mode == 3))
   {
   if(alarm_2WeekDay < allWorkDays) alarm_2IsOn = false; 
   beepCaller = true;
   beepIsOn = true;
   doBeep (beepCaller);
   }
  if (flagIs && ((alarm_2Mode == 2) || (alarm_2Mode == 3)))
  {
  if(alarm_2WeekDay < allWorkDays) alarm_2IsOn = false;
  alarm_2PortIsUp = now();
  alarm_2PortIsOn = true;  
  } 
}

void doBeep (bool caller)
{
 static byte beepTimes; 
 if (beepIsOn)
 {
  tone (beepPort, 900);
  if (doPause (700, true))
   {
     noTone(beepPort);
     beepTimes ++; 
     doPause (300, false);
   }
  if ((beepTimes > 15) && (!caller))
  {
  beepTimes = 0;  
  beepIsOn = false;
  }
  if ((beepTimes > 63) && caller)
  {
  beepTimes = 0;  
  beepIsOn = false;
  } 
  if (btn > 0)
  {
  beepIsOn = false;
  beepTimes = 0;
  noTone(beepPort);
  }
 }
}

bool doPause(unsigned int pause_, bool mode)
{
  startPause: if (timeElapsed > pause_)
              {
                timeElapsed = 0;
                return true;       
              }
             else if(mode) return false;
                  else goto startPause;
}

int getValueForCorrect (const char str[], int value, int minValue, byte maxValue)
 { 
   byte flagForOut;
   byte buttn;
      
  do
    {
     doPause(300, false);
     buttn = module.getButtons();
     
     if (buttn == 0) flagForOut++;
       if (flagForOut > 200)
        {
        flag_esc = true;
        flag = true;
        return value;
        }
               
     switch (buttn)
     {
       case 1:
       case 2:
       case 4:
       case 8:
       {
        flag_esc = true;
        flag = true;
        return value;
       }
       break;       
       case 32:
       {
        flagForOut = 0;
        value++;
        if (value >= maxValue) value = maxValue;
       }
       break;
      
       case 64:
       {
        flagForOut = 0;
        value--;
        if (value <= minValue) value = minValue;
       }
       break;

       case 128:
       {
        flag = true;
        return value;
       }
       break;
     }
     
      if (value < 0 ) 
      {
      module.setDisplayToString (str);  
      module.setDisplayToString("-", false, 5);  
      module.setDisplayDigit (( (value % 10) - value) / 10, byte (6), false);
      module.setDisplayDigit ( -value % 10, byte (7), false);
      }
      
      if ((maxValue == 1) && (value == 1))
      {
      module.setDisplayToString (str);
      module.setDisplayToString(strYes, false, 5); 
      }
        if ((maxValue == 1) && (value == 0))
        {
        module.setDisplayToString (str);
        module.setDisplayToString(strNo, false, 5);   
        }
        if (maxValue > 1 && value >= 0)
        {
        module.setDisplayToString (str);  
        module.setDisplayDigit ((value - (value % 10)) / 10, byte (6), false);
        module.setDisplayDigit ( value % 10, byte (7), false);
        }
       
    }
  while (buttn != 16);
  
  return value;
 }

byte restOfTimerTime()
{
  return byte((tempForTimer + 0.03 * tempForTimer - timer) / (tempForTimer / 8));
}

void showStrTimerAlarm (const char str_[])
{
  doPause (100, false);
  module.setDisplayToString (str_);
  doPause (1000, false);
}

void setAlarm_1()
{
  byte copyAlarm_1WeekDay = alarm_1WeekDay;
  byte copyAlarm_1Mode = alarm_1Mode;
  int alarm_1Mode_1 = int(alarm_1Mode)  & 0b00000001;
  int alarm_1Mode_2 = ((int(alarm_1Mode) - alarm_1Mode_1) & 0b00000010) / 2;
  byte hour_ = hour (alarm_1);
  byte min_ = minute (alarm_1);
  byte sec_ = second (alarm_1);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strAlarm_1);

  do
  {
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 
   
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue;

   alarm_1WeekDay = getValueForCorrect(strDay, alarm_1WeekDay, 1, 10);
   if (flag) continue;

   alarm_1Mode_1 = getValueForCorrect(strBeep, alarm_1Mode_1, 0, 1);
   if (flag) continue;

   alarm_1Mode_2 = getValueForCorrect(strRelay, alarm_1Mode_2, 0, 1);
   alarm_1Mode = byte(alarm_1Mode_1) + 2 * byte(alarm_1Mode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   alarm_1 = hour_ * 3600 + min_ * 60 + sec_;
   alarm_1IsOn = true;
   EEPROM .put(eeAlarm_1Address, alarm_1);
   EEPROM.write (17, alarm_1WeekDay);
   EEPROM.write (18, alarm_1Mode);
   EEPROM.write (19, alarm_1IsOn);
   EEPROM.write (eeAlarm_1IsReSetAddress, 1);
  }
  else 
  {
  alarm_1 = tempForAlarm_1;
  alarm_1Mode = copyAlarm_1Mode;
  alarm_1WeekDay = copyAlarm_1WeekDay;
  alarm_1IsOn = false;
  EEPROM.write (19, alarm_1IsOn);
  alarm_1PortIsOn = false;
  }
}

void setAlarm_2()
{
  byte copyAlarm_2WeekDay = alarm_2WeekDay;
  byte copyAlarm_2Mode = alarm_2Mode;
  int alarm_2Mode_1 = int(alarm_2Mode)  & 0b00000001;
  int alarm_2Mode_2 = ((int(alarm_2Mode) - alarm_2Mode_1) & 0b00000010) / 2;
  byte hour_ = hour (alarm_2);
  byte min_ = minute (alarm_2);
  byte sec_ = second (alarm_2);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strAlarm_2);

  do
  {
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 
   
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue;

   alarm_2WeekDay = getValueForCorrect(strDay, alarm_2WeekDay, 1, 10);
   if (flag) continue;

   alarm_2Mode_1 = getValueForCorrect(strBeep, alarm_2Mode_1, 0, 1);
   if (flag) continue;

   alarm_2Mode_2 = getValueForCorrect(strRelay, alarm_2Mode_2, 0, 1);
   alarm_2Mode = byte(alarm_2Mode_1) + 2 * byte(alarm_2Mode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   alarm_2 = hour_ * 3600 + min_ * 60 + sec_;
   alarm_2IsOn = true;
   EEPROM.put(eeAlarm_2Address, alarm_2);
   EEPROM.write (29, alarm_2WeekDay);
   EEPROM.write (30, alarm_2Mode);
   EEPROM.write (31, alarm_2IsOn);
   EEPROM.write (eeAlarm_2IsReSetAddress, 1);
  }
  else 
  {
  alarm_2 = tempForAlarm_2;
  alarm_2Mode = copyAlarm_2Mode;
  alarm_2WeekDay = copyAlarm_2WeekDay;
  alarm_2IsOn = false;
  EEPROM.write (31, alarm_2IsOn);
  alarm_2PortIsOn = false;
  }
}

void setTimeDate()
{ 
  int copyAdjustmentTime = adjustmentTime;
  flag = false;
  flag_esc = false;
    
  time_t timeForSet = now (); 
  int setHour = hour (timeForSet);
  int setMinute = minute (timeForSet);
  const byte setSecond = 0;
  int setDay = day (timeForSet);
  int setMonth = month (timeForSet);
  int setYear = year (timeForSet) - 2000;
    
  for (byte i=0; i < 8; i++)
    {  
      module.setLED (0,i);
    }
  do
  {
   setHour = getValueForCorrect(strHour, setHour, 0, 23);
   if (flag) continue;  
   
   setMinute = getValueForCorrect(strMinute, setMinute, 0, 59);
   if (flag) continue;  

   setDay = getValueForCorrect(strDay, setDay, 1, 31);
   if (flag) continue;  

   setMonth = getValueForCorrect(strMonth, setMonth, 1, 12);
   if (flag) continue;  

   setYear = getValueForCorrect(strYear, setYear, 15, 99);
   if (flag) continue;  

   adjustmentTime = getValueForCorrect(strAdjustment, adjustmentTime, -60, 60);
   if (flag) continue;
  }
  while (!flag);
  
  if (!flag_esc) 
  {
    setTime (setHour, setMinute, setSecond, setDay, setMonth, setYear);
    timeForSet = now ();
    RTC.set(timeForSet);    // set the RTC and the system time
    EEPROM.put(eeAdjustmentTimeAddress, adjustmentTime);
  }
    else adjustmentTime = copyAdjustmentTime;
}

void setTimer()
{
  byte copyTimerMode = timerMode;
  int timerMode_1 = int(timerMode)  & 0b00000001;
  int timerMode_2 = ((int(timerMode) - timerMode_1) & 0b00000010) / 2;
  byte hour_ = hour (timer);
  byte min_ = minute (timer);
  byte sec_ = second (timer);

  flag = false;
  flag_esc = false;
  
  showStrTimerAlarm (strTimer);

  do
  {
   min_ = getValueForCorrect(strMinute, min_, 0, 59);
   if (flag) continue; 
  
   hour_ = getValueForCorrect(strHour, hour_, 0, 23);
   if (flag) continue; 

   sec_ = getValueForCorrect(strSec, sec_, 0, 59);
   if (flag) continue; 

   timerMode_1 = getValueForCorrect(strBeep, timerMode_1, 0, 1);
   if (flag) continue;

   timerMode_2 = getValueForCorrect(strRelay, timerMode_2, 0, 1);
   timerMode = byte(timerMode_1) + 2 * byte(timerMode_2) ;
   if (flag) continue;
   
  }
  while (!flag);
  if (!flag_esc)
  {
   if ((min_ == 0) && (hour_ == 0) && (sec_ == 0)) sec_ = 3; 
   timer = hour_ * 3600 + min_ * 60 + sec_;
   timerIsOn = true;
   EEPROM .put(0, timer);
   EEPROM.write (eeTimerIsReSetAddress, 1);
  }
  else 
  {
  timer = tempForTimer;
  timerMode = copyTimerMode;
  timerIsOn = false;
  }
}

void show(byte sMode)
{
  byte n;
  byte m;
  int left;
  int middle;
  int right;
  char* separator[] = {"-", "_", "~", "*", "o"};
  flag_esc = false;
  switch (sMode)
    {
      case 1:
      {
        left = hour();
        middle = minute();
        right = second();
        n = 0; m = 0;
        if (alarm_1IsOn) n = 3;
        if (alarm_2IsOn) m = 4;
                
        if ((lastShowMode != 1 ) || (! timerIsOn))
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        
        if (timerIsOn)
        {
          for (byte i=0; i < restOfTimerTime(); i++)
          {
            module.setLED (TM1638_COLOR_RED,i);
          }
        } 
        lastShowMode = 1; 
      }
      break;
      
      case 2:
      {
        left = hour(alarm_1);
        middle = minute(alarm_1);
        right = second(alarm_1);
        n = 3; m = 3;
        if (alarm_1IsOn) m = 0;
        if (lastShowMode != 2) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        if (alarm_1WeekDay < 8) module.setLED (TM1638_COLOR_RED, alarm_1WeekDay - 1);
        if (alarm_1WeekDay == 8)
        {
          for (byte i=1; i < 6; i++)
          {  
           module.setLED (1,i);
          }
        }
        if (alarm_1WeekDay == 9)
        {
         module.setLED (TM1638_COLOR_RED, 6); 
         module.setLED (TM1638_COLOR_RED, 0);
        }
        if (alarm_1WeekDay == 10)
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (1,i);
          }
        }
        lastShowMode = 2;
      }
      break;
      
      case 3:
      {
        left = day();
        middle = month();
        right = year() - 2000;
        n = 1; m = 1;
        if (lastShowMode != 3) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        module.setLED (TM1638_COLOR_RED, weekday ()-1);
        lastShowMode = 3;
      }
      break;

      case 4:
      {
        left = hour(alarm_2);
        middle = minute(alarm_2);
        right = second(alarm_2);
        n = 4; m = 4;
        if (alarm_2IsOn) n = 0;
        if (lastShowMode != 4) 
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (0,i);
          }
        }
        if (alarm_2WeekDay < 8) module.setLED (TM1638_COLOR_RED, alarm_2WeekDay - 1);
        if (alarm_2WeekDay == 8)
        {
          for (byte i=1; i < 6; i++)
          {  
           module.setLED (1,i);
          }
        }
        if (alarm_2WeekDay == 9)
        {
         module.setLED (TM1638_COLOR_RED, 6); 
         module.setLED (TM1638_COLOR_RED, 0);
        }
        if (alarm_2WeekDay == 10)
        {
          for (byte i=0; i < 8; i++)
          {  
           module.setLED (1,i);
          }
        }
        lastShowMode = 4;
      }
      break;

      case 8:
      {
        left = hour(timer);
        middle = minute(timer);
        right = second(timer);
        n = 2; m = 2;
        if (lastShowMode != 8)
         {
          for (byte i=0; i < 8; i++)
           {  
            module.setLED (0,i);
           } 
         }
        lastShowMode = 8;
      }
      break;
   }
  
  module.setDisplayDigit(byte ((left - (left % 10)) / 10), byte (0), false);
  module.setDisplayDigit(byte (left % 10), byte (1), false);
  module.setDisplayDigit(byte ((middle - (middle % 10)) / 10), byte (3), false);
  module.setDisplayDigit(byte (middle % 10), byte(4), false);
  module.setDisplayDigit(byte ((right - (right % 10)) / 10), byte (6), false);
  module.setDisplayDigit(byte (right % 10), byte (7), false);
  module.setDisplayToString(separator[n], false, 2);
  module.setDisplayToString(separator[m], false, 5);
  
  byte b = module.getButtons();
  if(lastShowMode == 8 && b == 128) timerIsOn = true;
  if(lastShowMode == 2 && b == 128) alarm_1IsOn = true;
  if(lastShowMode == 4 && b == 128) alarm_2IsOn = true;
}

void timerRun ()
{ if (timerMode ==2 || timerMode ==3) digitalWrite (timerPort, HIGH);
  static byte seconds = second();
  if (seconds != second())
  {
  timer --;
  seconds = second();
  }
  if (timer == 0)
  {
   timerIsOn = false;
   timer = tempForTimer;
   digitalWrite (timerPort, LOW); 
   if (timerMode == 1 || timerMode == 3)
   {
   beepIsOn = true;
   beepCaller = false;
   doBeep (beepCaller);
   }
  }
}

 

g.f.vostrikov2012
Offline
Зарегистрирован: 30.11.2016

простите ,а где скетч на часы

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

g.f.vostrikov2012 пишет:

простите ,а где скетч на часы

я запретил.

zuka
Offline
Зарегистрирован: 15.07.2016

Первый пример запустился сразу, второму для pro-mini нужен подбор библиотек чтобы уместился

uvlich
Offline
Зарегистрирован: 10.10.2016

Что-то около 40% флеша и примерно столько ОЗУ занимает, не помню точно. Проверялось всё на ПРО Мини. А библиотечки в начале файла описаны, поставить их в Arduino IDE очень просто. 

zuka
Offline
Зарегистрирован: 15.07.2016
Вот сообщение об ошибке:
Arduino: 1.6.13 (Windows 7), Плата:"Arduino Pro or Pro Mini, ATmega168 (5V, 16 MHz)"
Скетч использует 15 538 байт (108%) памяти устройства. Всего доступно 14 336 байт.
Глобальные переменные используют 833 байт (81%) динамической памяти, оставляя 191 байт для локальных переменных. Максимум: 1 024 байт.
processing.app.debug.RunnerException: Скетч слишком большой; прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
 
uvlich
Offline
Зарегистрирован: 10.10.2016

Понятно. Просто у меня ПроМини с 328-ой атмегой.

Скетч использует 15 538 байт (50%) памяти устройства. Всего доступно 30 720 байт.
Глобальные переменные используют 833 байт (40%) динамической памяти, оставляя 1 215 байт для локальных переменных. Максимум: 2 048 байт.
Hemero
Offline
Зарегистрирован: 04.08.2017

Только у вас нашел исчерпывающую информацию и рабочие скетчи.Все отлично работает.Благодарю.

b707
Offline
Зарегистрирован: 26.05.2017

Шикарный пример, что. коли нет понимания - можно и с помощью millis забить процессорное время не хуже delay :) см функцию в строке 244 (первый скетч)

автор, "кнопки подтормаживают", да?  :)

uncle_grin
Offline
Зарегистрирован: 26.04.2015

Второй скетч работает. Проверил на Меге, чуть-чуть подправил под свои нужды

b707, вы ехидный, в каждой теме нагадить нужно. Сделайте лучше, потом критикуйте

b707
Offline
Зарегистрирован: 26.05.2017

uncle_grin пишет:

 

b707, вы ехидный, в каждой теме нагадить нужно. Сделайте лучше, потом критикуйте

Не в каждой, а только там, где выкладывают хрень. во втором коде такая же бредовая функция doPause(0). как в первом.

 

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

uncle_grin пишет:

Второй скетч работает. Проверил на Меге, чуть-чуть подправил под свои нужды

b707, вы ехидный, в каждой теме нагадить нужно. Сделайте лучше, потом критикуйте

Он вам показал как вы при помощи миллис сделали фактически delay(). А вы сразу обижаетесь.

b707
Offline
Зарегистрирован: 26.05.2017

Ну. справедливости ради, во втором коде автор сделал попытку чуть улучшить код пресловутой функции doPause, чтобы она не была откровенной копией delay. В параметрах добавился второй член, как раз указывающий. будет пауза блокирующей или нет. Правда сам автор этой возможностью не пользуется (наверно, списал где-нибудь, не поняв сути?) -во всем коде программы неблокирующая пауза только в одном месте, а в других местах везде программа просто висит указанное кол-во миллисекунд.

Делаем вывод - то что код "работает" - это комплимент, на самом деле кнопки в нем должны тормозить, как и в коде из заглавного сообщения.

uncle_grin
Offline
Зарегистрирован: 26.04.2015

Штирлиц пишет:

Он вам показал как вы при помощи миллис сделали фактически delay(). А вы сразу обижаетесь.

Ни в коем случае, какие обиды.

b707, сделайте как надо и выложите скетч - вот это будет нормально!

Возможно, даже скорее всего, автор списал не разобравшись. Ну и что? И я наверное 2/3 списываю - на то и форум, чтобы исправлять ошибки а не ехидничать. Соображаете в чем-то - отлично, научите других а не зазнавайтесь. Всегда же найдутся более умные

 

b707
Offline
Зарегистрирован: 26.05.2017

uncle_grin пишет:

 на то и форум, чтобы исправлять ошибки а не ехидничать.

Исправляют пусть сами. Если вам указали на ошибку - это уже огромная помощь, ибо исправить ошибку - это чаще всего вопрос технический, главное - знать, где она, ошибка....

 

 

uncle_grin
Offline
Зарегистрирован: 26.04.2015

b707 пишет:

uncle_grin пишет:

 на то и форум, чтобы исправлять ошибки а не ехидничать.

Исправляют пусть сами. Если вам указали на ошибку - это уже огромная помощь, ибо исправить ошибку - это чаще всего вопрос технический, главное - знать, где она, ошибка....

 

 

Мое мнение это зазнайство и скотство.

Посмотрите как общаются люди на Опеннет.РУ, поучитесь...

b707
Offline
Зарегистрирован: 26.05.2017

uncle_grin пишет:

Мое мнение это зазнайство и скотство.

Посмотрите как общаются люди на Опеннет.РУ, поучитесь...

Внешняя разница имеется, но ни на одном форуме не любят тех, кто задает элементарные вопросы, не заглянув в гугл или в сотый раз ставит "проблемы", которые давно разобраны в ФАКе или в учебниках. Если человек хочет что-то узнать - он должен продемонстрировать свое желание учиться. "Тянуть за уши к знаниям", как в детском саду, тут никого не будут.

sadman41
Offline
Зарегистрирован: 19.10.2016

uncle_grin пишет:

Мое мнение это зазнайство и скотство.

Посмотрите как общаются люди на Опеннет.РУ, поучитесь...

А что, на опеннете вашем на пост типа "Купил микротик, насобирал из кусков с интернета конфиг, заливаю - всё зависает. Проверьте!" все прямо кидаются и начинают в свои девайсы этот конфиг заливать, тестовую сеть собирать, да баги вылавливать?

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

.... все прямо кидаются и начинают в свои девайсы этот конфиг заливать, тестовую сеть собирать, да баги вылавливать?...

не, я пряи представил автора - как он идет по двору и видит дворника. который неправильно снег чистит. И как наш "не ехидный и не сволочной"  сразу хватает у дворника лопату и давай шуровать - ведь он умеет лучше, а значит его долг почистить двор самостоятельно :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
 анекдот,хотя найти бы такой форум.
  На форуме "Сам себе ремонтник" новичек открыл тему : Как сделать ремонт в своей квартире. Ну завсегдаи форума разумеется откликнулись. Вы делаете ремонт, это здорово, давайте адрес, подъедем решим. Новичек кинул адрес. Через день заваливается человек 10 и давай шуровать. Через неделю ремонт закончен. Новичек доволен. Ну и последний говорит: -Учись салага, а то всю жизнь будешь только на форуме писать.
*** 
 Ну и продолжение этой истории. Новичок открывает тему на другом форуме: Как мне чинить автомобиль. И его ..(сам в шоке) послали  известно куда.  Новичок в непонятках . Написал ,что на другом форуме ему помогли, но все равно никто не едет ему автомобиль чинить. 
uvlich
Offline
Зарегистрирован: 10.10.2016

b707 пишет:

Ну. справедливости ради, во втором коде автор сделал попытку чуть улучшить код пресловутой функции doPause, чтобы она не была откровенной копией delay. В параметрах добавился второй член, как раз указывающий. будет пауза блокирующей или нет. Правда сам автор этой возможностью не пользуется (наверно, списал где-нибудь, не поняв сути?) -во всем коде программы неблокирующая пауза только в одном месте, а в других местах везде программа просто висит указанное кол-во миллисекунд.

Делаем вывод - то что код "работает" - это комплимент, на самом деле кнопки в нем должны тормозить, как и в коде из заглавного сообщения.

Спасибо, что указали на ошибку.

Лирика: есть у меня один знакомый, тоже всё знает и всех учит по политической части, только вот не любмт его никто, даже его собаки.

 

В первом посте темы я написал, что вспомнил далёкое детсво. А составляя скетч, я вспоминал забытый лет 30 назад язык С. Теперь бы я написал такое СОВСЕМ по-другому, но мне  это уже не интересно. А часики работают, хотя кнопочки и притормаживают. Жена пользуется.