Arduino UNO R4 WiFiで現在時刻をNTPサーバーから取得してLEDマトリクスにスクロール表示させる方法
こんにちは、せでぃあ(@cediablog)です。
Arduino UNO R4 MinimaやArduino UNO R4 WIFIは、本体マイコンにRTC(リアルタイムクロック)機能という時計機能を有しています。
そのため、一度最新時刻を書き込んでしまえば、あとは内部時計で時を刻んでくれます。
今回はArduino UNO R4 WIFIをネットワークに接続して、NTPサーバーから現在時刻・日時・曜日情報を取得してLEDマトリクスにスクロール表示させるプログラムを紹介します。
本体一つあれば動作が可能なテーマになっています!
- WiFiネットワークへの接続・切断方法
- NTPサーバーから現在時刻を取得する方法
- 取得した時刻情報をRTCに書き込む方法
- RTC情報を読み出す方法
- LEDマトリクスにテキストスクロールさせる方法
WiFi接続の未経験者は、こちらの記事を読んでいただけますと理解が進むと思います。
RTCから現在時刻を取り出す方法は、こちらの記事にて詳しく説明しています。
せでぃあはこんな人物です
✅プライム企業に勤める電気・機械設計エンジニア
✅親子の絆を深めるため、夏休みに子供と一緒に電子工作を製作
✅Arduinoプログラミングを用いて作ったプログラミング電子工作「信GO機」が市の発明くふう展で「優秀賞」を受賞
✅本ブログにてArduinoスクラッチプログラミングLESSON記事投稿中
✅YouTubeチャンネル「せでぃあブログちゃんねる」運営中
Arduino UNO R4 WiFiはここで買えます
NTPサーバーとは
NTPサーバーとは、インターネットなどのネットワーク上で正確な時刻情報を配信するサーバーのことです。
Arduinoの「NTPClient関数」を使うことで、NTPサーバーと通信を行い現在時刻を取得できます。
NTPサーバーの一例
- ntp.nict.jp:独立行政法人情報通信研究機構 (NICT) が運営
- pool.ntp.org:NTP Pool Projectが運営
- time.google.com:Googleが運営
今回取り扱うプログラムでは、「nitp.nict.jp」に接続して現在時刻を取得することにしました。
年月日や曜日も取得することができます。
NTPサーバーから現在時刻を取得してLEDマトリクスに表示させる
今回作成するプログラム動作を説明します。
- プログラム動作を開始。
- WiFiネットワークに接続。
マトリクスLEDに接続中アニメーションを表示。 - 3秒後に接続状態を確認する。
接続状態に応じてマトリクスLEDにOK・NGを表示。 - NTPサーバーに接続して現在時刻を取得。
- 取得した時刻データをRCTに書き込む。
- LEDマトリクスにテキストスクロール表示。
プログラム転送後、または本体のリセットボタンを押すとプログラム動作を開始します。
WiFi接続状態に応じてマトリクスLEDに「OK」または「NG」を表示させます。
接続に成功したときは、OKが表示されます。
接続に失敗しているときは、NGの表示がされます。
NTPサーバーにアクセスして、現在時刻情報を取得します。
NTPサーバーから取得した時刻データをRTCに書き込みます。
RTCから年月日、曜日、時刻情報を取り出し、LEDマトリクスにテキストスクロールさせます。
プログラムデバッグ目的も兼ねて、STEPの進捗に応じてLEDマトリクスに「NTP」や「GET」などの表示をさせています。
Arduino UNO R4 WIFIはLEDマトリクスが本体に内蔵されていることが特徴で、本体のみで動作を楽しめるプログラムになっています。
動作確認が楽しくなるプログラム内容になっています。
ライブラリをインストールする
今回の動作プログラムを実行させるためにはライブラリをインストールする必要があります。
- NTPClientライブラリ
- ArduinoGraphicsライブラリ
これらのライブラリはArduinoIDEインストール時にインストールされないため、手動でライブラリを追加します。
Arduino IDEの最新版をインストールしたい方は、こちらの記事を参考にしていただけますと幸いです。
NTPClientライブラリのインストール
NTPClientライブラリは、UDP通信を使ってNTPサーバーから現在時刻を取得するライブラリです。
①ArduinoIDEを開いて、スケッチをクリックします。
②ライブラリをインクルード→ライブラリを管理をクリックします。
③ライブラリマネージャーの検索窓に「NTPClient」と入力してライブラリを検索し、インストールボタンを押してインストールを行います。
ArduinoGraphicsライブラリのインストール
ArduinoGraphicsライブラリは、LEDマトリクスに表示させるフォント作成ライブラリです。
NTPClientライブラリと同じ手順で進め、ライブラリマネージャーの検索窓に「ArduinoGraphics」と入力してライブラリをインストールします。
私はライブラリをインストール済であったため、上記表示になっています。
未インストール時はインストールボタンが表示されるので、そこからインストールできます。
これでライブラリのインストール作業は完了です。
LEDマトリクス表示パターンを作る
メインプログラムを作る前に、LEDマトリクス点灯パターンファイルを作成しておく必要があります。
今回作成するLEDマトリクス表示
- WiFi接続中アニメーション
- 接続「OK」表示
- 接続「NG」表示
- 現在時刻取得中表示「NTP」
- 現在時刻取得完了表示「GET」
これらの作り方を順番に説明していきます。
WiFi接続中アニメーションの作り方
LEDマトリクスエディタを使ったマトリクス表示作成方法を紹介します。
ブラウザ上でマトリクス表示を作成してプログラムコードを生成することができます。
- マトリクス作画エリア
- 表示パターンエリア
- コード生成ボタン
実際のLEDマトリクスと同じ「縦8×横12=96マス」表示になっています。
LEDマトリクスエディタの使い方はとても簡単です。
点灯させたいLEDマスをクリックして、黒塗り表示にするだけです。
画面左下のコピーボタンをクリックすると、同じ表示パターンがコピーされます。
このように同じパターンがコピーされるので、アニメーション表示を作成するときに便利な機能です。
表示パターン下の数字は、アニメーション表示するときの1コマ表示時間(msec)になります。
デフォルト値は、66msec/コマ≒15コマ/秒です。
1コマずつ表示時間を指定できるのは嬉しいですよね!
2コマ目の表示パターンを作ります。
3コマ目の表示パターンを作ります。
だんだんそれっぽくなってきましたね。
最後の4コマ目を作ります。
電波が飛んでいるイメージの絵になりましたね。
これでWiFi接続中アニメーションの作成は完了です。
アニメーション表示パターンの作成が完了したら、プログラムコードを生成します。
画面右上のコード生成ボタンをクリックして、任意のファイル名を指定してデータを生成します。
今回は、ファイル名を「connect_animation」と入力します。
生成したプログラムコードファイルは、ダウンロードフォルダに保存されています。
アニメーション表示コードファイルはスケッチフォルダに移動させて使うので、削除しないようにしてください。
単独表示パターンのコードを生成する
アニメーションではなく、単独表示パターンであってもLEDマトリクスエディタを使ってコード生成することで、32ビット整列のデータを確認することができます。
この表示データをプログラム内で指定することで、表示させたいパターン通りにLEDマトリクスを点灯させることができます。
LEDマトリクスエディタを使って、OK表示パターンを作ります。
パターンを作ったら画面右上のコードファイル生成ボタンを押して、ファイル生成します。
今回ファイル名を「ok」にしましたが、他ファイル名と重複しなければ何でも良いです。
生成したコードファイルは、ダウンロードフォルダに保存されています。
生成ファイルを右クリックして、プログラムから開くからメモ帳を使ってファイルを開きます。
すると、コードの中身をかくにんすることができます。
中かっこ内の4列のうち、上から1~3列目までがマトリクス表示コードです。
4列目はアニメーション表示時間のため、今回は使用しません。
残り3パターンの表示「NG」NTP」「GET」をマトリクスエディタで作成します。
作成したらOK表示と同様に、コードを生成してマトリクス表示コードを確認します。
確認したコードは、プログラム作成時に使用します。
これでプログラム作成前の準備は完了です。
プログラムの作り方
プログラムは以下に示す3つのプログラムで構成されます。
スケッチフォルダの構成
- メインプログラム
UNO_R4_WiFi_RTC_GetTime.ino - シークレットプログラム
arduino.secrets.h - アニメーション表示プログラム
connect_animation.h
まずはプログラムファイルから作っていきます。
Arduino IDEのインストール方法を紹介しています。
スケッチフォルダを作成する
まずはプログラムファイルを作って、スケッチフォルダを生成します。
Arduino IDEを開いて、ファイルを名前を付けて保存します。
プログラムは後ほど作りますので、まずは未作成状態のまま保存してください。
ファイル名は「UNO_R4_WiFi_RTC_GetTime」にしました。
シークレットプログラムを作る
今回はWiFi接続するために、プログラム内でSSIDとパスワードを入力する必要があります。
これらは「秘密情報」であるため、メインプログラムとは別のプログラムに記述しておき、メインプログラム内でシークレットプログラムを読み出す方法を使うことが有効です。
シークレットプログラムの作り方を解説します。
メインプログラム内で使用する変数「SECRET_SSID」と「SECRET_PASS」を、arduino_secrets.h内で定義します。
これでシークレットプログラムが完成しました。
メインプログラムからインクルード命令で読み出して使用します。
アニメーションファイルをスケッチフォルダに保存する
マトリクスエディタで作成したアニメーションプログラムを、プログラムスケッチフォルダ内に保存します。
シークレットプログラムと同様、メインプログラムからインクルード命令で読みだして使います。
アニメーションプログラムファイルを、メインプログラムファイルと同じスケッチフォルダに保存します。
同じフォルダに保存することで、スケッチのタブに自動的に組み込まれます。
スケッチファイル「UNO_R4_WiFi_RTC_GetTime.ino」をダブルクリックして開きます。
プログラムの上のタブに「connect_animation.h」が表示されていることを確認してください。
これでアニメーション表示プログラムのスケッチ組み込作業が完了しました。
メインプログラムを作る
メインプログラムを作成していきます。
/* 作品名:UNO_R4_WiFi_RTC_GetTime */
/* 作成者:せでぃあ https://cediablog.com */
/* NTPサーバーから現在時刻を取得してLEDマトリクスに表示させる */
// RTCライブラリをインクルードする
#include "RTC.h"
// WiFiS3ライブラリをインクルードする
#include "WiFiS3.h"
// WiFiUdpクラスをインクルードする
#include "WiFiUdp.h"
// NTPClientライブラリをインクルードする
#include "NTPClient.h"
// arduino_secretsをインクルードする
#include "arduino_secrets.h"
// ArduinoGraphicsライブラリをインクルードする
#include "ArduinoGraphics.h"
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
// connect_animationをインクルードする
#include "connect_animation.h"
// 現在時刻のオフセット(日本時間は標準時間+9時間)
#define timeZoneOffsetHours 9
// NTPサーバーのアドレス
#define ntpserver "ntp.nict.jp"
// ネットワークのSSIDとパスワードを定義する
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
// WiFiUDPオブジェクトを作成
WiFiUDP ntpUdp;
// NTPClientオブジェクトを作成
NTPClient timeClient(ntpUdp, ntpserver, timeZoneOffsetHours * 3600);
// マトリックスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
//日時を文字列として格納するための変数
char realtime[100];
// 接続成功時にLEDマトリクスに表示するマークを定義"OK"
const uint32_t connect_ok[] = {
0x31149285,
0x48588588,
0x54492311,
};
// 接続失敗時にLEDマトリクスに表示するマークを定義"NG"
const uint32_t connect_ng[] = {
0x85fc50a5,
0xa509579,
0x518d185f,
};
// NTP接続時にLEDマトリクスに表示するマークを定義"NTP"
const uint32_t connect_ntp[] = {
0x97792,
0x5d27b249,
0x24924000,
};
// NTPデータ取得後にLEDマトリクスに表示するマークを定義"GET"
const uint32_t get_ntp[] = {
0xf7784,
0x2872b729,
0x42f72000,
};
void setup() {
// シリアル通信を開始する
Serial.begin(9600);
// LEDマトリクス動作を開始する
matrix.begin();
// RTC時刻の初期化
RTC.begin();
// WiFiネットワークに接続されているかチェックする
if (WiFi.status() != WL_CONNECTED) {
// シリアルモニタに接続中コメントとSSIDを表示
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// ネットワークに接続する
WiFi.begin(ssid, pass);
// 接続中マトリックスアニメーション表示を読み出す
matrix.loadSequence(connect_animation);
// 接続中マトリックスアニメーション表示を有効
matrix.play(true);
// 3秒待つ
delay(3000);
// WiFiネットワークに接続できたときの処理
if (WiFi.status() == WL_CONNECTED) {
// 接続に成功したことをシリアルモニタに表示する
Serial.println("Connected to wifi");
// マトリックスパネルにOKマークを表示する
matrix.loadFrame(connect_ok);
// 1秒待つ
delay(1000);
// サーバーに接続中であることシリアルモニタに表示する
Serial.println("Starting connection to server...");
// NTPClientを開始
timeClient.begin();
// NTPClientを更新
timeClient.update();
// マトリックスパネルにNTPマークを表示する
matrix.loadFrame(connect_ntp);
// 1秒待つ
delay(1000);
// NTPサーバーから取得した日本のエポック秒(UNIX時間)をRTC時刻にセット
RTCTime timeToSet = RTCTime(timeClient.getEpochTime());
RTC.setTime(timeToSet);
// ネットワークから切断する
WiFi.disconnect();
// マトリックスパネルにGETマークを表示する
matrix.loadFrame(get_ntp);
// 1秒待つ
delay(1000);
} else {
// 接続に失敗したことをシリアルモニタに表示する
Serial.println("Disonnected to wifi");
// マトリックスパネルにNGマークを表示する
matrix.loadFrame(connect_ng);
}
}
}
void loop() {
// 時刻の格納先
RTCTime currentTime;
// RTCから時計データを取得
RTC.getTime(currentTime);
// 曜日文字列の格納先
char str_dayofweek[6] = "(XXX)";
// RTCから入手した曜日データにより表示内容を振り分ける
// 0:日曜日~6:土曜日
switch ((int)currentTime.getDayOfWeek()) {
case 0:
strcpy(str_dayofweek, "(SUN)");
break;
case 1:
strcpy(str_dayofweek, "(MON)");
break;
case 2:
strcpy(str_dayofweek, "(TUE)");
break;
case 3:
strcpy(str_dayofweek, "(WED)");
break;
case 4:
strcpy(str_dayofweek, "(THU)");
break;
case 5:
strcpy(str_dayofweek, "(FRI)");
break;
case 6:
strcpy(str_dayofweek, "(SAT)");
;
break;
}
// 年月日、曜日、時間データを文字列「realtime」に格納
sprintf(realtime, " %04d/%02d/%02d%s %02d:%02d:%02d ",
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
str_dayofweek,
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds());
// LEDマトリクスに表示する文字列をシリアルモニタに表示
Serial.print("JPN time = ");
Serial.println(realtime);
// LEDマトリクス表示を開始
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
// テキストスクロール速度を指定(msec)
matrix.textScrollSpeed(50);
// 使用するフォントを設定
matrix.textFont(Font_5x7);
// テキスト描画を開始
matrix.beginText(0, 1, 0xFFFFFF);
// テキスト表示を行う
matrix.print(realtime);
// 表示を終了し、スクロール表示方向を指定
matrix.endText(SCROLL_LEFT);
// LEDマトリクス表示を終了
matrix.endDraw();
}
上記のサンプルプログラムをコピーアンドペーストしてもOKです。
シークレットプログラム
#define SECRET_SSID "接続するネットワークSSID"
#define SECRET_PASS "接続するネットワークパスワード"
ネットワークのSSIDとパスワードは、使用するネットワーク環境に合わせて書き換えてください。
アニメーションプログラム
const uint32_t connect_animation[][4] = {
{
0x0,
0x0,
0x60060,
66
},
{
0x0,
0xf01,
0x8060060,
66
},
{
0x1f,
0x82044f21,
0x8060060,
66
},
{
0x3fc4029f,
0x92044f21,
0x8060060,
66
}
};
アニメーションプログラムは、LEDマトリクスエディタで生成したコードファイルをそのまま使います。
Arduino UNO R4 WIFI向けの初期設定やデータ転送方法などはこちらの記事を参考にしてください。
プログラム演算内容について
プログラムは大きく分けて下記の5つの動作を順番に行います。
- 必要なライブラリとプログラムをインクルードする。
- Arduino本体をWiFiネットワークに接続する。
- NTPサーバーに接続して、現在時刻情報を取得する。
- Arduino本体をWiFiネットワークから切断する。
- NTPサーバーから取得した現在時刻をRTCに書き込む。
- RTCデータをLEDマトリクスにスクロール表示させる。
①は初期化プロセスで行います。
②~④までの処理を、プログラム演算後に1度だけ処理される「setup関数」内で行います。
残りの⑤のみ、繰り返し演算処理される「loop関数」内で行います。
定期的に最新時刻をサーバーから取得することも可能ですが、今回は1度だけ最新時刻を取得して後はRTCの時刻情報を使用します。
必要なライブラリとプログラムをインクルードする
インクルード命令を使って、必要なライブラリと別タブで作ったプログラムを読み出します。
呼び出すライブラリ
// RTCライブラリをインクルードする
#include "RTC.h"
// WiFiS3ライブラリをインクルードする
#include "WiFiS3.h"
// WiFiUdpクラスをインクルードする
#include "WiFiUdp.h"
// NTPClientライブラリをインクルードする
#include "NTPClient.h"
// ArduinoGraphicsライブラリをインクルードする
#include "ArduinoGraphics.h"
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
呼び出すプログラム
// arduino_secretsをインクルードする
#include "arduino_secrets.h"
// connect_animationをインクルードする
#include "connect_animation.h"
WiFiネットワークへの接続と切断プログラム解説
Arduino UNO R4 WIFI本体をWiFiネットワークに接続・切断するプログラムの作り方を解説します。
WiFiS3ライブラリのクラス
Espressif(エスプレッシフ)社製のマイコン「ESP32-S3」を実装することで、Wi-FiやBluetoothに対応しています。
Arduino UNO R4 WIFIを使ってWiFi接続するための専用ライブラリ「WiFiS3.h」を使ってWiFi接続します。
Arduino UNO R4 WIFI専用で用意されているライブラリ「WiFiS3.h」には4つのクラスがあります。
WiFiS3ライブラリのクラス
- WiFiクラス
- WiFiUdpクラス
- WiFiClientクラス
- WiFiServerクラス
今回は「WiFiクラス」と「WiFiUdpクラス」を使用します。
WiFiクラスについて
WiFiクラスは、ArduinoボードのWi-Fi機能を制御するためのクラスです。
このクラスを使用すると、ArduinoをWi-Fiネットワークに接続させることができます。
WiFi接続の基本となるクラスです。
WiFiUdpクラスについて
WiFiUdpクラスは、UDP(User Datagram Protocol)プロトコルを使用してネットワーク上の他のデバイスと通信するためのクラスです。
このクラスを使用するとArduinoをUDPサーバーに接続したり、UDPクライアントとしてデータを送受信したりすることができます。
NTPサーバーから現在時刻を取得するために使用する「NTPClientクラス」がUDP通信を使ってデータを取得する機能であるため、「WiFiUdpクラス」を使用します。
WiFiクラスを使ってネットワーク接続・切断する
WiFiクラスを使ってネットワーク接続するプログラムの作り方を解説します。
// WiFiS3ライブラリをインクルードする
#include "WiFiS3.h"
WiFiS3ライブラリをインクルードして、プログラム内で使用可能にします。
// ネットワークのSSIDとパスワードを定義する
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
変数「ssid」「pass」を定義します。
文字列は、arduino_secrets.hで定義した文字列が代入されます。
// ネットワークに接続する
WiFi.begin(ssid, pass);
WPA/WPA2ネットワークに接続するために、begin()メソッドを使用します。
WiFiネットワークに接続するためのメソッド
WiFi.begin(“接続するSSID” , “接続するためのパスワード”)
// ネットワークから切断する
WiFi.disconnect();
ネットワークから切断するときは、disconnect()メソッドを使用します。
WiFiネットワークから切断するためのメソッド
WiFi.disconnect()
ネットワーク接続状態を確認する
WiFiネットワークへの接続状態を確認するために、statusメソッドを使用します。
接続状態を確認するためのメソッド
WiFi.status()
WiFi.status()の戻り値(抜粋)
- WL_CONNECTED:Wi-Fiネットワークに接続された状態
- WL_IDLE_STATUS:接続されていない状態
- WL_NO_SSID_AVAIL:利用可能なSSIDがない状態
- WL_SCAN_COMPLETED:Wi-Fiネットワークをスキャンした状態
- WL_CONNECT_FAILED:Wi-Fiネットワークへの接続に失敗した状態
- WL_CONNECTION_LOST:Wi-Fiネットワークとの接続が切断された状態
- WL_DISCONNECTED:Wi-Fiネットワークから切断された状態
WiFiネットワークに接続されているかどうかの確認には、戻り値「WL_CONNECTED」を使います。
「WL_CONNECTED」が戻ってこれば「接続できている」と判断します。
それ以外の戻り値は接続できていないときに戻ってくるものであるため、「WL_CONNECTED」が戻ってこない場合は「WiFiネットワークに接続できていない」と判断します。
// WiFiネットワークに接続されているかチェックする
if (WiFi.status() != WL_CONNECTED) {
上記プログラムでは、「!=」の条件になっているので、「WiFiネットワークに接続されていないとき」という条件になります。
NTPサーバーから現在時刻を取得する
NTPサーバーから、現在時刻情報を取得するプログラムの作り方を解説します。
// WiFiUdpクラスをインクルードする
#include "WiFiUdp.h"
// NTPClientライブラリをインクルードする
#include "NTPClient.h"
NTPサーバーからUDP通信を使って現在時刻を取得するライブラリ「NTPClient.h」をインクルードします。
さらにWiFiUdp.hライブラリをインクルードして、UDP通信を使用可能にします。
// WiFiUDPオブジェクトを作成
WiFiUDP ntpUdp;
NTPClient関数を使ってUDP通信するためのオブジェクトを作成します。
// 現在時刻のオフセット(日本時間は標準時間+9時間)
#define timeZoneOffsetHours 9
// NTPサーバーのアドレス
#define ntpserver "ntp.nict.jp"
// NTPClientオブジェクトを作成
NTPClient timeClient(ntpUdp, ntpserver, timeZoneOffsetHours * 3600);
NTPサーバーから現在時刻を取得するための、NTPClientオブジェクトを作成します。
NTPClientオブジェクト
NTPClient(UDPオブジェクト、UDPサーバーアドレス、時刻のオフセット(秒)、更新間隔(ミリ秒))
日本時間は標準時間+9時間のため、9時間×60分×60秒=オフセット時刻(秒)とします。
今回は演算時1度だけのデータ取得であるため、更新間隔は指定していません。
// NTPClientを開始
timeClient.begin();
// NTPClientを更新
timeClient.update();
// NTPサーバーから取得した日本のエポック秒(UNIX時間)をRTC時刻にセット
RTCTime timeToSet = RTCTime(timeClient.getEpochTime());
NTPサーバーから現在時刻を取得するため使用するメソッドを紹介します。
使用するメソッド
- NTPオフジェクト.begin():NTP Clientを開始
- NTPオフジェクト.update():NTP Clientを更新
- NTPオフジェクト.getEpochTime():エポック時間を取得
RTC(Arduino内部時計)に現在時刻を書き込むため、いったんエポック時間で値を取得します。
取得した現在時刻をRTCに書き込む
NTPサーバーから取得した現在時刻情報をArduino内部時計機能であるRTC(リアルタイムクロック)に書き込みます。
// RTCライブラリをインクルードする
#include "RTC.h"
RTCクラスを使用するためのライブラリ「RTC.h」をインクルードします。
// RTC時刻の初期化
RTC.begin();
RTCを初期化してRTCを使用可能な状態にします。
RTCを初期化するメソッド
RTC.begin()
// NTPサーバーから取得した日本のエポック秒(UNIX時間)をRTC時刻にセット
RTCTime timeToSet = RTCTime(timeClient.getEpochTime());
RTCの時間設定を行うためのオブジェクトを作成します。
// NTPサーバーから取得した日本のエポック秒(UNIX時間)をRTC時刻にセット
RTCTime timeToSet = RTCTime(timeClient.getEpochTime());
RTC.setTime(timeToSet);
RTCにサーバーから取得した現在時刻をRTCTimeオブジェクトにセットします。
RTCに時刻情報をセットするメソッド
RTC.setTime(時刻データ)
RTC情報を取り出してテキストデータを作る
RTC情報から日時、曜日データを取り出し、LEDマトリクスにテキストスクロール表示されるための文字列データを作ります。
//日時を文字列として格納するための変数
char realtime[100];
LEDマトリクスに文字列として現在時刻を表示させるための変数を作ります。
// 時刻の格納先
RTCTime currentTime;
RTC情報を格納するための、RTCTimeオブジェクトを作成します。
// RTCから時計データを取得
RTC.getTime(currentTime);
RTCから時刻情報を取り出してオブジェクトに書き込みます。
RTCから時刻情報を取り出すメソッド
RTC.getTime()
// 曜日文字列の格納先
char str_dayofweek[6] = "(XXX)";
// RTCから入手した曜日データにより表示内容を振り分ける
// 0:日曜日~6:土曜日
switch ((int)currentTime.getDayOfWeek()) {
case 0:
strcpy(str_dayofweek, "(SUN)");
break;
case 1:
strcpy(str_dayofweek, "(MON)");
break;
case 2:
strcpy(str_dayofweek, "(TUE)");
break;
case 3:
strcpy(str_dayofweek, "(WED)");
break;
case 4:
strcpy(str_dayofweek, "(THU)");
break;
case 5:
strcpy(str_dayofweek, "(FRI)");
break;
case 6:
strcpy(str_dayofweek, "(SAT)");
;
break;
}
曜日の格納先char型変数「str_dayofweek」を作ります。
RTCから曜日データを取り出します。
曜日情報を取り出すメソッド
RTCTimeオブジェクト.getDayOfWeek()
RTCから曜日データを取得すると数値データで返ってきます。
数値データに応じて、表示させる曜日文字列を設定します。
曜日データの対照表
- 0:日曜日
- 1:月曜日
- 2:火曜日
- 3:水曜日
- 4:木曜日
- 5:金曜日
- 6:土曜日
LEDマトリクスに表示させる文字列は「char型」のため、string型をchar型に変換させます。
string型をchar型に変換するためには、strcpy関数を使います。
strcpy関数
strcpy(格納先char型変数名, 変換前のstring型文字列)
// 年月日、曜日、時間データを文字列「realtime」に格納
sprintf(realtime, " %04d/%02d/%02d%s %02d:%02d:%02d ",
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
str_dayofweek,
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds());
RTCから年月日と時間データを取得して、STEP4で作成した曜日文字列を含めて1つのテキストデータを作ります。
LEDマトリクス表示させるテキストデータ「realtime」を作成します。
このテキストデータを生成するには、sprintf関数を使うと便利です。
sprintf関数
sprintf(char文字列、書式、可変数の引数)
書式の部分はスペースを含めてテキストデータ化されます。
正常にテキストスクロール表示させるには、文字列前後にスペースを設けておきます。
書式
- %d:符号付10進数
- %s:文字列
RTCから読み出す情報
- currentTime.getYear():年
- Month2int(currentTime.getMonth()):月
- currentTime.getDayOfMonth():日
- currentTime.getHour():時間
- currentTime.getMinutes():分
- currentTime.getSeconds()):秒
マトリクスLED点灯動作のプログラム解説
Arduino UNO R4 WIFIには、本体に12×8=96個のマトリクスLEDが実装されています。
マトリクスLEDの表示方法は主に下記3種類あります。
マトリクスLEDの表示方法
- 単独表示
- アニメーション表示
- テキストスクロール表示
今回作成するプログラムでは、①~③の全てを使います。
マトリクスLEDのアニメーション表示
WiFi接続中アニメーション表示プログラムの作り方を解説します。
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
// connect_animationをインクルードする
#include "connect_animation.h"
Arduino_LED_Matrixライブラリをインクルードして、プログラム内で使用可能にします。
またWiFi接続中アニメーション表示用プログラムもインクルードします。
// マトリクスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
マトリクスパネルを点灯させるためのオブジェクトを作成します。
// 接続中マトリクスアニメーション表示を読み出す
matrix.loadSequence(connect_animation);
// 接続中マトリクスアニメーション表示を有効
matrix.play(true);
LEDマトリクスアニメーション表示データを格納するために、loadSequence()メソッドを使用します。
格納したアニメーションを表示させるために、play()メソッドを使用します。
マトリクスアニメーション表示させるためのメソッド
matrix.loadSequence(アニメーション表示データ)
matrix.play(true)
※True:無限ループ表示 False(デフォルト):1度だけ表示
マトリクスLEDの単独表示
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
Arduino_LED_Matrixライブラリをインクルードして、プログラム内で使用可能にします。
// マトリクスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
マトリクスパネルを点灯させるためのオブジェクトを作成します。
// 接続成功時にLEDマトリクスに表示するマークを定義"OK"
const uint32_t connect_ok[] = {
0x31149285,
0x48588588,
0x54492311,
};
// 接続失敗時にLEDマトリクスに表示するマークを定義"NG"
const uint32_t connect_ng[] = {
0x85fc50a5,
0xa509579,
0x518d185f,
};
// NTP接続時にLEDマトリクスに表示するマークを定義"NTP"
const uint32_t connect_ntp[] = {
0x97792,
0x5d27b249,
0x24924000,
};
// NTPデータ取得後にLEDマトリクスに表示するマークを定義"GET"
const uint32_t get_ntp[] = {
0xf7784,
0x2872b729,
0x42f72000,
};
接続成功、失敗時に表示させるパターンを定義します。
ここであらかじめ準備しておいた、それぞれのパターン表示データを使います。
// マトリクスパネルにOKマークを表示する
matrix.loadFrame(connect_ok);
// マトリクスパネルにNGマークを表示する
matrix.loadFrame(connect_ng);
// マトリックスパネルにNTPマークを表示する
matrix.loadFrame(connect_ntp);
// マトリックスパネルにGETマークを表示する
matrix.loadFrame(get_ntp);
シーケンスにない単独パターンを表示させるために、loadFrame()メソッドを使用します。
単独パターン表示するためのメソッド
matrix.loadFrame(単独パターン表示データ)
テキストスクロール表示
日時データをテキストスクロールさせます。
「YYYY/MM/DD(曜日) HH:MM:SS」のテキストが右から左に流れます。
// ArduinoGraphicsライブラリをインクルードする
#include "ArduinoGraphics.h"
// Arduino_LED_Matrixライブラリをインクルードする
#include "Arduino_LED_Matrix.h"
ArduinoGraphicsライブラリをインクルードして、文字フォントを使用可能にします。
さらにArduino_LED_Matrixライブラリをインクルードして、プログラム内で使用可能にします。
// マトリクスパネルのオブジェクトを作成する
ArduinoLEDMatrix matrix;
マトリクスパネルを点灯させるためのオブジェクトを作成します。
// LEDマトリクス表示を開始
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
// テキストスクロール速度を指定(msec)
matrix.textScrollSpeed(50);
// 使用するフォントを設定
matrix.textFont(Font_5x7);
// テキスト描画を開始
matrix.beginText(0, 1, 0xFFFFFF);
// テキスト表示を行う
matrix.print(realtime);
// 表示を終了し、スクロール表示方向を指定
matrix.endText(SCROLL_LEFT);
// LEDマトリクス表示を終了
matrix.endDraw();
テキストスクロール表示させます。
表示させる文字列には「realtime」を指定します。
テキストスクロール表示させるためのメソッド
matrix.beginDraw():表示動作を開始
matrix.endDraw():表示動作を終了
matrix.print(文字列データ):テキストデータを表示
matrix.endText(SCROLL_LEFT):スクロール表示を指定
※SCROLL_LEFT:右→左 SCROLL_RIGHT:左→右
プログラム内のコメントにメソッドの機能を説明しています。
マトリクスLEDのサンプルスケッチについて紹介しています。
まとめ
Arduino UNO R4 WIFIは、本体さえあればネットワーク接続から現在時刻を取得して、その結果をLEDマトリクスに表示できてしまう多機能マイコンです。
正直コスパ最強じゃないかと思います。
今回は1度だけNTPサーバーから現在時刻を取得して、あとはRTCで管理している時間を使ってLEDマトリクス表示させていますが、定期的にNTPサーバーから現在時刻を取得してそのままLEDマトリクスに表示させることもできます。
今回のプログラムをアレンジして、プログラムに対して動作がどう変わるのか試してみると面白いと思います。
Arduino UNO R4 WiFiで遊んでみたい!と思った方は下記サイトで購入できます。
Arduino UNO R4 WIFIが買える国内サイト
通信ケーブルは別売りですので、併せて購入検討しておくと送料が無料にできてお得です。
最後まで読んでいただき、ありがとうございました。
Arduino UNO R4シリーズはビジュアルプログラミングには対応していません。
Arduino UNO R3はビジュアルプログラミングにも対応していますので、小学生にはこちらがおすすめです。
ELEGOOのArduino互換キットは、コスパに優れた初心者向けキットです!
コメント
コメント一覧 (6件)
どうしても、書き込みできない。「Arduino UNO R4 WiFiで現在時刻をNTPサーバーから取得してLEDマトリクスにスクロール表示させる方法」のシクレットファイルを読み込む
部分と思われますが、エラー発生。[Compilation error: expected ‘}’ before ‘char]
ここまでは、{}の部分がないように思います。わからない??
nobioさん、コメントありがとうございます。
先ほどブログ記載のプログラムをコピペして検証しましたが、問題なく動作できました。
お手数をおかけして恐縮ですが、メインプログラムやアニメーションプログラムで{}の数があっているか確認いただけますと幸いです。
「コンパイルエラー: ‘char’ の前に ‘}’ が必要です」というエラーが出ている模様ですが、char ssid[]とshar pass[]は{}がない宣言箇所で記述されるプログラムですので、
arduino_secrets.h内の記述や、プログラム冒頭に「{」が記述されていないかご確認いただきたく存じます。
どうぞよろしくお願いいたします。
こんにちは。
ご説明ありがとうございました。
とても役に立ちました。
さて、本ソフトにて半日置いておくと、時間がずれて
しまっていますので、定期的にNTPへ読み込みするソフトを
ご教授頂けないでしょうか。
よろしくお願いいたします。
電気屋さん、コメントありがとうございます。
おっしゃる通りArduinoのRTC機能で時刻を管理すると徐々に標準時間とのずれが生じます。
その対策については、nobioさんのコメントの通り「定期的にNTPサーバー経由で現在時刻を取得する」方法になります。
<対策方法>
・ネットワークに接続してNTPサーバーから現在時刻を取得してRTCに書き込むまでのプログラムをloop関数内に移動する。
・NTPClient(UDPオブジェクト、UDPサーバーアドレス、時刻のオフセット(秒)、更新間隔(ミリ秒))の更新間隔(ミリ秒)も設定する。
※サンプルプログラムでは更新間隔を省略していますが、定期的に現在時刻を取得する場合は更新間隔の指定も必要です。
まずは電気屋さんにて対策プログラムにチャレンジしていただけますと幸いです。
どうぞよろしくお願いいたします。
Wifiがずっと接続できなくていろいろ調べていたら5GHz帯は受け付けないのですね、初心者なもので簡単なところで躓いてしまいました;;
sakoさん、コメントありがとうございます。
おっしゃる通り、5GHz帯は対応しておらず、2.4GHz帯の対応になります。
<参考情報>
Wi-Fi:802.11 b/g/n対応、最高150 Mbps、2.4 GHz帯使用
ブログ記事内にもその旨注意事項として記載させていただきます。
初心者の方が誰でも簡単にプログラムに触れられるサイトを目指してまいります。
今後ともよろしくお願いいたします。