/********************************************************/
// 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;
}