binary clock

## 目的
2進数表記の時計を作りたい

## 超ざっくりした流れ
1．時計を表現するために4×4の配列を準備
![2021-06-22 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1675184/68d9670d-87db-1222-f73c-c2ec709b0d5f.png)
2．今の時間を取得する(例えば、21:57)
3．取得した時間を元に、それぞれのポイントで光るか光らないかを制御


## 流れ
###### void setup()
・時計を表現するために4×4の配列を準備

今からそれぞれの場所がHIGHなら光って、LOWならライトが消えるようにしたい。（1）へ
###### void loop()
（1）
今の時刻を取得する
21：57ならhourに21,minuteに57みたく抜き出して考える。
この抜き出したものをdispTokei()関数に送る。
この関数はHIGHなら時計を明るくする。
じゃあどうやってHIGHかLOWかを制御するのかというと、digitalTokei()で制御する。（2）へ飛ぶ

######void digitalTokei()
（2）ここではさっき抜き出した、21：57ならhourに21,minuteに57この数字一つ一つに
######void dispTokei()
数字を書き込む
######void tbset()

時刻の取得
4＊4の配列を準備
取ってきた時刻から二進数に変換
HIGHの部分をLEDに出力

## ソースコード
```
#include <DS1302RTC.h>

#include <Time.h>
#include <TimeLib.h>


// Init the DS1302
// Set pins: CE, IO,CLK
// Set pins: RST,DAT,CLK
DS1302RTC RTC(14, 15, 16);

//時刻を取得するための変数
time_t tokei;

const int buttonPinH = 19; //時を進めるボタン
const int buttonPinM = 18; //分を進めるボタン
int buttonState = 0;

//LEDの表示状態
int tb46[4][6] = {{HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}, {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}, {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}, {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}};
//列のピン番号
int tb01[4] = {
11, 10, 9, 8
};
//行のピン番号
int tb02[6] = {
2, 3, 4, 5, 6, 7
};


//初期設定
void setup()
{
//ボタンを入力に設定　 //第2引数は3種。中でもINPUT_PULLUPを指定することで内部プルアップ抵抗を有効にするらしい
pinMode(buttonPinH, INPUT_PULLUP);
pinMode(buttonPinM, INPUT_PULLUP);
pinMode(buttonPinS, INPUT_PULLUP);

//LEDピンを出力に設定
/*
pin.Mode(..,OUTPUT)は設定されたピンはρインピーダンス状態になる。
簡単に言うと準備OK！！みたいな。それを4＊4のポイント全てで起動させる
*/
for (int i = 0; i <= 3; i++)
{
pinMode(tb01[i], OUTPUT);
}
for (int i = 0; i <= 5; i++)
{
pinMode(tb02[i], OUTPUT);
}

// setTime(16,30,0,2,17,2018);
Serial.begin(9600);
/*
RTC.haltRTC()が意味分からないけど、haltが「停止」って意味だから、時刻が停止してたらtrue,動いてたらfalse返す的なメソッドだと思う
*/
if (RTC.haltRTC())
Serial.print("Clock stopped!");
else
Serial.print("Clock working.");
/*
書き込む権限があるかどうか的な
*/
if (RTC.writeEN())
Serial.print("Write allowed.");
else
Serial.print("Write protected.");

/*
 RTC.getでRTCから現在時刻をArduinoが読み取る
setSyncProviderに入れることでRTCの時刻とArduinoの時刻を合わせてる
 */
setSyncProvider(RTC.get);
if (timeStatus() == timeSet)//RTCの時刻とArduinoの時刻が等しいならOK。そうじゃないならsetする
Serial.print(" Ok!");
else
Serial.print(" FAIL!");
RTC.set(now());
}
//初期設定終了


void loop()
{
while ( tokei == now() ) {
dispTokei(); //LED表示
}

/*
 digitalReadは、指定したピンの値を読み取る。返り値はHIGHまたはLOW。
*/
buttonState = digitalRead(buttonPinH); //時ボタン
/*なんでLOWの時に時刻をセットするんだ？？LOWは0Vで電流が流れていないから適切な時刻を取得できているわけではないからかな？*/
if (buttonState == LOW) {
 /* rtc.setTime(byte hours, byte minutes, byte seconds)時刻をセット*/
setTime(hour() + 1, minute() , second(), day(), month(), year());
RTC.set(now());
}
buttonState = digitalRead(buttonPinM); //分ボタン
if (buttonState == LOW) {
setTime(hour(), minute() + 1, second(), day(), month(), year());
RTC.set(now());
}
buttonState = digitalRead(buttonPinS); //秒ボタン
if (buttonState == LOW) {
setTime(hour(), minute() , 0, day(), month(), year());
RTC.set(now());
}
/*今の時間をセット*/
tokei = now();
digitalTokei(); //LEDセット
}

void digitalTokei() {
String thisString1;
String thisString2;
int a;

a = minute(); //分
thisString1 = String(a).charAt(0);
thisString2 = String(a).charAt(1);
/*
必ずしも57分とか14分とは限らない。4分の時もある。その時は以下のように処理する
*/
if (thisString2 == "") {
thisString2 = thisString1;
thisString1 = "0";
}
tbset(3, thisString2);
tbset(2, thisString1);

a = hour(); //時
thisString1 = String(a).charAt(0);
thisString2 = String(a).charAt(1);
if (thisString2 == "") {
thisString2 = thisString1;
thisString1 = "0";
}
tbset(1, thisString2);
tbset(0, thisString1);

}

/*
 テーブルの内容を見てLED表示
 具体的にはどこが光っていてどこが消えているのかを確認する
 */
void dispTokei() {
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 5; j++)
{
  /*
   digitalWrite(13, HIGH);のようピン番号とHIGH(5V)かLOW(0V)かを渡す
   4*4の配列の中で光るべき場所にHIGHを入れている。初期設定の時点で列と行に分けているのでtb01とtb02は別々
  */
digitalWrite( tb01[i], tb46[i][j]);
digitalWrite( tb02[j], tb46[i][j]);
// delay(1);
/*なんでこれしてるんだろう？一旦全部LOWにしてLEDのライトを消すのかな？*/
digitalWrite( tb01[i], LOW);
digitalWrite( tb02[j], LOW);
}
}
}

//10進数を 2進数に変換しLEDにセット
//これをLEDにわたすことでHIGHの位置で光るようにする
void tbset(int tb46yoko, String thisString) {
if (thisString == "0") {
tb46[0][tb46yoko] = LOW;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "1") {
tb46[0][tb46yoko] = HIGH;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "2") {
tb46[0][tb46yoko] = LOW;
tb46[1][tb46yoko] = HIGH;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "3") {
tb46[0][tb46yoko] = HIGH;
tb46[1][tb46yoko] = HIGH;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "4") {
tb46[0][tb46yoko] = LOW;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = HIGH;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "5") {
tb46[0][tb46yoko] = HIGH;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = HIGH;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "6") {
tb46[0][tb46yoko] = LOW;
tb46[1][tb46yoko] = HIGH;
tb46[2][tb46yoko] = HIGH;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "7") {
tb46[0][tb46yoko] = HIGH;
tb46[1][tb46yoko] = HIGH;
tb46[2][tb46yoko] = HIGH;
tb46[3][tb46yoko] = LOW;
}
if (thisString == "8") {
tb46[0][tb46yoko] = LOW;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = HIGH;
}
if (thisString == "9") {
tb46[0][tb46yoko] = HIGH;
tb46[1][tb46yoko] = LOW;
tb46[2][tb46yoko] = LOW;
tb46[3][tb46yoko] = HIGH;
}

}

```


### 参考
https://minkara.carview.co.jp/userid/155344/blog/41147746/
https://blog.arduino.cc/2017/06/06/a-paris-inspired-arduino-powered-binary-clock/