2015/11/01
Arduino+7Seg LED+RTCでデジタル時計
部品箱で眠っているArduinoに安い7Seg LEDを接続してデジタル時計を作ります。
簡単にするために4桁(12:34)のLED(4桁7セグLED表示器 [BW428G-E1-10MM])を使います。
Arduinoの内部クロックでは精度が得られないので高精度(月差13秒程度)のRTC(RX-8025NB使用 I2C接続リアルタイムクロック(RTC)モジュール)を接続しました。
*RTCを接続しなくても動きますが精度は悪いです・・
電源投入時は、00:00で計時開始します、時刻合わせは「YYMMDDhhmmss+CR(‘\r’)」の形式でUARTに書込めば同期します。
全体の写真
7Seg LED(BW428G-E1-10MM:カソードコモン)のピン配列写真
7Seg LED(BW428G-E1-10MM)の接続写真(D2~D13に直接刺しています)
RTC(RX-8025NB)ブレークアウトボードの接続
スケッチ(Arduino7SEG2.ino) *ソース行を減らすために可読性を犠牲にしています(*- -)(*_ _)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
#include <Arduino.h> #include <Wire.h> #define RTC_ADDR 0x32 byte fontArray[10] = { // .gfedcba B00111111, // 0xC0 '0' a B00000110, // 0xF9 '1' f b . B01011011, // 0xA4 '2' g B01001111, // 0xB0 '3' e c . B01100110, // 0x99 '4' d B01101101, // 0x92 '5' B01111101, // 0x82 '6' B00000111, // 0xF8 '7' B01111111, // 0x80 '8' B01101111 // 0x98 '9' }; const byte segMap[] = { 4, 6, 11, 2, 3, 5, 8, 12 }; const byte digMap[] = { 13, 10, 9, 7 }; byte Dates[6] = { 100, 12, 31, 12, 34, 60 }; byte rtc_OK; void rtc_read(byte *d) { Wire.requestFrom(RTC_ADDR, 8); for (int i = 5; i >= 0; i--) { if ((i == 5) || (i == 2)) Wire.read(); // skip 0x0F and 0x03 byte w = Wire.read(); *(d + i) = ((w >> 4) * 10) + (w & 15); } } void rtc_write(byte *d) { Wire.beginTransmission(RTC_ADDR); for (int i = 5; i >= 0; i--) { if ((i == 5) || (i == 2)) Wire.write(0x00); // dummy 0x0F and 0x03 byte w = *(d + i); Wire.write(((w / 10) << 4) | (w % 10)); } Wire.endTransmission(); } int times_chk() { int rc = 9; if (Dates[0] > 99) Dates[rc = 0] = 15; // YY > Light check because the date is not used if (Dates[1] > 12) Dates[rc = 1] = 12; // MM > .. if (Dates[2] > 31) Dates[rc = 2] = 31; // DD > .. if (Dates[3] > 23) Dates[rc = 3] = 23; // hh if (Dates[4] > 59) Dates[rc = 4] = 59; // mm if (Dates[5] > 59) Dates[rc = 5] = 59; // ss return(rc); } void setup(void) { Serial.begin(115200); pinMode(17, OUTPUT); digitalWrite(17, LOW); pinMode(16, OUTPUT); digitalWrite(16, HIGH); for (int i = 0; i < 4; i++) pinMode(digMap[i], OUTPUT), digitalWrite(digMap[i], HIGH); for (int i = 0; i < 8; i++) pinMode(segMap[i], OUTPUT), digitalWrite(segMap[i], LOW); Wire.begin(); delay(80); Wire.beginTransmission(RTC_ADDR); byte RTC_init[] = { 0xE0, 0x22, 0x00 }; //151121 for (int i = 0; i < 3; i++) Wire.write(RTC_init[i]); //151121 Wire.endTransmission(); delay(20); rtc_read(Dates); if (times_chk() != 9) rtc_write(Dates); Dates[0] = 100; rtc_read(Dates); rtc_OK = (times_chk() == 9); } void loop(void) { int i, j, p = 0; byte sbuff[12], w, x, y, z; unsigned long pre_ms = millis() + 1000, temp_ms; while (1) { if (Serial.available()) { unsigned char b = Serial.read(); if ((b >= '0') && (b <= '9') && (p < 12)) sbuff[p++] = b; if (b == '\r') { if (p == 12) { for (p = j = 0; j < 6; j++) Dates[j] = ((sbuff[j + j] & 0x0F) * 10) + (sbuff[j + j + 1] & 0x0F); times_chk(); if (rtc_OK) rtc_write(Dates); pre_ms = millis() + 1000; } for (j = 0; j < 6; j++) Serial.print(Dates[j]), Serial.print("/\0/\0 \0:\0:\0\n" + j + j); } } if ((temp_ms = millis()) >= pre_ms) { pre_ms = temp_ms + 1000 - (temp_ms - pre_ms); if ( ++Dates[5] > 59) if (Dates[5] = 0, ++Dates[4] > 59) if (Dates[4] = 0, ++Dates[3] > 23) Dates[3] = 0; if ((Dates[5] == 0) && (rtc_OK)) rtc_read(Dates); } for (i = 0; i < 4; i++) { if (i) digitalWrite(digMap[i - 1], HIGH); digitalWrite(segMap[0], w = (((i == 1) && ((pre_ms - millis()) < 500)) ? 3 : 0)); j = ((i & 1) ? (Dates[3 + (i >> 1)] % 10) : (Dates[3 + (i >> 1)] / 10)); for (x = 0x40, y = 1; y < 8; x >>= 1, y++, w += z) digitalWrite(segMap[y], z = ((fontArray[j] & x) ? 1 : 0)); digitalWrite(digMap[i], LOW); delayMicroseconds(w * 500); } digitalWrite(digMap[3], HIGH); } } |
コメント:2
Very Cool Project. i like your coding very much. you just write 2 library in this sketch!
2016/10/17 @ 06:42 PM
Saeed より
すみません。このプログラムをGRSAKURAのRTCで使和せていただきたいと考えているのですがどう書き換えればいいかなど教えていただけますか?
2017/05/27 @ 11:47 PM
asean より