回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

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

头像 驴友花雕 2025.07.27 10 0

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

这次我将向您展示如何制作一个有趣的好看的时钟,它的构建也非常简单。确切的时间时间以椭圆形模拟时钟的形式显示在大型 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

评论

user-avatar
icon 他的勋章
    展开更多