フルカラーLEDで時計を作ってみました。
構成
部品
-
Adafruit I2C通信の8×8ミニLEDマトリックス基板(緑色)
時刻や日付などを表示
Arduino向けライブラリは以下の2点使用
https://github.com/adafruit/Adafruit_LED_Backpack
https://github.com/adafruit/Adafruit_LED_Backpack -
リアルタイムクロックモジュール(RTC) DS3231
正確に時間を計測してくれる。温度センサも内蔵
Arduino向けライブラリは以下
https://github.com/jarzebski/Arduino-DS3231 -
制御用マイコン Adafruit Pro Trinket – 3V 12MHz
-
Adafruit Pro Trinket バッテリーモジュール
Pro TrinketとLiPoバッテリー間に接続し、USB接続時は充電してくれる
動作
タクトスイッチを押すと8x8LEDマトリックスディスプレイに各種モードで表示します。
- 時刻表示
- 日付, 温度表示
- グラフィック表示
時刻が切り替わる際に干支の絵がピコピコ表示します。
1時 子
2時 牛
3時 寅
4時 卯
5時 辰
6時 巳
7時 午
8時 未
9時 申
10時 酉
11時 戌
12時 亥
Arduino IDE用コード
watch_men.ino
#include <Wire.h>
#include <DS3231.h> //https://github.com/jarzebski/Arduino-DS3231
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
int mode, mode_ori;
DS3231 clock;
RTCDateTime dt;
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16
int hr1, hr2, mg, sb;
int r[NUMPIXELS] = {0}, g[NUMPIXELS] = {0}, b[NUMPIXELS] = {0};
int demoState = 0;
unsigned long time = 0;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
static const uint8_t PROGMEM
//子
ne_bmp[] =
{ B01100110,
B10011001,
B10011001,
B01000010,
B10000001,
B00100100,
B10000001,
B01011010},
//丑
ushi_bmp[] =
{ B01100110,
B01100110,
B11111111,
B11110000,
B01010100,
B11110001,
B10000001,
B10100101},
//寅
tora_bmp[] =
{ B00011000,
B01011010,
B01111110,
B00011000,
B01011010,
B00011000,
B11000011,
B00011000},
//卯
u_bmp[] =
{ B01100110,
B10011001,
B10011001,
B10011001,
B10000001,
B00000000,
B00100100,
B00000000},
//辰
tatsu_bmp[] =
{ B10011001,
B10011001,
B00000000,
B10100101,
B10000001,
B01100110,
B10011001,
B10100101},
//巳
mi_bmp[] =
{ B01111111,
B01000000,
B00100010,
B10010000,
B01001000,
B00100100,
B01111000,
B01000000},
//午
uma_bmp[] =
{ B00111100,
B00011000,
B10100101,
B10000001,
B11000011,
B11000011,
B10000001,
B10100101},
//未
hitsu_bmp[] =
{ B11111111,
B11111111,
B10011001,
B00000000,
B00100100,
B10000001,
B11000011,
B11100111},
//申
saru_bmp[] =
{ B01111110,
B11011011,
B10000001,
B10100101,
B10000001,
B00000000,
B10011001,
B01100110},
//酉
tori_bmp[] =
{ B00000000,
B00000000,
B01000010,
B00011000,
B00100100,
B01111110,
B00100100,
B00011000},
//戌
inu_bmp[] =
{ B10111101,
B00011000,
B00000000,
B00000000,
B01000010,
B00011000,
B00011000,
B00000000},
//亥
i_bmp[] =
{ B10100101,
B00011000,
B00000000,
B11000011,
B0011000,
B01100110,
B10000001,
B10100101};
void modeCnt() {
delay(200);
if(digitalRead(3) == 0) {
mode++;
}
if(mode > 4) {
mode = 0;
}
}
void setup()
{
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
pixels.setBrightness(20);
pixels.begin(); // This initializes the NeoPixel library.
pixels.show();
matrix.begin(0x70);
matrix.setBrightness(6);
Serial.begin(115200);
pinMode(3, INPUT_PULLUP);
attachInterrupt(1, modeCnt, FALLING);
mode = 0;
// Initialize DS3231
//Serial.println("Initialize DS3231");
clock.begin();
// Set sketch compiling time
//clock.setDateTime(__DATE__, __TIME__);
// Manual (Year, Month, Day, Hour, Minute, Second)
//clock.setDateTime(2014, 4, 25, 12, 59, 54);
}
void loop()
{
dt = clock.getDateTime();
if (dt.hour >= 12) {
hr1 = dt.hour - 12;
} else{
hr1 = dt.hour;
}
hr2 = map(hr1, 0, 12, 0, NUMPIXELS);
mg = map(dt.minute, 0, 60, 0, NUMPIXELS);
sb = map(dt.second, 0, 60, 0, NUMPIXELS);
hr2 = NUMPIXELS - hr2;
if (hr2 == NUMPIXELS) {
hr2 = 0;
}
mg = NUMPIXELS - mg;
if (mg == NUMPIXELS) {
mg = 0;
}
sb = NUMPIXELS - sb;
if (sb == NUMPIXELS) {
sb = 0;
}
for (int i=0; i<NUMPIXELS; i++) {
r[i] = 0;
}
if (mg == 0) {
for (int i=0; i<NUMPIXELS; i++) {
g[i] = 0;
}
}
if (sb == 0) {
for (int i=0; i<NUMPIXELS; i++) {
b[i] = 0;
}
}
r[hr2] = 63;
g[mg] = 88;
b[sb] = 87;
for (int i=0; i<NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(r[i], g[i], b[i]));
}
pixels.show();
//Serial.println(clock.dateFormat("Y/m/d (l) H:i:s", dt));
//Serial.println(mode);
//Serial.println(clock.readTemperature());
if (mode == 0) {
mode_ori = mode;
matrix.clear();
matrix.writeDisplay();
}
//デジタル時刻
if (mode == 1) {
mode_ori = mode;
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=8; x>=-29; x--) {
if (mode != 1){return;}
matrix.clear();
matrix.setCursor(x,0);
//matrix.print(String(dt.hour) + ":" + String(dt.minute));
matrix.print(clock.dateFormat("H:i", dt));
matrix.writeDisplay();
delay(50);
}
}
//日付
if (mode == 2) {
mode_ori = mode;
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=8; x>=-58; x--) {
if (mode != 2){return;}
matrix.clear();
matrix.setCursor(x,0);
//matrix.print(clock.dateFormat("m/d l", dt));
matrix.print(clock.dateFormat("m/d D.", dt));
matrix.writeDisplay();
delay(40);
}
}
//気温
if (mode == 3) {
clock.forceConversion();
mode_ori = mode;
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=8; x>=-23; x--) {
if (mode != 3){return;}
matrix.clear();
matrix.setCursor(x,0);
matrix.print(String(clock.readTemperature(),1));
matrix.writeDisplay();
delay(50);
}
}
//DEMO
if (mode == 4) {
mode_ori = mode;
switch (demoState) {
case 0:
matrix.clear();
switch (hr1) {
case 0:
matrix.drawBitmap(0, 0, ne_bmp, 8, 8, LED_ON);
break;
case 1:
matrix.drawBitmap(0, 0, ushi_bmp, 8, 8, LED_ON);
break;
case 2:
matrix.drawBitmap(0, 0, tora_bmp, 8, 8, LED_ON);
break;
case 3:
matrix.drawBitmap(0, 0, u_bmp, 8, 8, LED_ON);
break;
case 4:
matrix.drawBitmap(0, 0, tatsu_bmp, 8, 8, LED_ON);
break;
case 5:
matrix.drawBitmap(0, 0, mi_bmp, 8, 8, LED_ON);
break;
case 6:
matrix.drawBitmap(0, 0, uma_bmp, 8, 8, LED_ON);
break;
case 7:
matrix.drawBitmap(0, 0, hitsu_bmp, 8, 8, LED_ON);
break;
case 8:
matrix.drawBitmap(0, 0, saru_bmp, 8, 8, LED_ON);
break;
case 9:
matrix.drawBitmap(0, 0, tori_bmp, 8, 8, LED_ON);
break;
case 10:
matrix.drawBitmap(0, 0, inu_bmp, 8, 8, LED_ON);
break;
case 11:
matrix.drawBitmap(0, 0, i_bmp, 8, 8, LED_ON);
break;
}
matrix.writeDisplay();
break;
case 1:
matrix.clear();
matrix.writeDisplay();
break;
}
demoState++;
if (demoState > 1) {
demoState = 0;
}
}
if (mg == 0 && dt.second < 10) {
mode = 10;
switch (demoState) {
case 0:
matrix.clear();
switch (hr1) {
case 0:
matrix.drawBitmap(0, 0, ne_bmp, 8, 8, LED_ON);
break;
case 1:
matrix.drawBitmap(0, 0, ushi_bmp, 8, 8, LED_ON);
break;
case 2:
matrix.drawBitmap(0, 0, tora_bmp, 8, 8, LED_ON);
break;
case 3:
matrix.drawBitmap(0, 0, u_bmp, 8, 8, LED_ON);
break;
case 4:
matrix.drawBitmap(0, 0, tatsu_bmp, 8, 8, LED_ON);
break;
case 5:
matrix.drawBitmap(0, 0, mi_bmp, 8, 8, LED_ON);
break;
case 6:
matrix.drawBitmap(0, 0, uma_bmp, 8, 8, LED_ON);
break;
case 7:
matrix.drawBitmap(0, 0, hitsu_bmp, 8, 8, LED_ON);
break;
case 8:
matrix.drawBitmap(0, 0, saru_bmp, 8, 8, LED_ON);
break;
case 9:
matrix.drawBitmap(0, 0, tori_bmp, 8, 8, LED_ON);
break;
case 10:
matrix.drawBitmap(0, 0, inu_bmp, 8, 8, LED_ON);
break;
case 11:
matrix.drawBitmap(0, 0, i_bmp, 8, 8, LED_ON);
break;
}
matrix.writeDisplay();
break;
case 1:
matrix.clear();
matrix.writeDisplay();
break;
}
demoState++;
if (demoState > 1) {
demoState = 0;
}
}
if (mg == 0 && dt.second > 10) {
mode = mode_ori;
}
delay(800);
}
投稿者の人気記事
-
HomeMadeGarbage
さんが
2020/03/01
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する