[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

    }

  }

}








 

 - 요기까지 ; 복잡하면 다음 실험 데이터 봐주세요 -  


0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

메이커 DIY

번호 제목 글쓴이 날짜 조회수
57 DIY [Tube] in Love - WEY20P0011 icon 청계천도사 11-20 13,071
56 DIY 인턴인 [튜브]는 라이언을 미워하지 않는다. - WEY20P0010 icon 청계천도사 11-19 16,817
55 DIY 라이언 가족중 [튜브]를 초대합니다. [19금 버전] - WEY20P0009 icon 청계천도사 11-18 14,273
54 DIY 라이언의 친구중[제이지] - WEY20P0008 icon 청계천도사 11-17 13,672
53 DIY 라이언의 친구들이 오고싶어합니다. -WEY20P0007 icon 청계천도사 11-17 13,207
52 DIY 내 친구 [미니언] 입니다. - WEY20P0006 icon 청계천도사 11-13 14,038
51 DIY 외로운 라이언에게 친구만들어주기 (Apeaxch) - WEY20P0005 icon 청계천도사 11-12 13,799
50 DIY 꽃게 철입니다. 이넘도 요리해 먹을가요? [Sebastian] - WEY20P0004 icon 청계천도사 11-11 12,226
49 DIY 오르골 기초 올렸습니다. +3 icon 청계천도사 11-09 14,284
48 DIY Thermistor 규격표 보는법 icon 청계천도사 11-06 12,472
47 DIY 곰돌이 푸우 ~~~ 가 왔습니다. - WEY20P0003 icon 청계천도사 11-05 13,496
46 DIY 라이언(카카오프렌즈) 친구 왔어요. - WEY20P0002 icon 청계천도사 11-04 13,034
45 DIY 이런 컬러링 만들기 [헬X키티] - WEY20P0001 icon 청계천도사 11-03 13,062
44 DIY 오르골 이야기 둘째 편 icon 청계천도사 06-21 14,275
43 DIY 다른 프로젝트 시작... 오르골 +1 icon 청계천도사 06-18 12,548
42 DIY 작성중 - [더미천국] 아두이노 기초편4 입니다. (이대로 따라하면 고수된다) icon 청계천도사 03-27 12,952
41 DIY [더미천국] 아두이노 기초편3 입니다. (이대로 따라하면 고수된다) icon 청계천도사 12-28 12,813
40 DIY [더미천국] 아두이노 기초편 2 입니다. (이대로 따라하면 고수된다) icon 청계천도사 12-28 15,486
39 DIY [더미천국] 아두이노 기초편 1 입니다. (이대로 따라하면 고수된다) +1 icon 청계천도사 12-16 13,418
38 DIY [더미천국] 펠티에 소자를 아시나요? icon 청계천도사 12-07 13,112