This time I will show you how to make an interesting nice looking clock, which is also extremely simple to build. The exact time time is displayed on a large LCD screen in the form of an elliptical analog clock. The time can also be easily adjusted with the help of three buttons.
In this case, for the sake of simplicity, a real-time clock module is not used, so the accuracy is not so high and depends mostly on the crystal within the microcontroller.
The device consists of several components:
The basic code is downloaded from the blaber.com.pl site by adjusting it to the above-mentioned display which is more accessible and much cheaper than the original. Code is a modification of the digital clock, and although it works, it still requires a lot of work on the graphics. This is a great example of how to use the u8g2 library to draw objects and write text on different types of displays.
When switching on, the time is 12:00 and we have to manually set the current time. We make it easy with the help of three buttons. The middle button is used to enter the settings mode, and with the first click the Minutes are set, and with the second click the Hours. In settings mode, the arrows are moved with the help of the other two buttons. When it comes to precision, considering that we do not use RTC module the clock is quite accurate. In my case for 24 hours the difference between real time and that of the clock was only a few seconds.
Finally, the device is built into a suitable box made of PVC material with thicknesses of 3mm and 5mm and coated with self-adhesive colored wallpaper.
#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);
}
}