//
*****************************************************************************************
// Program name : world_clock.c
// Description : World_clock by Raspberry Pi Zero WH
// Author : Yoshio Kato
// Start date : 15th.Apr.2019
// Compile : cc -o world_clock world_clock.c -l wiringPi
// Excution : sudo ./world_clock
//*****************************************************************************************
#include <wiringPi.h> //wiringPiヘッダーファイルをインクルード
#include <time.h> //timeヘッダーファイルをインクルード
#include <stdio.h> //stdioiヘッダーファイルをインクルード
#include <stdlib.h> //stdlibヘッダーファイルをインクルード "system"
char offset_time[20] = {9,1,2,2,10,-10,-5,-5,2,-3,8,2,2,-7,2,-4,3,-7,10,2} ; //UTCとの差
// 0-9 London,Paris,Berlin,Sydney,Honolulu,Mexico City,NewYork,Cairo,Buenos Aires,
// 10-19 Ulaanbaatar,Oslo,Copenhagen,San Francisco,Zurich,Detroit, Nairobi, Vancouver,Melbourne, Roma
#define a 8 // a セグメント GPIO
#define b 14 // b セグメント GPIO
#define c 18 // c セグメント GPIO
#define d 23 // d セグメント GPIO
#define e 24 // e セグメント GPIO
#define f 25 // f セグメント GPIO
#define g 15 // g セグメント GPIO
#define shutdown_sw 26 //シャットダウンスイッチのGPIO
#define add10_sw 11 //+10スイッチのGPIO
char digit_gpio[4] = {21,16,12,20} ; //デジット選択 GPIO D1,D2,D3,D4
char thumbwheel_sw_gpio[4] = {2,3,4,17} ; // サムホイールスィッチ GPIO
char segment[10][8] ={{a,b,c,d,e,f,0,0}, //0のセグメントデータ
{b,c,0,0,0,0,0,0}, //1のセグメントデータ
{a,b,d,e,g,0,0,0}, //2のセグメントデータ
{a,b,c,d,g,0,0,0}, //3のセグメントデータ
{b,c,f,g,0,0,0,0}, //4のセグメントデータ
{a,c,d,f,g,0,0,0}, //5のセグメントデータ
{a,c,d,e,f,g,0,0}, //6のセグメントデータ
{a,b,c,f,0,0,0,0}, //7のセグメントデータ
{a,b,c,d,e,f,g,0}, //8のセグメントデータ
{a,b,c,d,f,g,0,0}} ; //9のセグメントデータ
time_t timer ;
struct tm *tim ; //構造体の設定
//*****************************************************************************************
// 初期設定処理
//*****************************************************************************************
int init(){
int i ;
if(wiringPiSetupGpio() == -1) //wiringPiの設定 戻り値が-1の時はエラー
return(-1) ; //エラーリターン
for(i=0; i<4; i++){ //デジット、サムホイールスイッチのGPIO設定
pinMode(digit_gpio[i],OUTPUT) ; //デジットのGPIOを出力
pinMode(thumbwheel_sw_gpio[i],INPUT) ; //サムホイールスイッチのGPIOを入力
pullUpDnControl(thumbwheel_sw_gpio[i],PUD_UP) ; //サムホイールスイッチのGPIOをプルアップ
}
for(i=0; i<7;i++)
pinMode(segment[8][i],OUTPUT) ; //各セグメントのGPIOを出力
pinMode(shutdown_sw,INPUT) ; //シャットダウンスイッチのGPIOを入力
pullUpDnControl(shutdown_sw,PUD_UP) ; //シャットダウンスイッチのGPIOをプルアップ
pinMode(add10_sw,INPUT) ; //add10スイッチのGPIOを入力
pullUpDnControl(add10_sw,PUD_UP) ; //add10スイッチをプルアップ
return(1) ;
}
//*****************************************************************************************
// サムホイールスイッチの読み込み
//*****************************************************************************************
int read_sw_value(){
int i ;
int data = 0 ;
for(i=0 ;i<4; i++) //サムホイールスイッチから4ビット読み込む
data = (data << 1) | !(digitalRead(thumbwheel_sw_gpio[i])) ;
if(digitalRead(add10_sw) == 0) //add10_swがonならば10を加える
data += 10 ; //data=data + 10
return(data) ; //読み込んだデータを返す
}
//*****************************************************************************************
// 7セグメント表示器を消去
//*****************************************************************************************
void erase_7seg_led(){
int i ;
for(i=0; i<7; i++)
digitalWrite(segment[8][i],1) ; //a~gセグメントを5V
for(i=0; i<4; i++)
digitalWrite(digit_gpio[i],0) ; //デジット1~4を0V
}
//*****************************************************************************************
// 指定したデジットに数字を表示
//*****************************************************************************************
void display_data(char dgt, char time_data){
int i =0 ;
erase_7seg_led() ; //全ての表示を消去
while(segment[time_data][i] != 0) //数字を構成するデータが0出ない間繰り返す
digitalWrite(segment[time_data][i++],0) ; //対応するセグメントを0V
digitalWrite(digit_gpio[dgt],1) ; //指定したデジットを5V 数字が表示
delay(4) ; //4ms時間をおく
}
//*****************************************************************************************
// 時と分の表示
//*****************************************************************************************
void display(){
display_data(0,tim->tm_hour /10) ; //時を10で割り商をデジット1へ表示
display_data(1,tim->tm_hour %10) ; //時を10で割り余りをデジット1へ表示
display_data(2,tim->tm_min /10) ; //分を10で割り商をデジット1へ表示
display_data(3,tim->tm_min % 10) ; //分を10で割り余りをデジット1へ表示
}
//*****************************************************************************************
// メイン
//*****************************************************************************************
int main(){
char count = 60 ; //表示回数カウンター用
char i ; //UTCとの差分用
if(init() == -1) //初期設定処理をコール
return(-1) ; //初期設定処理でエラー発生ならば終了
while(digitalRead(shutdown_sw) != 0){ //シャットダウンスイッチが押されていない間繰り返す
if(count == 60){ //60回(約1秒)表示したら時間を求める
i = 24 + offset_time[read_sw_value()] ;
//サムホイールスイッチの値からUTCとの差を求める
if(i >= 24)
i -= 24 ; //その値が24より大きいときは24を引く
time(&timer) ;
tim = gmtime(&timer) ; //現在時刻を求める
tim->tm_hour = tim->tm_hour + i ; //UTCとの差分で現地時刻にする
if(tim->tm_hour >= 24) //24を超えたら翌日なので24を引く
tim->tm_hour = tim->tm_hour -24 ;
count = 0;
}
display() ; //表示処理をコール
count++ ; //表示回数に1を加える
}
erase_7seg_led() ; //全ての表示を消去
count = 0 ;
while(digitalRead(shutdown_sw) == 0){ //shutdownスイッチがはなされるまでの間実行
delay(100) ; //100msのdelay
count ++ ; //100ms毎にcountをプラスする
}
if(count >= 30) //countが30(3秒)以上か
system("sudo shutdown -h now") ; //3秒以上なのでshutdownコマンドを実行し終了する
else
return(1) ; //shutdownではないのでOSへ戻る
}
//********************************** End of Program ******************************************