RTCモジュールと電源リレーモジュールを使用して、特定の時間に接続している別の Arduino を起動してツイートをします。
今回は電源リレーにつながっている Arduino から21時56分に起動してツイートするようにしてみました。
接続方法
少しわかりにくいですが、左のメインの Arduino に RTC モジュールと電源リレーモジュールを付けて、電源モジュールの先にはツイート用の別の Arduino と電源供給用のモバイルバッテリーを付けています。
本当はディープスリープなどで実現したいのですが、なんとなく家に電源リレーがあったのでやってみました。
使用機材
あとで書きます。
ソースコードはこちら
PowerRelay.ino
// ========================================================================
// set pin value
// ========================================================================
# define CLK_PIN 8 //(基板上CLK⇒6番ピン)
# define DAT_PIN 7 //(基板上DAT⇒7番ピン)
# define RST_PIN 6 //(基板上RST⇒8番ピン)
# define RELAY_PIN 12 //(電源リレーIN1⇒12番ピン)
// ========================================================================
// set power on time
// ========================================================================
# define POWER_START_HOUR 21 // 電源オンの時間
# define POWER_START_MINUTES 56 // 電源オンの分
// setting date format
struct DateTime{
boolean CH; //1でClockHalt(停止)だが、0を入れてこの機能使わない前提
boolean Mode12; //1で12時間表示だが、0を入れて24時間表示で使う前提
boolean WP; //1でWriteProtectだが0を入れてこの機能使わない前提
int Date;
int Month;
int Week;
int Year;
int Seconds;
int Minutes;
int Hour;
};
// ========================================================================
// init
// ========================================================================
void setup() {
//シリアル通信準備
Serial.begin( 9600 );
Serial.print( "start" );
// setting power relay pin mode
pinMode( RELAY_PIN , OUTPUT );
digitalWrite( RELAY_PIN , LOW ); // power off
// setting clock pin mode
pinMode( RST_PIN, OUTPUT );
pinMode( CLK_PIN, OUTPUT );
// setting initial time
//setYear(2021);setMonth(2);setDate(18);setHour(21);setMinutes(37);setSeconds(13);
//setWeek(4); // 1:月 2:火 3:水 4:木 5:金 6:土 7:日
};
// ========================================================================
//
// ========================================================================
void loop() {
Serial.print( "looping" );
byte RTC_clock_image[8];
DateTime myDateTime;
read_rtc_byte(RTC_clock_image);
extract_datetime(RTC_clock_image,myDateTime);
//yyyy-mm-dd hh:ss:ii week
Serial.print(myDateTime.Year); Serial.print("-");
Serial.print(myDateTime.Month); Serial.print("-");
Serial.print(myDateTime.Date); Serial.print(" ");
Serial.print(myDateTime.Hour); Serial.print(":");
Serial.print(myDateTime.Minutes); Serial.print(":");
Serial.print(myDateTime.Seconds); Serial.print("(");
Serial.print(myDateTime.Week); Serial.println(")");
// power relay start
if( myDateTime.Hour == POWER_START_HOUR && myDateTime.Minutes == POWER_START_MINUTES ){
digitalWrite( RELAY_PIN , HIGH ); // power on
Serial.println("start power on");
}
else{
Serial.println("start power off");
digitalWrite( RELAY_PIN , LOW ); // power off
}
delay(1000);
}
// ========================================================================
// set read date functions
// ========================================================================
//RTCからクロックデータをまるごと読みだし、
byte read_rtc_byte(byte image[]){
pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeをまず送信用で準備
digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
write_1byte(0xbf);//バーストモードのコマンド0xbf送信
//読み出しに移るのでDAT_PINのピンモード切り替える。CLK_PIN上げのまま
pinMode(DAT_PIN, INPUT);
//8byte分続けて読みbyte配列のimageに入れる
for (int i=0; i<=7; i++){
read_1byte(image[i]);
}
//RST_PIN下げる
digitalWrite(RST_PIN, LOW); wait();
}
void write_1byte(byte data){
//コマンド等送信 1ビットずつ繰り返し8ビット(1バイト)分送る
for (int i=0; i <= 7; i++){
digitalWrite(CLK_PIN, LOW);wait(); //LOW確認
digitalWrite( DAT_PIN, bitRead(data, i));wait();
digitalWrite(CLK_PIN, HIGH);wait(); //クロック(LOWからHIGH)で書き込む
//クロック上げたままで関数を抜ける。
}
}
void read_1byte(byte &data){
//データ受信 1ビットずつ繰り返し8ビット(1バイト)分読みだす
data = 0;
for (int i=0; i<=7; i++){
digitalWrite(CLK_PIN, HIGH);wait();//clock上げ。(上げたまま引き継いだ時はそのまま)
digitalWrite(CLK_PIN, LOW);wait();//clock下げて、
bitWrite( data,i, digitalRead(DAT_PIN));//読む
//クロック下げた状態で関数を抜ける
}
}
void setImage(byte command, byte image){ //コマンド、書き込みデータ
pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeを送信用で準備
digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
write_1byte(command);
write_1byte(image);
digitalWrite(CLK_PIN, LOW);wait();//clock下げて、
digitalWrite(RST_PIN, LOW);wait();//最後はRST_PIN下げる
}
void getImage(byte command, byte &image){
pinMode(DAT_PIN, OUTPUT);//DAT_PINのpinmodeを送信用で準備
digitalWrite(RST_PIN, LOW);wait();//最初はRST_PIN下げた状態
digitalWrite(RST_PIN, HIGH);wait();//開始(RST_PIN 上げ)
write_1byte(command);
pinMode(DAT_PIN, INPUT);//DAT_PINのpinmodeを受信用に切り替え
read_1byte(image);
digitalWrite(RST_PIN, LOW);wait();//最後はRST_PIN下げる
}
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.Week =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;
}
// ========================================================================
// set yyyy m d h s i
// ========================================================================
void setYear(int year){ // (ex. 2020
setImage(0x8C, (((year - 2000)/10)<<4)+(year % 10));
}
void setWeek(byte Week){
setImage(0x8A, Week); // 1:月 2:火 3:水 4:木 5:金 6:土 7:日
}
void setMonth(int month){ // 1-12
setImage(0x88,((month/10)<<4)+(month % 10));
}
void setDate(int date){
setImage(0x86,((date/10)<<4)+(date % 10));
}
void setHour(int hour){//0-23
setImage(0x84,((hour/10)<<4)+(hour % 10));
}
void setMinutes(int minutes){
setImage(0x82,((minutes/10)<<4)+(minutes % 10));
}
void setSeconds(int seconds){
setImage(0x80,((seconds/10)<<4)+(seconds % 10));
}
~~~~
#### 参考リンク
- [リレー制御モジュールをArduinoから使う | Program Resource ](https://programresource.net/2015/05/02/2569.html)
- [RTCモジュール(DS1302)を試す(2)|LiuK|note ](https://note.com/liuk_net/n/na52a558f9847)