[DIY] 볼트메터 시계만들기 1-6
그동안 뜸했죠.
컴터 앞에서 정리하기보단
제작에 보다 많은시간을 써서..
진행이 어느정도 되었냐 하면 소프트웨어가 많이 진행 되었습니다.
실제로 요즘 앋이디어 상품을 제작, 개발해 보면 하드웨어가 30%, 소프트웨어가 70%정도 시간을 더 가져가야 일이 진해이 됩니다.
일단 회로의 부분별 시험할 수 있는 소프트웨어를 만들었습니다.
그전에 [뭘 만드는지]를 확실하게 정의하여야 합니다.
그래서 각 초침, 분침, 시침의 음직임을 정리 했습니다.
이왕 만들바엔 좀 우아하게 만들어야 겠지요!!
이 시계는 디지털 시계보다 보다 많은 고려를 해야 합니다
[초침]
극적인 음직임을 위하여 1초에 한번씩 음직이는 것으로 했습니다.
0 - 59까지 음직입니다.
아두이노 출력은 0 - 4 - 8 -.. (TS)*4 .. 236으로 됩니다.
* TS ; 초 데이툼 [0..59]
[분침]
초침 보다 부드럽게 음직이기로 하였습니다.
0 - 59분 이지만 초침을 고려하여 음직입니다. 즉 초침보다는 세밀하게 음직입니다.
아두이노 출력은 0 - 1- ... (TM)*4 + ((TS+1)/15) .. - 239까지 출력 됩니다.
* TM ; 분 데이툼 [0..59]
[시침]
초침 보다 부드럽게, 분침처럼 우아하게 세밀하게 음직이기로 하였습니다.
0 - 11시 이지만 초침, 분침을 고려하여 음직입니다. 즉 초침보다는 세밀하게 음직입니다.
아두이노 출력은 0 - 1- ... (TS)*20 + ((TM+1)/3) .. - 239까지 출력 됩니다.
* TS ; 시 데이툼 [0..59]
프로그램 작성해 봤습니다.
ㅇㅇㅇㅇ /* function of This clock 1. Clock Run Mode : 0 2. Set clock Mode : 1 3. Alarm Set Mode : 2 4. Set Alarm Period : 3 */ #include <TimerOne.h> #include "TM1637.h" #include <Wire.h> #include "RTClib.h" #define ON 1 #define OFF 0 // Hardware set TM1637 #define RTCIRQ 2//pins definitions for TM1637 and can be changed to other ports // hardware Switch #define Mode 5 #define Hour 6 #define Min 7 #define Rest 8 #define HourMeter 9 #define MinMeter 10 #define SecMeter 11 #define Orgel 12 #define DIOTM1637 A2 #define CLKTM1637 A3 RTC_DS1307 rtc; int8_t TimeDisp[] = {0x00, 0x00, 0x00, 0x00}; bool ClockPoint = 1; bool Update; bool OrgelSong; unsigned char halfsecond = 0; unsigned char second; unsigned char minute = 00; unsigned char hour = 00; unsigned char ClockHour, ClockMin, ClockSec; unsigned char MeterHour, MeterMin, MeterSec, SubSec; unsigned char OldHour, OldMin; unsigned char AlarmHour = 6, AlarmMin = 0; unsigned char AlarmOffHour = 6, AlarmOffMin = 0; unsigned char AlarmPeriodMin = 5; enum mode {RunCLKTM1637, SetClock, SetAlarm, SetPeriod}; bool FlagMode, FlagHour, FlagMin, FlagMm0, FlagMm1; byte CntMode, CntHour, CntMin; unsigned int CntMm0; byte ClockMode; unsigned int MM0, MM1 ; TM1637 tm1637(CLKTM1637, DIOTM1637); DateTime now; void setup() { pinMode(RTCIRQ, INPUT_PULLUP); pinMode(Mode, INPUT_PULLUP); pinMode(Hour, INPUT_PULLUP); pinMode(Min, INPUT_PULLUP); pinMode(Rest, INPUT_PULLUP); pinMode(Orgel, OUTPUT); pinMode(HourMeter, OUTPUT); pinMode(MinMeter, OUTPUT); pinMode(SecMeter, OUTPUT); digitalWrite(Orgel, 1); // Orgel OFF digitalWrite(HourMeter, 1); digitalWrite(MinMeter, 1); digitalWrite(SecMeter, 1); //analogWrite(Orgel, 100); //TCCR2B = TCCR2B & B11111000 | B00000001; // for PWM frequency of 31372.55 Hz Serial.begin(57600); tm1637.set(); tm1637.init(); Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR if (! rtc.begin()) { Serial.println("Couldn't find RTC"); //while (1); } if (! rtc.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 4, 2019 at 11am you would call: // rtc.adjust(DateTime(2019, 1, 4, 11, 0, 0)); } } void loop() { switch (ClockMode) { case RunCLKTM1637: if (Update == ON) { TimeUpdate(); tm1637.display(TimeDisp); if (ClockHour > 12) ClockHour -= 12; //Contimue Mode MeterHour = ClockHour * 20 + (ClockMin / 3); MeterMin = ClockMin * 4 + (ClockSec / 15); MeterMin = MeterMin * 4 + SubSec; // Discontimus Mode //MeterHour = ClockHour * 20; //MeterMin = ClockMin * 4 ; //MeterMin = MeterMin * 4 ; analogWrite(HourMeter, ClockHour); analogWrite(MinMeter, ClockMin); analogWrite(SecMeter, ClockSec); OldHour = ClockHour; OldMin = ClockMin; Serial.print("MM0= "); Serial.print(MM0); Serial.print(" "); Serial.print("Mode= "); Serial.print(ClockMode); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print("Hour "); Serial.print(now.minute(), DEC); Serial.print("Min "); Serial.print(now.second(), DEC); Serial.println("sec "); if (AlarmPeriodMin > 0) { // ON condition unsigned int AlarmOn16, Clock16, AlarmOff16; Clock16 = ClockHour * 60 + ClockMin; AlarmOn16 = AlarmHour * 60 + AlarmMin; AlarmOff16 = AlarmOn16 + AlarmPeriodMin; Serial.print(AlarmOn16, DEC); Serial.print(" AlarmOn16, "); Serial.print(Clock16, DEC); Serial.print(" Clock16, "); Serial.print(AlarmOff16, DEC); Serial.println(" AlarmOff16 "); if ((Clock16 >= AlarmOn16) && (Clock16 <= AlarmOff16)) { //if (OrgelSong == 0) {} OrgelOn(); MM0 = 3500; // about 18 Sec } } else { OrgelOff(); } } if (MM0 == 0) OrgelOff(); break; case SetClock: { if (FlagHour == 1 ) { ClockHour++; if (ClockHour > 23) ClockHour = 0; FlagHour = 0 ; } if (FlagMin == 1 ) { ClockMin++; if (ClockMin > 59) ClockMin = 0; FlagMin = 0 ; } rtc.adjust(DateTime(2019, 1, 21, ClockHour, ClockMin, 0)); TimeUpdate(); tm1637.display(TimeDisp); } break; case SetAlarm: if (FlagHour == 1 ) { AlarmHour++; if ( AlarmHour > 23) AlarmHour = 0; FlagHour = 0 ; } if (FlagMin == 1 ) { AlarmMin++; if (ClockMin > 59) ClockMin = 0; FlagMin = 0 ; } AlarmUpdate(); tm1637.display(TimeDisp); AlarmOffHour = AlarmHour; AlarmOffMin = AlarmMin + AlarmPeriodMin; if (AlarmOffMin > 60) { AlarmOffMin -= 60; AlarmOffHour = AlarmHour + 1; } break; case SetPeriod: if (FlagHour == 1 ) { AlarmPeriodMin += 10; if ( AlarmPeriodMin > 59) AlarmPeriodMin -= 60; FlagHour = 0 ; } if (FlagMin == 1 ) { AlarmPeriodMin++; if (ClockMin > 59) AlarmPeriodMin = 0; FlagMin = 0 ; } AlarmPeriod(); tm1637.display(TimeDisp); AlarmOffHour = AlarmHour; AlarmOffMin = AlarmMin + AlarmPeriodMin; if (AlarmOffMin > 60) { AlarmOffMin -= 60; AlarmOffHour = AlarmHour + 1; } break; } if (FlagMode == 1) { ClockMode++; FlagMode = 0; ClockMode &= 0x03; } if (FlagMm0 == 1) { OrgelSong = !OrgelSong; FlagMm0 = 0; if (OrgelSong == 1) { MM0 = 6000; // 30000/5 digitalWrite(Orgel, 1); } else { MM0 = 0; } } } ///////////// interrupt 2 msec//////////////////// void TimingISR() { halfsecond ++; if (MM0 > 0) MM0--; switch (ClockMode) { case RunCLKTM1637: if (halfsecond == 250) // 500mSec { Update = 1;//~Update; ClockPoint = !ClockPoint; halfsecond = 0; } break; case SetClock: if (halfsecond >= 25) // 50mSec { Update = 1;//~Update; ClockPoint = !ClockPoint; halfsecond = 0; } break; case SetAlarm: if (halfsecond >= 10) // 20mSec { Update = 1;//~Update; ClockPoint = !ClockPoint; halfsecond = 0; } break; case SetPeriod: if (halfsecond >= 250) // 500mSec { Update = 1;//~Update; ClockPoint = !ClockPoint; halfsecond = 0; } break; } if (digitalRead(Mode) == 0) { // mode switch - push one time toggle ClockMode or SetMode) CntMode++; if (CntMode == 5) { FlagMode = 1; } else if (CntMode > 5) { CntMode = 6; } } else { CntMode = 0; } if (digitalRead(Hour) == 0) { // mode switch - push one time toggle ClockMode or SetMode) CntHour++; if (CntHour == 5) { FlagHour = 1; } else if ((CntHour > 100) && ((CntHour % 20) == 0)) { FlagHour = 1; if (CntHour == 240) CntHour = 100; } } else { CntHour = 0; } if (digitalRead(Min) == 0) { // mode switch - push one time toggle ClockMode or SetMode) CntMin++; if (CntMin == 5) { FlagMin = 1; } else if ((CntMin > 100) && ((CntMin % 20) == 0)) { FlagMin = 1; if (CntMin == 240) CntMin = 100; } } else { CntMin = 0; } if (digitalRead(Rest) == 0) { // mode switch - push one time toggle ClockMode or SetMode) CntMm0++; if (CntMm0 == 5) { FlagMm0 = 1; } if (CntMm0 == 600) {// 3 second FlagMm1 = 1; } } else { CntMm0 = 0; } } void TimeUpdate(void) { //DateTime now = rtc.now(); if (ClockPoint)tm1637.point(POINT_ON); else tm1637.point(POINT_OFF); ClockHour = now.hour(); ClockMin = now.minute(); ClockSec = now.second(); TimeDisp[0] = ClockHour / 10; TimeDisp[1] = ClockHour % 10; TimeDisp[2] = ClockMin / 10; TimeDisp[3] = ClockMin % 10; Update = OFF; } void AlarmUpdate(void) { //DateTime if (ClockPoint)tm1637.point(POINT_ON); else tm1637.point(POINT_OFF); // TimeDisp[0] = AlarmHour / 10; TimeDisp[1] = AlarmHour % 10; TimeDisp[2] = AlarmMin / 10; TimeDisp[3] = AlarmMin % 10; Update = OFF; } void AlarmPeriod(void) { //DateTime if (ClockPoint)tm1637.point(POINT_ON); else tm1637.point(POINT_OFF); // TimeDisp[0] = 0; TimeDisp[1] = 0; TimeDisp[2] = AlarmPeriodMin / 10; TimeDisp[3] = AlarmPeriodMin % 10; Update = OFF; } void OrgelOn(void) { digitalWrite(Orgel, 1); // Orgel 1.5V } void OrgelOff(void) { if (MM0 == 0) { if (analogRead(A6) > 100) { digitalWrite(Orgel, 0); // Orgel 0V } } } |
- 요기까지 ; 복잡하면 다음 실험 데이터 봐주세요 -