/********************************************************/   
//       FILE        リモコン時計 (7SegLED) 
//       DATE        :Tue, Jan 10, 2025                                     
//       DESCRIPTION : タイマー割り込みにて 制御。	                           
//       CPU TYPE    : Arduino UNO                                          
//                                         				by Chiyabo                         
//      This file is generated by Renesas Project Generator.               
/********************************************************/   
                                                                                                
#define SI  8													                                   								       
#define SCK 9													                                   								       
#define RCK 10                                                                                  
#define SEL1 11													                                 								       
#define SEL2 12													                                 								       
#define SEL3 13                                                                                 

//超シンプル 赤外線リモコン受信(NECフォーマット)    
                                                                                                
#define BAUDRATE 9600                                                                           
#define DATAPIN 2	//ArduinoUNO:2   M5Stamp:19 RaspberryPi PICO:8     
//赤外線リモコン受信  
#define NECT 562                // クロック基準時間(NECフォーマット)     

bool iRrepeatCoomand ;                                                                          
uint16_t iRAddr ;                                                                               
uint8_t iRCommand ;                                                                             
uint8_t TimeInCnt = 0 ;                                                                         
uint8_t TimeInEn = false ;                                                                      
                                                                                                
uint8_t RemoconTimeSec = 0 ;                                                                    
uint8_t RemoconTimeMin = 0 ;                                                                    
uint8_t RemoconTimeHor = 0 ;                                                                    
                                                                                                
char sec = 0 ;            // 秒                    
char min = 59 ;        // 分                    
char hor = 23 ;        //  時                    
                                                                                                
int Sec_Change = 0 ;                                                                            
int Min_Change = 0x59 ;                                                                         
int Hor_Change = 0x23 ;                                                                         
                                                                                                
unsigned int Time_Up_Cnt = 0 ;  // 1Sec=( 1.6ms * Time_Up_Cnt(625) )                            
unsigned int Timer_Cnt = 2 ;    	// Timer-Int(2) * 800us = 1.6ms                                 
unsigned int Timer_Adjust = 625 ;  // 1000ms / 1.6ms = 625                                      
char HorCnt = 0 ;                                                                               
char HorCnt_24 = 0 ;                                                                            
char HorDwnCnt = 0 ;                                                                            
                                                                                                
unsigned char Led_Sel = 0 ;                                                                     
unsigned char Led_Dot = 0 ;                                                                     
unsigned char Code ;                                                                            
                                                                                                
const unsigned char Led_Code[ ] = {0x5f,0x50,0x6d,0x79,0x72,0x3b,0x3f,	// "0"~"6"
								                  0x51,0x7f,0x73,0x77,0x3e,0x0f,0x7c,		// "7"~"d"
								                  0x2f,0x27								              // "e"~"f"
								                  } ;
                                                                                               
void setup( ){														                               								       
  Serial.begin( BAUDRATE ) ;                                                                    
  Serial.println( "\n Tokei To 7Seg-Display" ) ;                                                
                                                                                                
  pinMode( DATAPIN,INPUT );  // ( REMOCONINT_INPUT );                                           
                                                                                                                                           
  pinMode( SI, OUTPUT ) ;										                             								       
  pinMode( SCK, OUTPUT ) ;										                           								          
  pinMode( RCK, OUTPUT ) ;										                                                  
  pinMode( SEL1, OUTPUT ) ;										                           								        
  pinMode( SEL2, OUTPUT ) ;										                           								       
  pinMode( SEL3, OUTPUT ) ;										                           								       
                                                         
  digitalWrite( SEL1, HIGH ) ;                                                                  
  digitalWrite( SEL2, HIGH ) ;                                                                  
  digitalWrite( SEL3, HIGH ) ;                                                                  
                                                                                                
  // タイマー割り込み設定                                                                       
  TCCR1A = 0; // タイマー1動作モードを初期化                                                      
  TCCR1B = ( 1 << WGM12 ) | ( 1 << CS11 ) ; 	//CTCモード 分周比1/8
           								//WGM12 = CS11 = 1      
  OCR1A = 1600 - 1 ; 		// 800μsとなるように設定                                                    
  TIMSK1 = ( 1 << OCIE1A ) ; // タイマー1のAマッチ割り込みを許可  OCIE1A = 1           
}																	                                       								       																
																	                                       								       
void loop( ){														                                 								       
                                                                                                
  if( readIrData( ) ){                                                                          
    if( iRrepeatCoomand ){                                                                      
      Serial.print( "Repeat " ) ;                                                               
    }                                                                                           
    Serial.print( "Addr:" ) ;                                                                   
    Serial.print( iRAddr, HEX ) ;                                                               
    Serial.print("  Command:" ) ;                                                               
    Serial.println( iRCommand,HEX ) ;                                                           
  }                                                                                             
}                                                                                                     
                                                                                                
// TIMER割込みサービスルーチン                                                                    
ISR( TIMER1_COMPA_vect ){                                                                       
  if( --Timer_Cnt == 0 ){                                                                       
    Timer_Cnt = 2 ; // 800us*2=1.6ms 625Hz                                                      
    LED( ) ;                                                                                    
  }                                                                                             
}                                                                                               
                                                                                                
bool readIrData( ){                                                                             
  bool retStat = true ;                                                                         
  uint8_t readData[ 4 ] ;                                                                       
  int setPos = 0 ;                                                                                   
  int bitLen = 0 ;                                                                              
  int stat = HIGH ;                                                                             
  uint8_t bitData ;                                                                             
  unsigned long beginTime ;                                                                     
  unsigned long passTime ;                                                                      
  memset( readData, 0, sizeof( readData ) ) ;                                                   
  iRrepeatCoomand = false ;                                                                     
                                                                                                
  // ----- データ受信開始待ち -----                                                               
  while( digitalRead( DATAPIN ) == HIGH ) ;   	// LOWになるまで待つ     
  // ----- FRAMAE受信開始 -----
  beginTime = micros( ) ;                                                                       
  while( digitalRead( DATAPIN ) == LOW ) ;      // LeaderのHIGHの長さを計測    
  passTime = micros( ) - beginTime ;                                                            
  if( passTime < NECT * 12  || passTime > NECT * 20 ){                                          
    return false ;                                                                              
  }                                                                                             
                                                                                                
  // ----- FRAMAE種別 -----                                                                     
  beginTime = micros( ) ;                                                                       
  while( digitalRead( DATAPIN ) == HIGH ) ;                                                     
  passTime = micros( ) - beginTime ;                                                            
  if( passTime <= NECT * 6 ){	// LOW時間が6T以下ならばRepeatと判断    
    // Repeace FRAME                                                                            
    iRrepeatCoomand = true ;                                                                    
    return true ;                                                                               
  }                                                                                             
                                                                                                
  // ----- データ受信 -----                                                                      
  bitData = 0x01 ;                                                                              
  beginTime = micros( ) ;                                                                       
  bitLen = 0 ;                                                                                  
  stat = LOW ;                                                                                  
  passTime = 0 ;                                                                                
  while( bitLen < 32 && passTime < NECT * 6 ){                                                  
    passTime = micros( ) - beginTime ;                                                          
    if( digitalRead( DATAPIN ) !=  stat ){                                                      
      if( stat == HIGH ){                                                                       
        // ----- 1Bit 受信 -----                                                                 
        if( passTime >= NECT * 2 ){                                                             
          readData[ setPos ] |= bitData ;                                                       
        }                                                                                       
        if( bitData != 0x80 ){                                                                    
          bitData <<= 1 ;                                                                       
        }                                                                                       
        else{                                                                                   
          bitData = 0x01 ;                                                                      
          setPos ++ ;                                                                           
        }                                                                                       
        beginTime = micros( ) ;                                                                 
        bitLen ++ ;                                                                             
        stat = LOW ;                                                                            
      }                                                                                         
      else{                                                                                     
        beginTime = micros( ) ;                                                                 
        stat = HIGH ;                                                                           
      }                                                                                         
    }                                                                                           
  }                                                                                             
  bitData = ~readData[ 3 ] ;                                                                    
  retStat = ( bitData == readData[ 2 ] ) ? true :false ;                                        
  iRAddr = readData[ 1 ] << 8 | readData[ 0 ] ;                                                 
  iRCommand = readData[ 2 ] ;                                                                   
                                                                                                
  if( iRCommand == 0x76 ){ // 黄色                                                              
    if( TimeInEn == true ){                                                                   
      TimeInCnt = 0 ;                                                                          
      TimeInEn = false ;                                                                      
    }                                                                                                        
    else{                                                                                     
      TimeInEn = true ;                                                                         
      TimeInCnt = 0 ;                                                                            
    }                                                                                         
  }                                                                                             
                                                                                                
  if( TimeInEn == true ){                                                                       
    if( TimeInCnt <= 6 ){                                                                       
      //Serial.println( TimeInCnt, DEC ) ;                                                      
      switch ( TimeInCnt ){                                                                     
        // 時 設定                                                                               
        case 1 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                     
          else if( iRCommand <= 2 ){                                                            
            RemoconTimeHor = ( iRCommand * 10 ) ;                                               
          //Serial.println( RemoconTimeHor, DEC ) ;                                             
          }                                                                                     
        break ;                                                                                 
        case 2 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                     
          else if( iRCommand <= 9 ){                                                            
            RemoconTimeHor =( RemoconTimeHor + iRCommand ) ;                                    
            //Serial.println( RemoconTimeHor, DEC ) ;                                           
          }                                                                                     
          if( RemoconTimeHor > 23){	// ダブルチェック         
            RemoconTimeHor = 0 ;                                                                 
          }                                                                                     
          hor = RemoconTimeHor ;	// 時                    
          Hor_Change = HexChgDec( hor ) ;	// HEXをDEC値に変換する   
          //Serial.println( hor, DEC ) ;                                                        
        break ;                                                                                 
                                                                                                
        // 分 設定                                                                              
        case 3 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                     
          else if( iRCommand <= 5 ){                                                            
            RemoconTimeMin = ( iRCommand * 10 ) ;                                               
          }                                                                                     
        break ;                                                                                 
        case 4 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                      
          else if( iRCommand <= 9 ){                                                            
            RemoconTimeMin =( RemoconTimeMin + iRCommand ) ;                                    
          }                                                                                     
          if( RemoconTimeMin > 59){		//ダブルチェック         
            RemoconTimeMin = 0 ;                                                                  
          }                                                                                      
          min = RemoconTimeMin ;           // 分                    
          Min_Change = HexChgDec( min ) ;	// HEXをDEC値に変換する    
        break ;                                                                                       
                                                                                                
        // 秒 設定                                                                              
        case 5 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                     
          else if( iRCommand <= 5 ){                                                            
            RemoconTimeSec = ( iRCommand * 10 ) ;                                               
          }                                                                                     
        break ;                                                                                 
        case 6 :                                                                                
          if( iRCommand == 10 ){                                                                
            iRCommand = 0 ;                                                                     
          }                                                                                     
          else if( iRCommand <= 9 ){                                                            
            RemoconTimeSec =( RemoconTimeSec + iRCommand ) ;                                    
          }                                                                                     
          if( RemoconTimeSec > 59){		//ダブルチェック        
              RemoconTimeSec = 0 ;                                                              
          }                                                                                      
          sec = RemoconTimeSec ;             // 秒                    
          Sec_Change = HexChgDec( min ) ;	// HEXをDEC値に変換する    
          TimeInCnt = 0 ;                                                                        
          TimeInEn = false ;                                                                    
        break ;                                                                                        
                                                                                                
        default :                                                                               
          ;                                                                                     
        break ;                                                                                 
      }                                                                                         
      ++TimeInCnt ;                                                                             
    }                                                                                           
    else{                                                                                       
      TimeInCnt = 0 ;                                                                            
      RemoconTimeHor = 0 ;                                                                      
      RemoconTimeMin = 0 ;                                                                      
      RemoconTimeSec = 0 ;                                                                      
    }                                                                                           
  }                                                                                             
  return retStat ;                                                                              
}                                                                                               
                                                                                                
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
//     	FunctionName : Led Write Task									                     
//     		Prototype: void LED( void )                   				           
//     		Function : LED DATA SET	& WRITE								                   
//     		Input    : NONE								                                   
//     		Output   : NONE	    									                           
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */ 
void LED( void ){                                                                               
  unsigned char	Code ;													                         					             
  unsigned char	Change_Code ;                                                                   
                                                                         					             
  // Disp Off                                                                                   
  digitalWrite( SEL1, HIGH ) ;                                                                  
  digitalWrite( SEL2, HIGH ) ;                                                                  
  digitalWrite( SEL3, HIGH ) ;                                                                  
                                                                         					             
  if( ++Led_Sel >= 6 ){									                                 					             
    Led_Sel = 0 ;       								                                 					             
  }																                                       					             
                                                                                                
  if( ++Time_Up_Cnt >= Timer_Adjust ){   // 1Sec                  
    Time_Up_Cnt = 0 ;                                                                           
    if( Led_Dot == 0 ){                                                                         
        Led_Dot = 1 ;                                                                            
      }                                                                                         
    else{                                                                                       
        Led_Dot = 0 ;                                                                           
    }                                                                                           
                                                                                                
    if( HorDwnCnt == 0 ){                                                                       
      if( ++sec >= 60 ){                                                                        
        sec = 0 ;                                                                               
        Sec_Change = HexChgDec( sec ) ;    // HEXをDEC値に変換する   
        if( ++min >= 60 ){                                                                      
          min = 0 ;                                                                             
          Min_Change = HexChgDec( min ) ;   // HEXをDEC値に変換する   
          if( ++hor >= 24 ){                                                                    
            hor = 0 ;                                                                                         
            Hor_Change = HexChgDec( hor ) ;  // HEXをDEC値に変換する   
          }                                                                                     
          else{                                                                                 
            Hor_Change = HexChgDec( hor ) ;   // HEXをDEC値に変換する   
          }                                                                                     
          if( ++HorCnt >= 2 ){  // 2時間経過                                                     
            HorCnt = 0 ;                                                                        
            HorDwnCnt = 1 ; 	// 1Secカウント停止(時間調整)                                       
            if( ++HorCnt_24 >= 12 ){                                                            
              HorCnt_24 = 0 ;                                                                   
              HorDwnCnt = ( HorDwnCnt + 2 ) ; 	// 停止時間追加                                    
            }                                                                                   
          }                                                                                     
        }                                                                                       
        else{                                                                                   
          Min_Change = HexChgDec( min ) ;	// HEXをDEC値に変換する   
        }                                                                                       
      }                                                                                         
      else{                                                                                     
        Sec_Change = HexChgDec( sec ) ;	// HEXをDEC値に変換する   
      }                                                                                         
    }                                                                                           
    else{                                                                                       
      --HorDwnCnt ;                                                                             
    }                                                                                           
  }                                                                                                   
                                                                                                
  switch( Led_Sel ){									                                   					             
    case	0 :													                                   					             
      Change_Code = ( char )( Sec_Change & 0x000f ) ;                                           
      Code = ~Led_Code[ Change_Code ] ;                                  					             
      if( TimeInEn == true ){                                                                   
        if( Led_Dot == 1){                                               					             
          Code = ( Code | 0x80 ) ;                                       					             
        }                                                                					             
        else{                                                            					             
          Code = ( Code & 0x7F ) ;                                       					               
        }                                                                					             
      }                                                                                            
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, LOW ) ;                                                               
      digitalWrite( SEL2, LOW ) ;                                                               
      digitalWrite( SEL3, LOW ) ;                                                               
    break ;												                                       					             
                                                                         					             
    case	1:													                                   					             
      Change_Code =( char )( ( Sec_Change & 0x00f0 ) >> 4 ) ;                                   
      Code = ~Led_Code[ Change_Code ] ;	                                 					             
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, HIGH ) ;                                                              
      digitalWrite( SEL2, LOW ) ;                                                                 
      digitalWrite( SEL3, LOW ) ;                                                               
    break ;		  										                                     					             
                                                                         					             
    case	2:													                                   					             
      Change_Code =( char )( Min_Change & 0x000f ) ;                                            
      Code = ~Led_Code[ Change_Code ] ;                                  					             
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, LOW ) ;                                                               
      digitalWrite( SEL2, HIGH ) ;                                                                
      digitalWrite( SEL3, LOW ) ;                                                               
    break ;				  								                                     					             
                                                                         					             
    case	3:													                                   					             
      Change_Code =( char )(( Min_Change & 0x00f0 ) >> 4 ) ;                                    
      Code = ~Led_Code[ Change_Code ] ;	// Test                          					             
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, HIGH ) ;                                                              
      digitalWrite( SEL2, HIGH ) ;                                                                
      digitalWrite( SEL3, LOW ) ;                                                               
    break ;												                                       					             
                                                                         					             
    case	4:													                                   					             
      Change_Code =( char )( Hor_Change & 0x000f ) ;                                            
      Code = ~Led_Code[ Change_Code ] ;                                  					             
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, LOW ) ;                                                               
      digitalWrite( SEL2, LOW ) ;                                                                 
      digitalWrite( SEL3, HIGH ) ;                                                              
    break ;												                                       					             
                                                                         					             
    case	5:													                                   					             
      Change_Code =( char )(( Hor_Change & 0x00f0 ) >> 4 ) ;                                       
      Code = ~Led_Code[ Change_Code ] ;                                  					             
      ShiftCode( Code ) ;                                                                         
      digitalWrite( SEL1, HIGH ) ;                                                              
      digitalWrite( SEL2, LOW ) ;                                                                 
      digitalWrite( SEL3, HIGH ) ;                                                              
    break ;												                                       					             
                                                                         					             
    default:													                                   					             
      // Disp Off                                                                               
      digitalWrite( SEL1, HIGH ) ;                                                              
      digitalWrite( SEL2, HIGH ) ;                                                              
      digitalWrite( SEL3, HIGH ) ;                                                               
    break ;												                                       					             
  }																                                       					             
}																	                                       					             
                                                                         					             
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
//     	FunctionName : ShiftCode Task									                     
//     		Prototype: void ShiftCode( unsigned char )                       
//     		Function : LED DATA SET	& WRITE								                   
//     		Input    : NONE								                                   
//     		Output   : NONE										                               
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
void ShiftCode( unsigned char Code ){                                                           
  char  Count ;                                                                                 
  unsigned char  Scode ;                                                                        
                                                                                                
  Scode = Code ;                                                                                
  for( Count = 0 ; Count <= 7 ; ++Count ){                                                      
    if( ( Scode & 0x80 ) == 0x80 ){                                                             
      digitalWrite( SI, HIGH ) ;                                                                 
    }                                                                                           
    else{                                                                                       
      digitalWrite( SI, LOW ) ;                                                                  
    }                                                                                             
    Scode = ( Scode << 1 ) ;                                                                      
    //delayMicroseconds( 5 ) ;                                                                   
    digitalWrite( SCK, HIGH ) ;                                                                  
    //delayMicroseconds( 5 ) ;                                                                   
    digitalWrite( SCK, LOW ) ;                                                                   
    //delayMicroseconds( 5 ) ;                                                                   
  }                                                                                             
  digitalWrite( RCK, HIGH ) ;                                                                    
  //delayMicroseconds( 5 ) ;                                                                     
  digitalWrite( RCK, LOW ) ;                                                                     
}                                                                                               

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
//	FunctionName : HexChgDec								
//		Prototype: int HexChgDec(unsigned char HexByte)
//		Function : HEXをDEC値に変換する								 
//		Input    : 00h-->ffh										
//    Output   : 変換結果											 
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
int HexChgDec( unsigned char HexByte ){
	unsigned char i ;										
	int Value , Work ;									
  
	i = 0 ;
	Value = Work = 0 ;
	for( Work = 0 ; HexByte >= 0x0a ; Work++ ){
		HexByte = ( HexByte - 0x0a ) ;
	}																
	if( Work >= 0x0a ){							
		for( i = 0 ;  Work >= 0x0a ; i++ ){
			Work = ( Work - 0x0a ) ;						
		}															
	}																
	Value = ( ( i * 0x100 ) + ( Work * 0x10 ) + ( int )HexByte ) ;
	return Value;										
}