見出し画像

卓上時計

前回記事でRTCモジュールから日時の情報が取り出せるようになり、時刻合わせもできるようになりました。定番のLCD 1602(I2C通信)をつないで「卓上時計」にしてみます。

LiquidCrystal I2C

Arduino IDEでのライブラリマネージャから、LiquidCrystal I2Cというのを検索してインストールしておきます。

画像1

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);//アドレス0x3Fの場合もある。

初期化

 lcd.init(); //初期化
 lcd.backlight();//バックライト点ける

書き込み位置指定

lcd.setCursor(0, 0);// 1行目の頭なら
//lcd.setCursor(0, 1);//2行目の頭なら

書き込み

lcd.print();//引数に数値や文字列

これだけ知っていればとりあえず使えそうです。

配線

画像2

I2C の配線ではSDAはArduinoUNOのA4ピン SCLはA5ピンにつなぎます。I2C の配線参考
  http://www.musashinodenpa.com/arduino/ref/index.php?f=1&pos=341

サンプルコード

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);//アドレス0x3Fの場合もある。                                    

#define SCLK  6   //(基板上CLK⇒6番ピン)

#define IO  7    //(基板上DAT⇒7番ピン)

#define CE  8    //(基板上RST⇒8番ピン)

struct DateTime{
 int Seconds;
 boolean CH; //1でClockHalt(停止)だが、0を入れてこの機能使わない前提
 int Minutes;
 int Hour;
 boolean Mode12; //1で12時間表示だが、0を入れて24時間表示で使う前提
 int Date;
 int Month;
 int Day;
 int Year;
 boolean WP; //1でWriteProtectだが0を入れてこの機能使わない前提
};

String DayString[]={"MON","TUE","WED","THU","FRI","SAT","SUN"};

void setup() {
 lcd.init(); 
 lcd.backlight();

 pinMode(CE, OUTPUT);
 pinMode(SCLK, OUTPUT);
};

void loop() {
byte RTC_clock_image[8];//クロックデータの読み込み用。1バイト×8の配列
DateTime myDateTime;
read_rtc_byte(RTC_clock_image);//読みだしてバイト列を格納
extract_datetime(RTC_clock_image,myDateTime);//抽出してmyDateTime 

//lcd.clear()
lcd.setCursor(0, 0);
lcd.print(dig2(myDateTime.Hour));lcd.print(":");
lcd.print(dig2(myDateTime.Minutes));lcd.print(":");
lcd.print(dig2(myDateTime.Seconds));
lcd.setCursor(0, 1);
lcd.print(myDateTime.Year);lcd.print("-");
lcd.print(dig2(myDateTime.Month));lcd.print("-");
lcd.print(dig2(myDateTime.Date));lcd.print("(");
lcd.print(DayString[myDateTime.Day-1]);lcd.print(")");
delay(200);//0.2秒(200ミリ秒)ごと更新。
}
//正の1桁数の場合の2桁表示(例:0⇒00 2⇒02)
String dig2(int value){
 String strvalue=String(value);
 if(strvalue.length()==1){
   strvalue = "0"+strvalue;
 }
 return(strvalue);
}
//RTCからクロックデータをまるごと読みだし、
byte read_rtc_byte(byte image[]){
 pinMode(IO, OUTPUT);//IOのpinmodeをまず送信用で準備
 digitalWrite(CE, LOW);wait();//最初はCE下げた状態
 digitalWrite(CE, HIGH);wait();//開始(CE 上げ)
 write_1byte(0xbf);//バーストモードのコマンド0xbf送信
 //読み出しに移るのでIOのピンモード切り替える。SCLK上げのまま
 pinMode(IO, INPUT);
 //8byte分続けて読みbyte配列のimageに入れる
 for (int i=0; i<=7; i++){
   read_1byte(image[i]);
 }
 //CE下げる
 digitalWrite(CE, LOW); wait(); 
}

void write_1byte(byte data){
 //コマンド等送信 1ビットずつ繰り返し8ビット(1バイト)分送る
 for (int i=0; i <= 7; i++){
   digitalWrite(SCLK, LOW);wait();  //LOW確認
   digitalWrite( IO, bitRead(data, i));wait();
   digitalWrite(SCLK, HIGH);wait();  //クロック(LOWからHIGH)で書き込む
   //クロック上げたままで関数を抜ける。
 }  
}

void read_1byte(byte &data){
 //データ受信 1ビットずつ繰り返し8ビット(1バイト)分読みだす
 data = 0;
 for (int i=0; i<=7; i++){ 
   digitalWrite(SCLK, HIGH);wait();//clock上げ。(上げたまま引き継いだ時はそのまま)
   digitalWrite(SCLK, LOW);wait();//clock下げて、
   bitWrite( data,i, digitalRead(IO));//読む
   //クロック下げた状態で関数を抜ける
 }  
}

void setImage(byte command, byte image){ //コマンド、書き込みデータ
 pinMode(IO, OUTPUT);//IOのpinmodeを送信用で準備
 digitalWrite(CE, LOW);wait();//最初はCE下げた状態
 digitalWrite(CE, HIGH);wait();//開始(CE 上げ)
 write_1byte(command);
 write_1byte(image); 
 digitalWrite(SCLK, LOW);wait();//clock下げて、 
 digitalWrite(CE, LOW);wait();//最後はCE下げる
}

void getImage(byte command, byte &image){
 pinMode(IO, OUTPUT);//IOのpinmodeを送信用で準備
 digitalWrite(CE, LOW);wait();//最初はCE下げた状態
 digitalWrite(CE, HIGH);wait();//開始(CE 上げ)
 write_1byte(command);
 pinMode(IO, INPUT);//IOのpinmodeを受信用に切り替え
 read_1byte(image); 
 digitalWrite(CE, LOW);wait();//最後はCE下げる  
}

void wait(){
//Vcc5Vなのでデータシート11ページから待ち時間は1μ秒分とっておけばよい。
delayMicroseconds(1);
}

//byte配列からの情報抽出
void extract_datetime(byte image[], DateTime &TempDateTime){
 int data10, data1;
 //秒
 data10 = (image[0]>>4)&7; //上位4ビットを0111でマスクする。
 data1 = image[0] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Seconds =  (data10 * 10) + data1;
 TempDateTime.CH = image[0]>>7;
 //分
 data10 = (image[1]>>4)&7; //上位4ビットを0111でマスクする。
 data1 = image[1] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Minutes =  (data10 * 10) + data1; 
 //時
 data10 = (image[2]>>4)&3; //上位4ビットを0011でマスクする。
 data1 = image[2] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Hour =  (data10 * 10) + data1; 
 TempDateTime.Mode12 = image[2]>>7; //12時間表示モード。0にして使わない。
 //日
 data10 = (image[3]>>4)&3; //上位4ビットを0011でマスクする。
 data1 = image[3] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Date =  (data10 * 10) + data1; 
 //月
 data10 = (image[4]>>4)&1; //上位4ビットを0001でマスクする。
 data1 = image[4] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Month =  (data10 * 10) + data1; 
 //曜日
 TempDateTime.Day =image[5];
 //年
 data10 = (image[6]>>4) & 15; //上位4ビットを1111でマスクする。
 data1 = image[6] & 15; //下位4ビットを1111でマスクする。
 TempDateTime.Year =  (data10 * 10) + data1 + 2000; 
 //WP
 TempDateTime.WP =image[7]>>7; 
}

無事動いた\(^o^)/

画像3



いいなと思ったら応援しよう!