インフィニティミラー時計:終わりなき美しさと正確な時刻の融合
必要なパーツと用品
| パーツ | 数量 |
|---|---|
| リアルタイムクロック(RTC)モジュール | 1 |
| Arduino Nano R3 | 1 |
| 抵抗 10k Ω | 3 |
プロジェクト概要
自分へのご褒美にも、贈り物にも最素晴らしいデザイン「インフィニティミラー時計」をご紹介します。お手持ちのミラーが終わりのない無限の奥行きを持ち、同時に正確な時計としても機能したら素敵じゃないですか?今日広く使われているRGB LEDを使用したこのプロジェクトを皆さんと共有できることを嬉しく思います。動画を見て、無限ミラー時計の作り方を学んでください。
コード
Arduinoコード
#include
#include
#include
#ifdef __AVR__
#include
#endif
#define PIN 8
#define NUMPIXELS 60
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
namespace {
byte ysaat; // 設定用時
byte ydak; // 設定用分
byte saat; // 現在時
byte dak; // 現在分
byte sn; // 現在秒
byte kontrol = 0; // 制御状態
const int kCePin = 5; // Chip Enable
const int kIoPin = 6; // Input/Output
const int kSclkPin = 7; // Serial Clock
DS1302 rtc(kCePin, kIoPin, kSclkPin);
}
void printTime() {
Time t = rtc.time();
saat = t.hr;
dak = t.min;
sn = t.sec;
if (saat >= 12) { saat = saat - 12; }
// 時針(青)、分針(緑)、秒針(赤)をLEDで表示
pixels.setPixelColor(5 * saat, pixels.Color(25, 25, 255));
pixels.setPixelColor(dak, pixels.Color(0, 200, 10));
pixels.setPixelColor(sn, pixels.Color(255, 0, 0));
pixels.show();
// 秒が0になったら分針を更新
if (sn == 0) {
pixels.setPixelColor(dak - 1, pixels.Color(0, 0, 0));
pixels.setPixelColor(dak, pixels.Color(0, 200, 10));
pixels.show();
for (int i = 1; i < 60; i++) {
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
}
if (dak == 0) {
pixels.setPixelColor(59, pixels.Color(0, 0, 0));
}
}
void animasyon() {
colorWipe(strip.Color(255, 0, 0), 25); // 赤
colorWipe(strip.Color(0, 255, 0), 25); // 緑
colorWipe(strip.Color(0, 0, 255), 25); // 青
theaterChase(strip.Color(127, 127, 127), 50); // 白
theaterChase(strip.Color(127, 0, 0), 50); // 赤
theaterChase(strip.Color(0, 0, 127), 50); // 青
for (int i = 1; i < 60; i++) {
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
}
void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void theaterChase(uint32_t c, uint8_t wait) {
for (int j = 0; j < 10; j++) {
for (int q = 0; q < 3; q++) {
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, c);
}
strip.show();
delay(wait);
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, 0);
}
}
}
}
void yenisaat() {
Time t(2018, 2, 23, ysaat, ydak, 0, Time::kFriday);
rtc.time(t);
}
int clockSet = 10;
int up = 11;
int down = 12;
void setup() {
Serial.begin(9600);
#if defined(__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
strip.begin();
strip.show();
pixels.begin();
pinMode(clockSet, INPUT);
rtc.writeProtect(false);
rtc.halt(false);
}
void loop() {
// 時刻設定モード(kontrol=1: 時設定, 2: 分設定, 3: 完了)
if (kontrol == 1) {
pixels.setPixelColor(5 * ysaat, pixels.Color(25, 25, 255));
pixels.show(); delay(100);
pixels.setPixelColor(5 * ysaat, pixels.Color(0, 0, 0));
pixels.show(); delay(100);
if (digitalRead(up) == HIGH) {
ysaat++;
while (digitalRead(up) == HIGH);
if (ysaat == 12) ysaat = 0;
}
if (digitalRead(down) == HIGH) {
ysaat--;
while (digitalRead(down) == HIGH);
if (ysaat == 255) ysaat = 11;
}
pixels.setPixelColor(5 * ysaat, pixels.Color(25, 25, 255));
pixels.show(); delay(100);
pixels.setPixelColor(5 * ysaat, pixels.Color(0, 0, 0));
pixels.show(); delay(100);
yenisaat();
if (digitalRead(clockSet) == HIGH) {
while (digitalRead(clockSet) == HIGH) {
pixels.setPixelColor(kontrol, pixels.Color(255, 255, 255));
pixels.show();
}
pixels.setPixelColor(kontrol, pixels.Color(0, 0, 0));
pixels.show();
kontrol++;
ysaat = saat; ydak = dak;
}
}
if (kontrol == 2) {
if (digitalRead(clockSet) == HIGH) {
kontrol++;
while (digitalRead(clockSet) == HIGH) { }
ysaat = saat; ydak = dak;
}
if (digitalRead(up) == HIGH) {
ydak++;
while (digitalRead(up) == HIGH);
if (ydak == 60) ydak = 0;
}
if (digitalRead(down) == HIGH) {
ydak--;
while (digitalRead(down) == HIGH);
if (ydak == 255) ydak = 59;
}
pixels.setPixelColor(ydak, pixels.Color(0, 205, 10));
pixels.show();
yenisaat();
delay(100);
pixels.setPixelColor(ydak, pixels.Color(0, 0, 0));
pixels.show();
delay(100);
}
if (kontrol == 3) {
kontrol = 0;
yenisaat();
}
// 通常モード:時刻表示
while (kontrol == 0) {
if (digitalRead(up) == HIGH) {
animasyon();
}
if (digitalRead(clockSet) == HIGH) {
kontrol++;
while (digitalRead(clockSet) == HIGH);
ysaat = saat; ydak = dak;
}
printTime();
}
}
カスタムパーツとエンクロージャ
回路図
製造プロセス
- 鳩時計:歴史、職人技、現代への進化
- 現代ミラーの科学と技術:古代から最新コーティングまで
- Infinity Gears:41段ギアボックスが実現する346京年分の回転
- Arduino POVクロック:残像効果で浮かび上がるLED時計を自作する
- DIY Arduinoワードクロック – 文字で時刻を表示する洗練されたリアルタイムクロック
- 自作冷却ミラー式湿度計(チルドミラーヒグロメーター)──Arduinoで高精度な温湿度測定
- DIY万華鏡インフィニティミラー - Arduino 101で作る美しいLEDライトディスプレイ
- 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
- イタリア語ワードクロック自作:Arduino Nano、NeoPixel、LCD、RTCで時刻を文字で表示
- Arduino UNOで作るベルリンクロック – DIY LEDマトリクス時計
- Verilogクロックジェネレータ:設計と実装ガイド