/****************************************************/
// FILE JJY-DENPA-TEST 電波時計
// DATE :Tue, Jan 10, 2025
// DESCRIPTION : JJY模擬発生 試験
// CPU TYPE : Arduino UNO
// by Chiyabo
// This file is generated by Renesas Project Generator.
/****************************************************/
#include < LiquidCrystal_I2C.h > // ライブラリのインクルード
LiquidCrystal_I2C lcd( 0x27, 16 , 2 ) ;// 0x27のアドレス,16列2行のLCDを使用
#define TEST_JJY 3
#define EXT_INT 2
#define MAKER 0
#define OUTPUT_1 1 //'1'
#define OUTPUT_2 2 //'0'
#define Timer_Cnt0 63 // Timer-Int(2) * 800us * Timer_Cnt1 = 100ms
#define Timer_Cnt1 225 // Timer-Int(2) * 800us * Timer_Cnt1 = 360ms
#define Timer_Cnt2 287 // Timer-Int(2) * 800us * Timer_Cnt2 = 460ms
#define Timer_Cnt3 350 // Timer-Int(2) * 800us * Timer_Cnt3 = 560ms
#define Timer_Cnt4 413 // Timer-Int(2) * 800us * Timer_Cnt4 = 660ms
//#define JJY_TEST_MODE // 模擬電波 D3からOutPut
#define Timer_Adjust 625 // 1000ms / 1.6ms = 625
// 電波発生 定義
unsigned int Out_Maker_Cnt = 0 ;
unsigned char OutPut_End = false ;
unsigned char OutPutNomber = 0 ;
unsigned char OutBitFlg = false ;
// 0:Maker 1:H 2:L
const unsigned char OutPutSel[ ] = { 0, 0,
2, 2, 1, 2, 2, 1, 2, 1, 0, //15分
2, 2, 2, 1, 2, 2, 1, 1, 1 //17時
} ;
// JJY 電波取り込み
volatile byte Ext_Int_En = true ; // 外部割込み 開始
volatile byte Ext_Int_Act = false ; // 外部割り込み有
char JJY_Read_Start = false ;
char Maker_Chk = 0 ; // マーカーの0の数
char Maker_Cnt = 0 ; // マーカーの0の数が連続4回で’1’セット
//マーカー2回読み込み
char Level_H_Cnt = 0 ;
char Retray = false ;
char Old_hor ;
unsigned char Read_Cnt = 0 ;
unsigned char Read_Min = 0 ;
unsigned char Read_Hor = 0 ;
unsigned int Level_Check_Cnt = 0 ;
// LED-Display
char sec = 0 ; // 秒
char min = 59 ; // 分
char hor = 23 ; // 時
char SetMinHor = false ;
int Sec_Change = 0 ;
int Min_Change = 0x59 ;
int Hor_Change = 0x23 ;
// Timer INT
unsigned int Timer_Cnt = 0 ; // Timer-Int(2) * 800us = 1.6ms
void setup( ){
//Serial.begin( 9600 ) ;
//Serial.println( "\n Denpa_Tokei Test" ) ;
lcd.init( ) ; // LCDの初期化
lcd.backlight( ) ; // LCDバックライトの点灯
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "JJY_Tokei Test" ) ; // カスタムコード(HEX)
pinMode( TEST_JJY, OUTPUT ) ;
pinMode( EXT_INT,INPUT ); //割り込み番号0用の入力ピン
// タイマー割り込み設定
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
// 外部割り込み設定
attachInterrupt(digitalPinToInterrupt( EXT_INT ), JJY_TCO, RISING ) ; 立ち上がり割り込み
// 割り込み処理関数 :JJY_TCO
}
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 loop( ){
if( Timer_Cnt == 0 ){
Timer_Cnt = 2 ; // 800us*2=1.6ms 625Hz
JJY_TCO_READ( ) ;
#ifdef JJY_TEST_MODE
if( Ext_Int_En == true ){
// 模擬JJY発生Pro
if( OutPut_End == true){
if( ++OutPutNomber >= 20 ){ ;
Serial.println( "\n JJY-OutPut Retry" ) ;
OutPutNomber = 0 ;
}
OutPut_End = false ;
Out_Maker_Cnt = 0 ;
}
if( OutBitFlg == false ){
OutBitFlg = true ;
Serial.println( OutPutSel[ OutPutNomber ], DEC ) ;
}
Denpa( OutPutSel[ OutPutNomber ] ) ;
}
#endif
}
}
// TIMER割込みサービスルーチン
ISR( TIMER1_COMPA_vect ){
if( Timer_Cnt > 0 ){
--Timer_Cnt ;
}
}
// 外部割込みサービスルーチン
void JJY_TCO( ){
char i ;
char j = 0 ;
if( Ext_Int_En == true ){
for( i = 0 ; i < 10 ; i++ ){
if( digitalRead( EXT_INT ) == 1 ){
j++ ;
}
else{
j = 0 ;
}
}
if( j >= 10 ){
Ext_Int_Act = true ;
}
}
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
FunctionName : DENPA TEST Task
Prototype: void Denpa( unsigned char )
Function : LED DATA SET & WRITE
Input : JJY_SEL
Output : NONE
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
void Denpa( unsigned char JJY_SEL ){
++Out_Maker_Cnt ;
switch( JJY_SEL ){
case MAKER :
if( Out_Maker_Cnt <= 125 ){
digitalWrite( TEST_JJY, HIGH ) ;
}
if( Out_Maker_Cnt >= 126 ){
digitalWrite( TEST_JJY, LOW ) ;
}
break ;
case OUTPUT_1: //'1'
if( Out_Maker_Cnt <= 312 ){
digitalWrite( TEST_JJY, HIGH ) ;
}
if( Out_Maker_Cnt >= 313 ){
digitalWrite( TEST_JJY, LOW ) ;
}
break ;
case OUTPUT_2: //'0'
if( Out_Maker_Cnt <= 500 ){
digitalWrite( TEST_JJY, HIGH ) ;
}
if( Out_Maker_Cnt >= 501 ){
digitalWrite( TEST_JJY, LOW ) ;
}
break ;
default:
;
break ;
}
if( Out_Maker_Cnt >= Timer_Adjust ){ // !sec経過
OutPut_End = true ;
Out_Maker_Cnt = 0 ;
OutBitFlg = false ;
//Serial.println( JJY_SEL, DEC ) ;
}
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
FunctionName : JJY_TCO READ Task
Prototype: void JJY_TCO_READ( void )
Function : 電波受信処理
Input : NONE
Output : NONE
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
void JJY_TCO_READ( void ){
char Set_Min = 0 ;
char Set_Hor = 0 ;
if( ( Ext_Int_En == true ) && ( Ext_Int_Act == true ) ){
// Maker Read Stage1
if( JJY_Read_Start == false ){
if( ++Level_Check_Cnt == Timer_Cnt0 ){ // 0.1Sec
if( digitalRead( EXT_INT ) == 1 ){
++Maker_Chk ;
}
else{
Retray = true ;
}
}
if( Level_Check_Cnt == Timer_Cnt1 ){ // 0.36Sec
if( digitalRead( EXT_INT ) == 0 ){
++Maker_Chk ;
}
else{
Retray = true ;
}
}
if( Level_Check_Cnt == Timer_Cnt2 ){ // 0.46Sec
if( digitalRead( EXT_INT ) == 0 ){
++Maker_Chk ;
}
else{
Retray = true ;
}
}
if( Level_Check_Cnt == Timer_Cnt3 ){ // 0.56Sec
if( digitalRead( EXT_INT ) == 0 ){
++Maker_Chk ;
}
else{
Retray = true ;
}
}
if( Level_Check_Cnt == Timer_Cnt4 ){ // 0.66Sec
if( digitalRead( EXT_INT ) == 0 ){
if( ( ++Maker_Chk == 5 ) && ( Maker_Cnt == 0 ) ){
++Maker_Cnt ; // マーカー2回目読み込み要求
Level_Check_Cnt = 0 ;
Ext_Int_Act = false ;
Maker_Chk = 0 ;
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "Maker_Set1 " ) ; // カスタムコード(HEX)
lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
lcd.print( " " ) ; // カスタムコード(HEX)
//Serial.println( "Maker_Set1 " ) ;
}
else if( ( Maker_Chk == 5 ) && ( Maker_Cnt == 1 ) ){
Maker_Cnt = 0 ; // マーカー2回目読み込みリセット
Maker_Chk = 0 ;
JJY_Read_Start = true ;
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "Maker_Read_Start" ) ; // カスタムコード(HEX)
//Serial.println( "Maker_Set2 JJY_Read_Start" ) ;
Level_Check_Cnt = 0 ;
Ext_Int_Act = false ;
}
else{
Retray = true ;
}
}
else{
Retray = true ;
}
}
if( Retray == true ){
//Serial.println( " Retray Maker" ) ;
JJY_Read_Start = false ;
Retray = false ;
Ext_Int_Act = false ;
Maker_Chk = 0 ;
Maker_Cnt = 0 ;
Level_Check_Cnt = 0 ;
}
}
// JJY_Read_Start == true
else{
if( ++Level_Check_Cnt == Timer_Cnt0 ){ // 0.1Sec
if( digitalRead( EXT_INT ) == 1 ){
++Level_H_Cnt ;
}
else{
Retray = true ;
}
}
if( Level_Check_Cnt == Timer_Cnt1 ){ // 0.36Sec
if( digitalRead( EXT_INT ) == 1 ){
++Level_H_Cnt ;
}
}
if( Level_Check_Cnt == Timer_Cnt2 ){ // 0.46Sec
if( digitalRead( EXT_INT ) == 1 ){
++Level_H_Cnt ;
}
}
if( Level_Check_Cnt == Timer_Cnt3 ){ // 0.56Sec
if( digitalRead( EXT_INT ) == 1 ){
++Level_H_Cnt ;
}
}
if( Level_Check_Cnt == Timer_Cnt4 ){ // 0.66Sec
if( digitalRead( EXT_INT ) == 1 ){
++Level_H_Cnt ;
}
// 信号確認
if( ( Level_H_Cnt == 5 ) && ( Read_Cnt <= 8 ) ){
Read_Min = ( Read_Min & 0xfe ) ;
}
else if( ( Level_H_Cnt == 5 ) && ( Read_Cnt >= 12 ) ){
Read_Hor = ( Read_Hor & 0xfe ) ;
}
if( ( Level_H_Cnt == 3 ) && ( Read_Cnt <= 8 ) ){
Read_Min = ( Read_Min | 0x01 ) ;
}
else if( ( Level_H_Cnt == 3 ) && ( Read_Cnt >= 12 ) ){
Read_Hor = ( Read_Hor | 0x01 ) ;
}
if( Read_Cnt != 8 ){
//if( ( Level_H_Cnt != 3 ) && ( Level_H_Cnt != 5 ) ){
if( Level_H_Cnt < 3 ){
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "Retry_Data_NG " ) ; // カスタムコード(HEX)
//Serial.println( "Retry_Data_NG" ) ;
Retray = true ;
}
}
Level_H_Cnt = 0 ;
if( Retray == false ){
if( ++Read_Cnt <= 7 ){
Read_Min = ( Read_Min << 1 ) ;
}
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "Read_Cnt " ) ; // カスタムコード(HEX)
lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
lcd.print( " " ) ;
lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
lcd.print( Read_Cnt, DEC ) ; // カスタムコード(HEX)
//Serial.println( "Read_Cnt" ) ;
//Serial.println( Read_Cnt, DEC ) ;
if( ( Read_Cnt >= 12 ) && ( Read_Cnt <= 17 ) ){
// 信号確認
Read_Hor = ( Read_Hor << 1 ) ;
}
if( Read_Cnt == 18 ){
//lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
//lcd.print( "JJY_Read_Hor " ) ; // カスタムコード(HEX)
//lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
//lcd.print( Read_Hor, BIN ) ; // カスタムコード(HEX)
//Serial.println( " JJY_Read_Hor:" ) ;
//Serial.println( Read_Hor, BIN ) ;
// 取得時間の計算
Set_Min = Set_Min + ( bitRead( Read_Min, 7 ) * 40 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 6 ) * 20 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 5 ) * 10 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 3 ) * 8 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 2 ) * 4 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 1 ) * 2 ) ;
Set_Min = Set_Min + ( bitRead( Read_Min, 0 ) * 1 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 6 ) * 20 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 5 ) * 10 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 3 ) * 8 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 2 ) * 4 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 1 ) * 2 ) ;
Set_Hor = Set_Hor +( bitRead( Read_Hor, 0 ) * 1 ) ;
//Serial.println( Set_Min, DEC ) ;
//Serial.println( Set_Hor, DEC ) ;
sec = 20 ;
if( ( Set_Min <= 59 ) && ( Set_Hor <= 23 ) ){ // 時分確定
min = Set_Min ;
Min_Change = HexChgDec( min ) ; // HEXをDEC値に変換する
if( Old_hor == Set_Hor ){
hor = Set_Hor ;
Hor_Change = HexChgDec( hor ) ; // HEXをDEC値に変換する
Ext_Int_En = false ;
lcd.setCursor( 0, 0 ) ; // カーソルの位置を指定
lcd.print( "Good-End " ) ; // カスタムコード(HEX)
lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
lcd.print( " " ) ;
lcd.setCursor( 0, 1 ) ; // カーソルの位置を指定
lcd.print( Set_Hor, DEC ) ;
lcd.setCursor( 3, 1 ) ; // カーソルの位置を指定
lcd.print( Set_Min, DEC ) ;
//Serial.println( " Good-End" ) ;
JJY_Read_Start = false ;
}
else{
Old_hor = Set_Hor ;
//Serial.println( " OutPut Retry_Old_Hor2" ) ;
JJY_Read_Start = false ;
Level_Check_Cnt = 0 ;
Read_Min = 0 ;
Read_Hor = 0 ;
Read_Cnt = 0 ;
}
}
else{
Retray = true ;
}
}
}
Ext_Int_Act = false ;
Level_Check_Cnt = 0 ;
}
if( Retray == true ){
//Serial.println( " Retray Hor-Min" ) ;
Retray = false ;
Ext_Int_Act = false ;
Level_Check_Cnt = 0 ;
Level_H_Cnt = 0 ;
JJY_Read_Start = false ;
Maker_Chk = 0 ;
Read_Min = 0 ;
Read_Hor = 0 ;
Read_Cnt = 0 ;
}
}
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
// 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;
}