[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

번호 제목 글쓴이 날짜 조회수
200 DIY RHA_014 이불에 쌓여온 Marantz오디오 icon 청계천도사 08-20 1,313
199 DIY RHA_013 김창완(산울림)의 녹음기(Revox Mk2) 수리하기 icon 청계천도사 07-30 2,034
198 DIY RHA_012 황동버너 수리하기2(결론: 재 탄생) icon 청계천도사 07-30 2,044
197 DIY RHA_011 황동 버너 수리의 기억 icon 청계천도사 07-30 2,119
196 DIY Arduino uno보드를 만들기 icon 청계천도사 02-16 4,440
195 DIY Digilog Electronics 005 - Digilog Electronics 이야기 icon 청계천도사 02-12 4,257
194 DIY Digilog Electronics 004 - IC/전자 부품 핀 간격 이야기 icon 청계천도사 01-05 4,722
193 DIY Digilog Electronics 003 -Summing Amplifier icon 청계천도사 01-04 4,805
192 DIY Digilog Electronics 002 - 전자회로 기ch , 실험 환경 꾸미기 +1 icon 청계천도사 01-03 5,006
191 DIY Digilog Electronics 001 - 전자회로 기초 (사실은 복습입니다) icon 청계천도사 01-02 4,958
190 DIY MC-001 가을입니다. [알레르기 시작] icon 청계천도사 09-09 5,487
189 DIY RHA_010 밥통아~!! 너도 고장 나나냐?!! icon 청계천도사 08-28 5,412
188 DIY RHA_009 Magnet Contator (마그네트스위치 전자접촉기)교체 icon 청계천도사 08-16 5,891
187 DIY RHA_008 독일제 기계도 고장나면 고물 - 결국 수리함 icon 청계천도사 08-11 6,092
186 DIY RHA_007 [야매] 휴즈 만들어 끼우기 icon 청계천도사 08-11 5,383
185 DIY RHA_006 목공용 수평 멀티 드릴 수리하기 icon 청계천도사 08-06 5,707
184 DIY RHA_005 선풍기 수리 (대형 30인치, 15파이) icon 청계천도사 08-01 6,104
183 DIY RHA_004 대형 CNC 베어링 오일 주입기 수리(미스트 오일 주입기) icon 청계천도사 07-22 5,927
182 DIY RHA_003B 지게차 수리하기 (지게차 배터리선 연결하기) icon 청계천도사 07-22 5,723
181 DIY RHA_003A 지게차 수리하기 icon 청계천도사 07-19 5,795