ESP32をいじってます。MAX7219のドライブの8桁7セグLEDを時計風にしてみました。マトリックスのLED
ではNETより時刻を取得して表示していましたが,今回は,DS1307のRTCのモジュールを使ってみました。
このモジュールについては,諸兄が詳しくHPに掲載していますので,そちらが参考になりますので,覚え
書きに記録します。使うにあたって,諸兄のHPを参考に,基板上のダイオードと抵抗をはずしました。
このモジュールは,バックアップ用に,充電式のボタン電池を使う仕様になっているので,非充電用の
ボタン電池を使うと不具合が起こるようなので,通常のボタン電池で,使えるようにしました。また,
このモジュールをESP32に使うのに〇ZON購入のレベルシフターを使いました。
SWITCHSIENCEで以前に購入したものは保持していたのですが,1つしかなかったので,購入しましたが,
6個中2個が不良でした。安いので,こんなもんでしょうかね。RTCのモジュールは,3.3Vでも動き
ましたが,シフターをはさみました。
動画のような表示ですが,シリアルコンソールから,’y’の入力で,西暦と月を,’m’の入力で,月と
日にちと曜日を表示するようにしました。もっとも,曜日は,数字のままで,今日は,日曜日なので,
0の表示です。
RTCもモジュールは,はじめに初期設定の時刻を書き込みますが,ネットより時刻を取得して,それを
書き込むようにしてあります。下記のようなスケッチですが,使ってない関数もあります。
#include <SPI.h>
#include <Wire.h>
#include <time.h>
#include <WiFi.h>
//時刻設定
#define JST 3600* 9
#define RTC_address 0x68
//DS1307設定
//const char *week[] = {"日","月","火","水","木","金","土"};
const char *week[] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
uint8_t REG_table[8];
// MAX7219 Command address
#define MAX7219_TEST 0x0f
#define MAX7219_BRIGHTNESS 0x0a
#define MAX7219_SCAN_LIMIT 0x0b
#define MAX7219_DECODE_MODE 0x09
#define MAX7219_SHUTDOWN 0x0C
//SPI設定
#define CS_PIN 5//CLK 18 DIN 23
#define LED_CLK 18
#define LED_DIN 23
//Wifys接続設定
const char* ssid = "***************";
const char* password = "**************";
//const char* ssid = "*****************";
//const char* password = "**************";
struct tm timeInfo;//時刻を格納するオブジェクト
char s[30];//時刻文字格納用
/***********************************************************
*SPIデータ送信--SPIライブラリー使用
*
************************************************************/
void maxTransfer(uint8_t address, uint8_t value) {
digitalWrite(CS_PIN, LOW); // Start transfer.
SPI.transfer(address); // Send address.
SPI.transfer(value); // Send the value.
//digitalWrite(CS_PIN, HIGH); // Finish transfer.
}
/**********************************************************
*MAX7219初期設定
*
***********************************************************/
void MAX7219_INI(){
maxTransfer(MAX7219_DECODE_MODE, 0b11011011);// 3.4はデコードしない
digitalWrite(CS_PIN, HIGH);
maxTransfer(MAX7219_BRIGHTNESS, 0x01); // Use lowest intensity.
digitalWrite(CS_PIN, HIGH);
maxTransfer(MAX7219_SCAN_LIMIT, 0x07); // Display digits 01234567
digitalWrite(CS_PIN, HIGH);
maxTransfer(MAX7219_SHUTDOWN, 0x01); // Normal Operation
digitalWrite(CS_PIN, HIGH);
maxTransfer(MAX7219_TEST, 0x00); // Normal Operation
digitalWrite(CS_PIN, HIGH);
}
/******************************************************************
*今回使った書き込み関数
*
*******************************************************************/
void LED_OUT(uint8_t addr, uint8_t dat){
digitalWrite(CS_PIN, LOW);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, addr);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, dat);
digitalWrite(CS_PIN, HIGH);
}
/********************************************************************
*int ch_to_int(char,char)
*
*********************************************************************/
int ch_to_int(char a,char b){
int buff;
int c=a-'0';//charをintに変換
int d=b-'0';//charをintに変換
buff=(c<<4) | d;
return buff;
}
/********************************************************************
*7セグ初期化
*
*********************************************************************/
void sevn_seg_init(){
LED_OUT(0x9, 0b11011011); //7セグでデコードするビットに1を立てる:
LED_OUT(0xA, 5); //輝度を設定, 0-15:
LED_OUT(0xB, 7); //使用する桁数を指定, 桁数-1:
LED_OUT(0xC, 1); //特にいじる必要なし:
LED_OUT(0xF, 0); //同上:
}
/************************************************************************************************************************************
*Set up
*
**********************************************************************/
void setup() {
Wire.begin();
Serial.begin(115200);
pinMode(CS_PIN, OUTPUT);
pinMode(LED_CLK, OUTPUT);
pinMode(LED_DIN, OUTPUT);
digitalWrite(CS_PIN, HIGH);
digitalWrite(LED_CLK, LOW);
digitalWrite(LED_DIN, LOW);
//Wify接続
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.println();
Serial.printf("Connected, IP address: ");
Serial.println(WiFi.localIP());
//Netより時刻を取得
configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");
getLocalTime(&timeInfo);//tmオブジェクトのtimeInfoに現在時刻を入れ込む
sprintf(s, " %04d/%02d/%02d %02d:%02d:%02d:%02d",
timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday,
timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec,timeInfo.tm_wday);//人間が読める形式に変換
delay(800);
Serial.print(s[1]);//西暦
Serial.print(s[2]);
Serial.print(s[3]);
Serial.print(s[4]);
Serial.print("-");
Serial.print(s[6]);//月
Serial.print(s[7]);
Serial.print("-");
Serial.print(s[9]);//日
Serial.print(s[10]);
Serial.print("-");
Serial.print(s[12]);//時
Serial.print(s[13]);
Serial.print("-");
Serial.print(s[15]);//分
Serial.print(s[16]);
Serial.print("-");
Serial.print(s[18]);//秒
Serial.print(s[19]);
Serial.print(s[20]);
Serial.print(s[21]);
Serial.println(s[22]);
//Serial.println(s[23]);
//RTCに現在時刻データを書き込む
Wire.beginTransmission(RTC_address);
Wire.write(0x00);//Register 先頭アドレス
Wire.write(ch_to_int(s[18],s[19]));//second
Wire.write(ch_to_int(s[15],s[16]));//minute
Wire.write(ch_to_int(s[12],s[13]));//hour
Wire.write(s[22]-'0');//week
Wire.write(ch_to_int(s[9],s[10]));//day
Wire.write(ch_to_int(s[6],s[7]));//month
Wire.write(ch_to_int(s[3],s[4]));//year
Wire.endTransmission();
digitalWrite(CS_PIN, HIGH);
digitalWrite(LED_CLK, LOW);
digitalWrite(LED_DIN, LOW);
LED_OUT(0x9, 0b11011011); //7セグでデコードするビットに1を立てる:
LED_OUT(0xA, 5); //輝度を設定, 0-15:
LED_OUT(0xB, 7); //使用する桁数を指定, 桁数-1:
LED_OUT(0xC, 1); //特にいじる必要なし:
LED_OUT(0xF, 0);
//7セグ初期設定
//sevn_seg_init();
//7セグに表示
LED_OUT(0x3, 1); //3ケタ目'-'
LED_OUT(0x6, 1); //6ケタ目'-'
}
char h_on=1;
char y_on=0;
char m_on=0;
/*****************************************************************
*メインループ
*
******************************************************************
void loop() {
char inkey;
Wire.beginTransmission(RTC_address);
Wire.write(0x00);//Register 先頭アドレス
Wire.endTransmission();
//RTCデータの読み込み
Wire.requestFrom(RTC_address,7);
for(int i=0;i<=7;i++){
REG_table[i]=Wire.read();
}
if( Serial.available() > 0 ) {
inkey = Serial.read();
switch (inkey){
case 'h':h_on=1;
y_on=0;
m_on=0;
break;
case 'y':h_on=0;
y_on=1;
m_on=0;
break;
case 'm':h_on=0;
y_on=0;
m_on=1;
break;
}
}
if(h_on==1){//時分秒を表示
LED_OUT(0x9, 0b11011011);
LED_OUT(0x1, REG_table[0]); //秒を表示
LED_OUT(0x2, REG_table[0]>>4);//10秒を表示
LED_OUT(0x3, 1);
LED_OUT(0x4, REG_table[1]);//分を表示
LED_OUT(0x5, REG_table[1]>>4);//分を表示
LED_OUT(0x6, 1);
LED_OUT(0x7, REG_table[2]);//時を表示
LED_OUT(0x8, REG_table[2]>>4);//時を表示
}
if(y_on==1){//年号月の表示
LED_OUT(0x9, 0b11111111);
LED_OUT(0x8,2);
LED_OUT(0x7,0);
LED_OUT(0x6,REG_table[6]>>4);
LED_OUT(0x5,REG_table[6]);
LED_OUT(0x4,0xF);
LED_OUT(0x3,0xF);
LED_OUT(0x2,REG_table[5]>>4);
LED_OUT(0x1,REG_table[5]);
}
if(m_on==1){//月日曜日の表示
LED_OUT(0x9, 0b11111111);
LED_OUT(0x8,REG_table[5]>>4);//月
LED_OUT(0x7,REG_table[5]);
LED_OUT(0x6,0xF);
LED_OUT(0x5,REG_table[4]>>4);//日
LED_OUT(0x4,REG_table[4]);
LED_OUT(0x3,0xF);
LED_OUT(0x2,REG_table[3]);//曜日
LED_OUT(0x1,0xF);
}
}