【Arduino 动手做】DIY Arduino 模拟时钟

2025-07-27105
AI 快速预览详细 收起
本项目介绍了如何使用Arduino Nano微控制器、ST7920芯片的LCD显示屏和三个按钮制作一个模拟时钟。该项目适合STEM教育场景,适合8岁以上儿童。通过简单的组件和代码,用户可以轻松制作一个有趣的模拟时钟。项目代码从blaber.com.pl站点下载并调整为上述显示,展示了如何使用u8g2库在不同类型的显示器上绘制对象和写入文本。

一个有趣的漂亮的模拟式时钟,它的构建也非常简单。

这次我将向您展示如何制作一个有趣的好看的时钟,它的构建也非常简单。确切的时间时间以椭圆形模拟时钟的形式显示在大型 LCD 屏幕上。时间也可以借助三个按钮轻松调节。

在这种情况下,为了简单起见,没有使用实时时钟模块,因此精度没有那么高,主要取决于微控制器内的晶体。
该设备由几个组件组成:
- Arduino Nano 微控制器
- 基于 ST7920 芯片的 LCD 显示屏,分辨率为 128x64 点
- 和三个按钮

基本代码是从 blaber.com.pl 站点下载的,方法是将其调整为上述显示,比原始显示更易于访问且便宜得多。代码是对数字时钟的修改,虽然它可以工作,但它仍然需要在图形上做大量的工作。这是如何使用 u8g2 库在不同类型的显示器上绘制对象和写入文本的一个很好的示例。

开机时,时间是12:00,我们必须手动设置当前时间。我们在三个按钮的帮助下使它变得简单。中间按钮用于进入设置模式,第一次点击设置分钟,第二次点击小时。在设置模式下,箭头在其他两个按钮的帮助下移动。在精度方面,考虑到我们不使用 RTC 模块,时钟非常准确。就我而言,24 小时实时与时钟之间的差异只有几秒钟。
最后,将设备内置到一个合适的盒子中,由厚度为 3 毫米和 5 毫米的 PVC 材料制成,并涂有不干胶彩色壁纸。

 

01.jpg
02.jpg
03.jpg
04.jpg
09.jpg
10.jpg

项目代码

 

代码
#include <Arduino.h>
#include <U8g2lib.h>
#include <TimerOne.h>



U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R2, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);


byte inPin1 = 7;                  //digital input sw-1 marking hours or minutes
byte inPin2 = 6;                  //sw-2 digital input correcting minutes
byte inPin3 = 5;                  //digital input sw-3 correcting hours 
byte P1, P2;                      //button states
uint8_t s, m, g;                  //declaration of seconds, minutes and hours
boolean kropki;                   //variable of the dots
const char tarczaX[60] = {        //X coordinates of the target points
  64, 61, 56, 53, 50, 48, 45, 42, 40, 40,
  35, 34, 31, 29, 28, 28, 28, 29, 31, 34,
  35, 38, 40, 42, 45, 48, 50, 53, 56, 61,
  64, 68, 72, 76, 79, 82, 85, 87, 90, 92,
  94, 96, 98, 99, 100, 100, 100, 99, 98, 96,
  94, 92, 90, 87, 85, 82, 79, 76, 68, 64 };
const char tarczaY[60] = {        //y coordinates of the target points
  54, 54, 54, 54, 53, 52, 51, 49, 48, 48,
  44, 43, 40, 37, 35, 32, 27, 26, 23, 21,
  19, 17, 15, 13, 12, 10,  9,  8,  8,  8,
   8,  8,  8,  8,  8,  9, 10, 12, 13, 15,
  17, 19, 21, 23, 26, 32, 35, 37, 40, 42,
  44, 46, 48, 48, 48, 52, 53, 54, 54, 54 };  
  
void setup() {
  u8g2.begin();
  pinMode(inPin1, INPUT_PULLUP);          //setting the pin as a digital input
  pinMode(inPin2, INPUT_PULLUP);
  pinMode(inPin3, INPUT_PULLUP);
  u8g2.setContrast(220);
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(toggleOutput);
  P1 = 0; P2 = 0; s = 0; m = 0; g = 0;

}

void loop() {
  u8g2.setFont(u8g2_font_9x15B_tr);
  u8g2.setFontDirection(2);           //select the direction of subtitles
  Dipsw();
  u8g2.firstPage();
  char m_str[3];
  strcpy(m_str, u8x8_u8toa(m, 2));    //Replace m with a string with 2 digits
  do {
    u8g2.drawStr(115,27,"9");
    u8g2.drawStr(20,27,"3");
    u8g2.drawStr(67,0,"6");
    u8g2.drawStr(73,52,"12"); 
    u8g2.drawDisc(64,32,3);                     //center of the clock
    u8g2.drawDisc(42,57,2);                     //hour 1
    u8g2.drawDisc(24,49,2);                     //hour 2
    u8g2.drawDisc(24,14,2);                     //hour 4
    u8g2.drawDisc(42,5,2);                      //hour 5
    u8g2.drawDisc(85,5,2);                      //hour 7
    u8g2.drawDisc(104,14,2);                    //hour 8
    u8g2.drawDisc(104,49,2);                    //hour 10
    u8g2.drawDisc(85,57,2);                     //hour 11    
    if (P1 == 1){ u8g2.drawStr(10,0,"M");}      //marking correcting minutes
    if (P1 == 2){ u8g2.drawStr(10,0,"H");}      //marking of correcting hours
    //drawing hour hand
    if (g == 0 or g == 12){u8g2.drawTriangle(64,49, 67,32, 61,32);}
    if (g == 1 or g == 13){u8g2.drawTriangle(50,49, 67,34, 61,30);}
    if (g == 2 or g == 14){u8g2.drawTriangle(40,42, 65,35, 60,30);}
    if (g == 3 or g == 15){u8g2.drawTriangle(32,32, 64,35, 64,29);}
    if (g == 4 or g == 16){u8g2.drawTriangle(40,21, 63,29, 63,35);}
    if (g == 5 or g == 17){u8g2.drawTriangle(48,13, 66,30, 62,34);}
    if (g == 6 or g == 18){u8g2.drawTriangle(64,13, 68,32, 60,32);}
    if (g == 7 or g == 19){u8g2.drawTriangle(79,13, 67,34, 62,30);}
    if (g == 8 or g == 20){u8g2.drawTriangle(88,21, 66,35, 63,30);}
    if (g == 9 or g == 21){u8g2.drawTriangle(96,32, 64,35, 64,29);}
    if (g == 10 or g == 22){u8g2.drawTriangle(88,42, 64,35, 65,28);}
    if (g == 11 or g == 23){u8g2.drawTriangle(79,49, 67,31, 62,35);}
    //drawing a second hand
    u8g2.drawLine(64,32, tarczaX[s], tarczaY[s]);
    // draw minute hand
    //u8g2.drawStr(20,50,m_str);
    if (m == 0) {u8g2.drawLine(67,32, 64,54); u8g2.drawLine(61,32, 64,54);}
    if (m == 1) {u8g2.drawLine(67,32, 60,54); u8g2.drawLine(61,32, 60,54);}
    if (m == 2) {u8g2.drawLine(67,32, 56,54); u8g2.drawLine(61,32, 56,54);}
    if (m == 3) {u8g2.drawLine(66,33, 53,54); u8g2.drawLine(61,31, 53,54);}
    if (m == 4) {u8g2.drawLine(66,33, 50,53); u8g2.drawLine(61,31, 50,53);}
    if (m == 5) {u8g2.drawLine(65,34, 48,52); u8g2.drawLine(61,30, 48,52);}
    if (m == 6) {u8g2.drawLine(64,34, 45,51); u8g2.drawLine(61,30, 45,51);}
    if (m == 7) {u8g2.drawLine(64,34, 42,49); u8g2.drawLine(61,30, 42,49);}
    if (m == 8) {u8g2.drawLine(64,34, 40,48); u8g2.drawLine(61,30, 40,48);}
    if (m == 9) {u8g2.drawLine(64,35, 38,46); u8g2.drawLine(61,30, 38,46);} 
    if (m == 10) {u8g2.drawLine(65,35, 35,44); u8g2.drawLine(62,30, 35,44);}
    if (m == 11) {u8g2.drawLine(64,35, 34,43); u8g2.drawLine(62,29, 34,43);}
    if (m == 12) {u8g2.drawLine(64,35, 31,40); u8g2.drawLine(62,29, 31,40);}
    if (m == 13) {u8g2.drawLine(64,35, 29,37); u8g2.drawLine(63,29, 29,37);}
    if (m == 14) {u8g2.drawLine(64,35, 28,35); u8g2.drawLine(63,29, 28,35);}
    if (m == 15) {u8g2.drawLine(64,35, 28,32); u8g2.drawLine(63,29, 28,32);} //
    if (m == 16) {u8g2.drawLine(63,35, 28,27); u8g2.drawLine(64,29, 28,27);}
    if (m == 17) {u8g2.drawLine(63,35, 29,26); u8g2.drawLine(64,29, 29,26);}
    if (m == 18) {u8g2.drawLine(63,35, 31,23); u8g2.drawLine(64,29, 31,23);}
    if (m == 19) {u8g2.drawLine(63,35, 34,21); u8g2.drawLine(64,29, 34,21);}          
    if (m == 20) {u8g2.drawLine(63,35, 35,19); u8g2.drawLine(65,29, 35,19);}
    if (m == 21) {u8g2.drawLine(63,35, 38,17); u8g2.drawLine(65,29, 38,17);}
    if (m == 22) {u8g2.drawLine(62,34, 40,15); u8g2.drawLine(65,29, 40,15);}
    if (m == 23) {u8g2.drawLine(62,34, 42,13); u8g2.drawLine(65,29, 42,13);}
    if (m == 24) {u8g2.drawLine(62,34, 45,12); u8g2.drawLine(66,29, 45,12);}
    if (m == 25) {u8g2.drawLine(61,34, 48,10); u8g2.drawLine(66,32, 48,10);}
    if (m == 26) {u8g2.drawLine(61,33, 50,9); u8g2.drawLine(66,30, 50,9);}
    if (m == 27) {u8g2.drawLine(66,32, 53,8); u8g2.drawLine(61,33, 53,8);}
    if (m == 28) {u8g2.drawLine(67,32, 56,8); u8g2.drawLine(61,33, 56,8);}
    if (m == 29) {u8g2.drawLine(67,32, 61,8); u8g2.drawLine(61,32, 61,8);}          
    if (m == 30) {u8g2.drawLine(67,32, 64,8); u8g2.drawLine(61,32, 64,8);} ///
    if (m == 31) {u8g2.drawLine(67,32, 68,8); u8g2.drawLine(61,32, 68,8);}
    if (m == 32) {u8g2.drawLine(67,32, 72,8); u8g2.drawLine(61,32, 72,8);}
    if (m == 33) {u8g2.drawLine(67,32, 76,8); u8g2.drawLine(61,31, 76,8);}
    if (m == 34) {u8g2.drawLine(67,32, 79,8); u8g2.drawLine(62,31, 79,8);}
    if (m == 35) {u8g2.drawLine(67,33, 82,9); u8g2.drawLine(62,30, 82,9);}
    if (m == 36) {u8g2.drawLine(66,34, 85,10); u8g2.drawLine(62,30, 85,10);}
    if (m == 37) {u8g2.drawLine(66,34, 87,12); u8g2.drawLine(62,30, 87,12);}
    if (m == 38) {u8g2.drawLine(66,34, 90,13); u8g2.drawLine(63,30, 90,13);}
    if (m == 39) {u8g2.drawLine(66,35, 92,15); u8g2.drawLine(63,30, 92,15);}          
    if (m == 40) {u8g2.drawLine(66,35, 94,17); u8g2.drawLine(63,30, 94,17);}
    if (m == 41) {u8g2.drawLine(65,35, 96,19); u8g2.drawLine(64,30, 96,19);}
    if (m == 42) {u8g2.drawLine(65,35, 98,21); u8g2.drawLine(64,30, 98,21);}
    if (m == 43) {u8g2.drawLine(65,35, 99,23); u8g2.drawLine(64,29, 99,23);}
    if (m == 44) {u8g2.drawLine(64,35, 100,26); u8g2.drawLine(64,29, 100,26);}
    if (m == 45) {u8g2.drawLine(64,35, 100,32); u8g2.drawLine(64,29, 100,32);} ///
    if (m == 46) {u8g2.drawLine(64,35, 100,35); u8g2.drawLine(64,29, 100,35);}
    if (m == 47) {u8g2.drawLine(64,35, 99,37); u8g2.drawLine(64,29, 99,37);}
    if (m == 48) {u8g2.drawLine(64,35, 98,40); u8g2.drawLine(64,29, 98,40);}
    if (m == 49) {u8g2.drawLine(64,35, 96,42); u8g2.drawLine(65,28, 96,42);}          
    if (m == 50) {u8g2.drawLine(64,35, 94,44); u8g2.drawLine(65,28, 94,44);}
    if (m == 51) {u8g2.drawLine(63,35, 92,46); u8g2.drawLine(66,30, 92,46);}
    if (m == 52) {u8g2.drawLine(63,35, 90,48); u8g2.drawLine(66,30, 90,48);}
    if (m == 53) {u8g2.drawLine(64,34, 87,48); u8g2.drawLine(66,29, 87,48);}
    if (m == 54) {u8g2.drawLine(63,35, 85,48); u8g2.drawLine(67,31, 85,48);}
    if (m == 55) {u8g2.drawLine(67,31, 82,52); u8g2.drawLine(63,35, 82,52);}
    if (m == 56) {u8g2.drawLine(67,31, 79,53); u8g2.drawLine(62,35, 79,53);}
    if (m == 57) {u8g2.drawLine(67,31, 76,54); u8g2.drawLine(62,35, 76,54);}
    if (m == 58) {u8g2.drawLine(67,31, 72,54); u8g2.drawLine(62,34, 72,54);}
    if (m == 59) {u8g2.drawLine(67,31, 68,54); u8g2.drawLine(62,32, 68,54);}                  
  } while ( u8g2.nextPage() );
  delayMicroseconds(10000); 
}

void toggleOutput(){
    s++;
    if (s == 60) {
      s = 0;
      m++;
    }
    if (m == 60) {
      m = 0;
      g++;
    }
    if (g == 24) {
      g = 0;
    } 
    kropki = !kropki;               //blinking colon every 1 sec.
}

void Dipsw(){
  byte readPin1, readPin1A, readPin2, readPin2A, readPin3, readPin3A;
  readPin1 = digitalRead(inPin1);           //read the state of the rotation button
  readPin2 = digitalRead(inPin2);           //reading the status of the right move button
  readPin3 = digitalRead(inPin3);           //reading the state of the move left button
  delay(1);
  readPin1A = digitalRead(inPin1);
  readPin2A = digitalRead(inPin2);
  readPin3A = digitalRead(inPin3);
  if (readPin1 == LOW and readPin1 == readPin1A) {
    //setting the time - selecting hours or minutes
    P1++;
    delay(200);
    if (P1 == 3){
      P1 = 0;
    }
  }  
  if (readPin2 == LOW and readPin2 == readPin2A) {
    //correcting hours and minutes up
    if (P1 == 1){                           //correcting minutes
       m++;
       if (m == 59) {m = 0;}
    }
    if (P1 == 2){                           //framing minutes
      g++;
      if (g == 24){g = 0;}
    }
    delay(200);
  }
  if (readPin3 == LOW and readPin3 == readPin3A) { 
  //correcting hours and minutes down
    if (P1 == 1){                           //correcting minutes
      m--;
      if (m >= 60) {m = 59;}
      if (m <= 0) {m = 59;}
    }
    if (P1 == 2){                           //correcting hours
      g--;
      if (g >= 24){g = 23;}
      if (g <= 0){g = 23;}
    }
    delay(200);
  }
}

【Arduino 动手做】DIY Arduino 模拟时钟
项目链接:https://www.hackster.io/mircemk/diy-arduino-analog-clock-93aead
项目作者:北马其顿 米尔塞姆克(Mirko Pavleski)

项目视频 :https://www.youtube.com/watch?v=EkwxNqki2ew
项目代码:https://www.hackster.io/code_files/598371/download

 

00190-.gif

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(0)
- 没有更多了 -