M5Stack Core2 UIFlowでアナログ時計の作り方

プログラミング

前回記事にてRTCのプログラムを組んでみました。

今回はこのRTCを使ってアナログ時計の作り方を紹介します。

完成形を確認

今回作成するアナログ時計はそこまで複雑ではないのですがステップがそれなりになるためまずは完成形を見てイメージをつかんでから進める方が理解も深まると思います。

動画のように上部に日付、下部に時間(デジタル)、中央にアナログ時計という構成で作っていきます。

秒針は黒、分針は青、時針は赤で徐々に短く、太くなるようにします。

必要な要素を生成

今回作るアナログ時計に必要な要素は以下の5つです。

  • 日付のLabel
  • 時間(デジタル)のLabel
  • 時針のLine
  • 分針のLine
  • 秒針のLine

まずはこれらを生成していきます。

UIFlowの左からLabelを2つとLineを3つ、画面へドラッグアンドドロップで配置します。

Labelはほぼ表示する場所へ配置し、Lineは後でしっかり設定するため適当に配置します。

パラメータを設定

各要素のパラメータを以下のように設定します。

秒針用Line

最初に生成したLine(line1)を秒針用とし、以下の設定を行います。

  • Name:lineS
  • X1:160
  • Y1:120
  • X2:160
  • Y2:20
  • Line Width:1
  • Color:黒
  • Layer:(規定のまま)

分針用Line

2つ目に生成したLine(line2)を分針用とし、以下の設定を行います。

  • Name:lineM
  • X1:160
  • Y1:120
  • X2:160
  • Y2:40
  • Line Width:3
  • Color:青
  • Layer:(規定のまま)

時針用Line

最後に生成したLine(line3)を時針用とし、以下の設定を行います。

  • Name:lineH
  • X1:160
  • Y1:120
  • X2:160
  • Y2:60
  • Line Width:5
  • Color:赤
  • Layer:(規定のまま)

配置の状況を確認

パラメータの設定が完了したら以下のようになっていると思います。(日付のLabelの大きさは変えてありますが任意で変更などしてください)

秒針、分針、時針のX1、Y1はLineの始点なので画面の中心となる(160, 120)で設定しています。

それぞれY2が異なる理由は長さをそれぞれ100、80、60としているためです。

プログラムを組む

それでは順番にプログラムを組んでいきましょう。

変数を準備

色々な値を格納するために以下16個の変数を準備します。

  • 中心X
  • 中心Y
  • 年月日
  • 時分秒
  • 角度H
  • 角度M
  • 角度S
  • 針先HX
  • 針先HY
  • 針先MX
  • 針先MY
  • 針先SX
  • 針先SY
  • 長さH
  • 長さM
  • 長さS

中心X、中心Y

画面中心の座標を格納する変数で針の始点座標に定数として使います。

長さH、長さM、長さS

時針、分針、秒針の長さを格納する変数で針の終点座標の計算に定数として使います。

年月日、時分秒

年月日、時分秒のLabelに出力する文字列を格納する変数です。

角度H、角度M、角度S

時針、分針、秒針の角度を格納する変数です。

現在時刻から各針の角度に変換した結果を格納します。

針先HX、針先HY、針先MX、針先MY、針先SX、針先SY

時針、分針、秒針用Lineの終点座標を格納する変数です。

中心座標と各針の長さ、各針の角度から計算した座標値を格納します。

初期設定として定数を設定

定数用の変数に値を設定します。

  • 中心X:160
  • 中心Y:120
  • 長さH:60
  • 長さM:80
  • 長さS:100

年月日と時分秒を表示する

アナログ時計部分はとりあえず置いておいて、まずは年月日と時分秒を表示するためのプログラムを組みます。

現在日時の情報を取得するために[RTC]の「Set time by NTP host [cn.pool.ntp.org] timezone [9]」を配置します。(日本のタイムゾーンが「9」なので変更しています)

現在日時は刻々と変わるものなので「ずっと」ブロックを配置し、変数「年月日」「時分秒」へ文字列を組み立てて代入します。

年月日、時分秒のそれぞれのLabelへ表示するブロックを挿入して完成です。

各針の角度を計算する

RTCから現在の時分秒を取得できるようになったので現在時刻に合った角度を計算します。

考え方は一番上を0度(360度)として、各針が一回りするのにかかる時間で割る事で表現する最小角度を求め、現在時刻で掛け合わせて角度を計算します。

秒針であれば60秒で一回りするため、360度に60秒で割った6度が1秒で変化する角度になり現在時刻が10秒であれば一番上から60度回ったところが秒針の居るべき角度です。

分針も同様に考えられるのですが[RTC]の「Get minute」で取得できる値は1分毎にしか変化しないため、1分経過とともにいきなり6度も針の角度が変わってしまいます。

この変化を小さくするために現在時刻の秒も足しこんで3,600秒で1回転する事と考え、0.1度が1秒で変化する角度になり現在時刻が30分30秒であれば一番上から183度回ったところが分針の居るべき角度です。

時針も分針と同様の考えで720分で1回転する事と考え、0.5度が1分で変化する角度になり現在時刻が9時20分であれば一番上から280度回ったところが時針の居るべき角度です。

各針の終点座標を計算する

各針の角度が計算出来ているのでLineの始点と終点の座標のうち終点座標を計算する必要があります。

角度から座標の計算が必要なので三角関数を使います。

各針の長さを使い、X座標はsin、Y座標はcosを使って計算します。

計算結果は小数になる可能性があるので各座標の変数へ代入する時には整数化しています。(座標に小数は使えず指定するとエラーとなるため)

各針のLineの始点座標、終点座標を設定する

各針の終点座標が計算出来たので後はLineを設定するだけです。

プログラム完成

これで全て完了です。

作ったプログラムは以下からダウンロードできます。

まとめ

プログラムでアナログ時計を作った事がある人であれば一般的な方法で作りましたが初めて作る人には途中の計算で分からない部分があったかもしれません。

アナログ時計は現在時刻から角度を求めるところと角度から実際の座標に変換するところが肝になってきます。

これらを理解出来れば図形を扱うプログラムも簡単になると思います。

コメント

タイトルとURLをコピーしました