산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 나노 + DS3231 RTC 기반 128x64 LCD 스마트 시계 (아날로그/디지털 시간, 온도 표시)

부품 및 소모품

부품 수량
아두이노 나노 R3 1
Maxim Integrated DS3231M - ±5ppm, I2C 실시간 시계 1
10kΩ 단회전 포텐셔미터 1
푸시버튼 스위치 (모멘터리) 1
128x64 LCD 그래픽 디스플레이 1

필요 도구 및 장비

도구
납땜 인두 (일반)

프로젝트 개요

아두이노시아(Arduino e Cia) 웹 페이지에 소개된 프로젝트로, 128x64 LCD 그래픽 디스플레이, 디스플레이 대비 조절용 포텐셔미터, DS3231 RTC 모듈, 푸시 버튼으로 구성된 아두이노 시계입니다. RTC 모듈은 아두이노의 A4(SDA), A5(SCL) 핀에 연결됩니다. 버튼은 디지털 핀 3에 연결되며, 소프트웨어로 아두이노 내부 풀업 저항을 활성화합니다. 프로그램을 컴파일하기 전에 몇 가지 라이브러리를 설치해야 합니다. 라이브러리 압축을 풀고 아두이노 IDE의 LIBRARIES 폴더에 넣으세요.

프로그램에는 두 개의 화면이 있습니다:

화면 전환은 디지털 핀 3에 연결된 푸시 버튼을 눌러 수행합니다.

아두이노 나노 + DS3231 RTC 기반 128x64 LCD 스마트 시계 (아날로그/디지털 시간, 온도 표시)

DS3231 RTC 모듈의 날짜와 시간을 설정하려면 시리얼 모니터를 사용해 연도, 월, 일, 시, 분, 초 순서로 정보를 입력하세요. 정보를 올바르게 입력하면 완료 메시지가 표시됩니다.

코드

// 프로그램: 128x64 LCD 디스플레이와 RTC DS3231
// 작성자: Arduino e Cia
#include <U8glib.h>
#include <DS3232RTC.h>
#include <Streaming.h>
#include <Time.h>
#include <Wire.h>

// 아래 라인은 디스플레이 연결을 정의하며, 사용 모델에 맞게 조정해야 함
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4, 7); // Enable, RW, RS, RESET

int X2 = 0, Y2 = 0, X3 = 0, Y3 = 0;
float angulo = 0;
int posicao = 0, posicaoh = 0;
int temperatura = 0;
int min_temp = 500, max_temp = -500;
int ScreenWith = 128, ScreenWithC = 96;
int ScreenHeight = 64, ScreenHeightC = 32;

#define botao 3
int estado_botao = 0;
char* dia_da_semana[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

void tela_1() {
  u8g.drawRFrame(0, 0, 128, 64, 3);
  // 온도 표시
  u8g.setPrintPos(20, 30);
  u8g.print(temperatura);
  u8g.drawStr(42, 30, "C");
  u8g.drawCircle(37, 34, 2);
  mostra_relogio_digital();
  // 아날로그 시계 배경
  fundo_relogio();
  // 시침 업데이트
  desenha_ponteiro(hour()-1, 12.0, 10);
  // 분침 업데이트
  desenha_ponteiro(minute()-5, 60.0, 19);
  // 초침 업데이트
  desenha_ponteiro(second()-5, 60, 21);
}

void tela_2() {
  u8g.drawRFrame(0, 0, 128, 64, 3);
  u8g.drawRFrame(68, 4, 55, 56, 2);
  mostra_relogio_digital();
  u8g.setFont(u8g_font_5x8);
  u8g.drawStr(78, 35, "MIN");
  u8g.drawStr(78, 53, "MAX");
  u8g.setFont(u8g_font_6x13);
  u8g.setPrintPos(25, 41);
  u8g.print(dia_da_semana[(weekday()-1)]);
  // 현재 온도
  u8g.setPrintPos(83, 19);
  u8g.print(temperatura);
  u8g.drawStr(105, 19, "C");
  u8g.drawCircle(100, 12, 2);
  // 최저 온도
  u8g.setPrintPos(98, 36);
  u8g.print(min_temp);
  u8g.drawCircle(113, 29, 2);
  // 최고 온도
  u8g.setPrintPos(98, 54);
  u8g.print(max_temp);
  u8g.drawCircle(113, 47, 2);
}

void desenha_ponteiro(float valor, float rotacao, int Radius) {
  angulo = valor * 2.0 * 3.1415 / rotacao - 1.5707;
  X2 = ScreenWithC + Radius * cos(angulo);
  Y2 = ScreenHeightC + Radius * sin(angulo);
  u8g.drawLine(ScreenWithC, ScreenHeightC, X2, Y2);
}

void fundo_relogio() {
  u8g.drawCircle(ScreenWithC, ScreenHeightC, 27);
  u8g.drawCircle(ScreenWithC, ScreenHeightC, 1);
  u8g.setFont(u8g_font_6x13);
  u8g.setFontPosTop();
  u8g.drawStr(90, 9, "12");
  u8g.drawStr(114, 25, "3");
  u8g.drawStr(94, 44, "6");
  u8g.drawStr(74, 25, "9");
  for(int traco_minuto = 0; traco_minuto < 12; traco_minuto++) {
    angulo = traco_minuto / 12.0 * 2 * 3.1415;
    X2 = ScreenWithC + 25 * cos(angulo);
    Y2 = ScreenHeightC + 25 * sin(angulo);
    X3 = ScreenWithC + 25 * cos(angulo);
    Y3 = ScreenHeightC + 25 * sin(angulo);
    u8g.drawLine(X2, Y2, X3, Y3);
  }
}

void mostra_relogio_digital() {
  // 날짜 표시
  u8g.setFont(u8g_font_5x8);
  u8g.setPrintPos(8, 55);
  u8g.print(day());
  u8g.drawStr(19, 55, "/");
  u8g.setPrintPos(24, 55);
  u8g.print(month());
  u8g.drawStr(35, 55, "/");
  u8g.setPrintPos(41, 55);
  u8g.print(year());
  // 시:분 표시
  u8g.drawRBox(3, 4, 62, 21, 2);
  u8g.setColorIndex(0);
  u8g.setFont(u8g_font_fub17);
  u8g.drawStr(29, 21, ":");
  // 시가 10보다 작으면 0 채우기
  if (hour() < 10) {
    u8g.drawStr(3, 23, "0");
    posicaoh = 16;
  } else posicaoh = 3;
  u8g.setPrintPos(posicaoh, 23);
  u8g.print(hour());
  // 분이 10보다 작으면 0 채우기
  if (minute() < 10) {
    u8g.drawStr(38, 23, "0");
    posicao = 51;
  } else posicao = 38;
  u8g.setPrintPos(posicao, 23);
  u8g.print(minute());
  u8g.setColorIndex(1);
}

void setup() {
  pinMode(3, INPUT_PULLUP);
  Serial.begin(9600);
  if (u8g.getMode() == U8G_MODE_R3G3B2) u8g.setColorIndex(255);
  else if (u8g.getMode() == U8G_MODE_GRAY2BIT) u8g.setColorIndex(3);
  else if (u8g.getMode() == U8G_MODE_BW) u8g.setColorIndex(1);
  setSyncProvider(RTC.get);
  Serial << F("RTC Sync");
  if (timeStatus() != timeSet) Serial << F(" FAIL!");
  Serial << endl;
}

void loop() {
  temperatura = RTC.temperature() / 4.0;
  if (temperatura >= max_temp) max_temp = temperatura;
  if (temperatura <= min_temp) min_temp = temperatura;

  static time_t tLast;
  time_t t;
  tmElements_t tm;

  // 시리얼로 새 시간 설정 확인 (연,월,일,시,분,초)
  if (Serial.available() >= 12) {
    int y = Serial.parseInt();
    if (y >= 100 && y < 1000) Serial << F("Error: Year must be 2 or 4 digits!") << endl;
    else {
      if (y >= 1000) tm.Year = CalendarYrToTm(y);
      else tm.Year = y2kYearToTm(y);
      tm.Month = Serial.parseInt();
      tm.Day = Serial.parseInt();
      tm.Hour = Serial.parseInt();
      tm.Minute = Serial.parseInt();
      tm.Second = Serial.parseInt();
      t = makeTime(tm);
      RTC.set(t);
      setTime(t);
      Serial << F("Time changed to: ");
      printDateTime(t);
      Serial << endl;
      while (Serial.available() > 0) Serial.read();
    }
  }

  t = now();
  if (t != tLast) {
    tLast = t;
    printDateTime(t);
    Serial << endl;
  }

  // 버튼 눌림 확인
  boolean valor_botao = digitalRead(3);
  if (valor_botao != 1) {
    while(digitalRead(3) != 1) delay(100);
    estado_botao = !estado_botao;
  }

  // 화면 루프
  u8g.firstPage();
  do {
    if (estado_botao == 0) tela_1();
    if (estado_botao == 1) tela_2();
  } while(u8g.nextPage());
  delay(10);
}

// 시리얼에 날짜/시간 출력
void printDateTime(time_t t) {
  printI00(day(t), 0);
  Serial << monthShortStr(month(t)) << _DEC(year(t));
  Serial << ' ';
  printI00(hour(t), ':');
  printI00(minute(t), ':');
  printI00(second(t), ' ');
}

// 10 미만일 때 "00" 대신 "0" 출력 방지
void printI00(int val, char delim) {
  if (val < 10) Serial << '0';
  Serial << _DEC(val);
  if (delim > 0) Serial << delim;
}

라이브러리

라이브러리는 별도 다운로드 필요 (미리보기 없음)

회로도

아두이노 나노 + DS3231 RTC 기반 128x64 LCD 스마트 시계 (아날로그/디지털 시간, 온도 표시)

제조공정

  1. 아날로그와 디지털 신호: 산업 계측의 기초
  2. 아날로그 vs 디지털 센서: 유형, 응용 및 실용 예시
  3. 아두이노 POV 클락: 퍼시스턴스 오브 비전 LED 디스플레이 제작
  4. 아두이노로 만드는 대형 LED 마스터 시계 (알람 기능 포함, 12m 거리에서도 식별 가능)
  5. 아두이노 우노로 만드는 LCD 애니메이션 & 게임 기초
  6. 아두이노 듀(Due) + 3.2″ TFT로 만드는 실시간 시계 & 온도 모니터
  7. TM1637 4자리 디지털 시계: 시간/알람 설정 기능 탑재 (아두이노 나노)
  8. 아두이노와 노키아 5110 LCD로 만드는 DIY 전압계 - 단계별 가이드
  9. BME280 온도·습도·기압을 넥시온 터치스크린에 표시하기
  10. DS1302 RTC와 아두이노 우노로 만드는 신뢰할 수 있는 알람 시계