/***************************************************/
//  FILE  WIFI時計 7Seg-LED  TM1637+CDS(光センサー)
//  DATE        :Tue, Jan 10, 2025 
//  DESCRIPTION : タイマー割り込みにて 制御
//  CPU TYPE    : ESP32 
//	                                    by Chiyabo
//  This file is generated by Renesas Project Generator.
/**************************************************/
//                                                                  */
#include < WiFi.h >
#include < time.h >
#include < TM1637Display.h >

#define LED_SEC 32
#define LED_OK 13
#define LED_NG 12

// Module connection pins (Digital Pins)
#define CLK 22
#define DIO 21
TM1637Display display(CLK, DIO);
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff }; // all '1'
// 家のwifiのssidとパスワードを入力
const char* ssid = "YOUR_SSID";         			  // 各自のWifi環境のSSIDを指定する
const char* password = "YOUR_PASSWORD"; // 各自のWifi環境のPasswordを指定する

// NTPサーバー設定
const char* ntpServer = "ntp.nict.jp" ;  // 日本標準時(JST)
const long gmtOffset_sec = 9 * 3600 ;    // GMT+9(日本時間)
const int daylightOffset_sec = 0 ;       // サマータイム(日本は使用しない)

//timer 初期化
hw_timer_t * timer = NULL ; 

char Int_Cnt = 2  ;
char Int_1Sec = false ;
char Sec ;        // 秒
char Min ;        // 分
char Hor ;        // 時
char HorCnt = 0 ;

int Sec_Change ;        
int Min_Change ;     
int Hor_Change ;     

// アナログ入力関連
int analogPin = 33 ;  // potentiometer wiper (middle terminal)
                      // connected to analog pin 33
                      // outside leads to ground and +3.3V
int val = 0 ;         // variable to store the value read
char SetBrightNoOld ;

//割込みサービスルーチン 1秒
void IRAM_ATTR LED_Blink( ){
  digitalWrite( LED_SEC, !digitalRead( LED_SEC ) ) ;
  if( TimeInEnEnd == true ){ 
    digitalWrite( LED_NG, !digitalRead( LED_NG ) ) ;
    digitalWrite( LED_OK, !digitalRead( LED_OK ) ) ;
  }
  else{
    if( ErrFlg == true ){
      digitalWrite( LED_NG, LOW ) ; // 点灯
      digitalWrite( LED_OK, HIGH ) ; // 消灯
    }
    else{
      digitalWrite( LED_OK, LOW ) ; // 点灯
      digitalWrite( LED_NG, HIGH ) ; // 消灯  
    }
  }
  if( --Int_Cnt == 0 ){
    Int_Cnt = 2 ;
    Int_1Sec = true ;
  }
}

void setup( ){
  //Serial.begin( 115200 ) ;
  pinMode( LED_SEC, OUTPUT ) ;
  pinMode( LED_OK, OUTPUT ) ;
  pinMode( LED_NG, OUTPUT ) ;
  
  // 周波数を直接指定(ここでは1MHz = 1µsごとにカウントアップ)
  timer = timerBegin( 1000000 ) ;
  // 割り込み関数を登録
  timerAttachInterrupt( timer, &LED_Blink ) ;
  // アラーム設定: 500000カウントごと(=0.5Sec)、繰り返し
  timerAlarm( timer, 500000, true, 0 ) ; // 第3引数をtrue指定で、繰り返し。その際は第4引数は無
  
  // 表示のリセット(何も表示しない)
  display.clear ( ) ;
}

void loop( ){
  char SetBrightNoNew ;
  
  // 現在時刻を表示
  if( Int_1Sec == true ){
    Int_1Sec = false ;
    LED( ) ;
  }
  
  // 現在時刻を取得
  if( TimeInEn == true ){
    TimeInEnEnd = true ;
    TimeInEn = false ;
    WiFiTime( ) ;    
  }
  
  // DisPlay Bright Adjust
  if( DisplayTime == true ){
    val = analogRead( analogPin ) ;  // read the input pin 
    if( val <= 1490 ){
      SetBrightNoNew = 3 ;
    }
    else if(  val <= 2980 ){
      SetBrightNoNew = 2 ;
    }
    else{
      SetBrightNoNew = 1 ;
    }
    
    if( SetBrightNoOld != SetBrightNoNew ){
      SetBrightNoOld = SetBrightNoNew ;
      display.setBrightness( SetBrightNoOld ) ; 
    }
    DisplayTime = false ;     
  }
}

void connectToWiFi( ){
  // WiFiに接続
  WiFi.begin( ssid, password ) ;
  // WiFi接続出来るまで繰り返す
  while( WiFi.status( ) != WL_CONNECTED ){
    delay( 500 ) ;
  }
  // WiFi接続成功!
}

bool getLocalTime( ){
  struct tm timeinfo ;
  return getLocalTime( &timeinfo ) ;
}

void printLocalTime( ){
  struct tm timeinfo ;
  if ( !getLocalTime( &timeinfo ) ){
    // 時刻取得エラー
    ErrFlg = true ;
    return;
  }
  ErrFlg = false ;
  // 時刻を整形して表示
  //Serial.printf( "現在時刻: %04d/%02d/%02d %02d:%02d:%02d\n",
  //              timeinfo.tm_year + 1900,
  //              timeinfo.tm_mon + 1,
  //              timeinfo.tm_mday,
  //              timeinfo.tm_hour,
  //              timeinfo.tm_min,
  //              timeinfo.tm_sec ) ;
 Sec = ( char )timeinfo.tm_sec ;        // 秒
 Min = ( char )timeinfo.tm_min ;        // 分
 Hor = ( char )timeinfo.tm_hour ;       // 時
 
 //ESP32のWi-Fi切断
  WiFi.disconnect( true ) ;
}

/***************************************************/
//	FunctionName : WiFi時刻取得
//		Prototype: void WiFiTime( void )
//		Function : WiFi時刻設定 
//		Input    : NONE			
//		Output   : NONE	  
/***************************************************/
void WiFiTime( void ){
  
  connectToWiFi( ) ;
  
  // NTP時刻設定
  configTime( gmtOffset_sec, daylightOffset_sec, ntpServer ) ;
  // 時刻同期を待つ
  // NTPサーバーから時刻を取得中
  while ( !getLocalTime( ) ){
    // 時刻取得に失敗 再試行中...
    ErrFlg = true ;
    delay( 1000 ) ;
  }
  ErrFlg = false ;
  // 時刻取得完了!
  printLocalTime( ) ;
}

/***************************************************/
//	FunctionName : Led Write Task							
//		Prototype: void LED( void )                   		
//		Function : LED DATA SET	& WRITE
//		Input    : NONE								     
//		Output   : NONE	    						
/***************************************************/
void LED( void ){
  if( ++Sec >= 60 ){
    Sec = 0 ;
    if( TimeInEnEnd == true ){
      TimeInEnEnd = false ;
    }
    DisplayTime = true ;
    Min = ++Min ;        // 分
    if( Min >= 60 ){
      Min = 0 ;
      ++Hor ;
      if( Hor >= 24 ){
        Hor = 0 ;              
      }
      if( ++TimeInEnCnt >= 2 ){  // 2時間経過
        TimeInEnCnt = 0 ;
        TimeInEn = true ;
        //WiFiTime( ) ; //WiFi時間設定
      }
    }
  }
  //時計表示切替
  data[0] = display.encodeDigit(Hor / 10);
  data[1] = display.encodeDigit(Hor % 10) | 0b10000000;
  data[2] = display.encodeDigit(Min / 10);
  data[3] = display.encodeDigit(Min % 10);
  display.setSegments( data ) ;
}