// simple project using Arduino UNO and 128x64 OLED Display to display analog clock
// note - this project is meant for the 128x128 SH1107 OLED display, but WOKWI currently only supports 128x64 OLED display
// for this reason, the preview here only shows half of the design
// created by upir, 2023
// youtube channel: https://www.youtube.com/upir_upir
// YOUTUBE VIDEO: https://youtu.be/srgsBWHSNSQ
// links from the video:
// 128x128 SH1107 OLED Display: https://s.click.aliexpress.com/e/_DdOCQHj
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
// Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx
// Photopea (online Photoshop-like tool): https://www.photopea.com/
// u8g2 documentation: https://github.com/olikraus/u8g2/wiki/u8gvsu8g2
// Related videos:
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
#include <Arduino.h>
#include <U8g2lib.h> // u8g2 library for drawing on OLED display - needs to be installed in Arduino IDE first
#include <Wire.h> // wire library for IIC communication with the OLED display
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0); // set the OLED display to 128x64px, HW IIC, no rotation, used in WOKWI
//U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R0); // final display, 128x128px [page buffer, size = 128 bytes], HW IIC connection
// IIC connection of the OLED display and Arduino UNO
// +5V > +5V
// GND > GND
// SCL (serial clock) > A5 or SCL
// SDA (serial data) > A4 or SDA
const uint8_t KeyPrev = 4; //- кнопка
const uint8_t KeySelect = 5; //выбор
const uint8_t KeyNext = 6; //+
#define eq_width 7
#define eq_height 7
static const unsigned char eq[] U8X8_PROGMEM = { //эквалайзер
0x10, 0x10, 0x14, 0x14, 0x54, 0x54, 0x55, };
#define half_width 7
#define half_height 7
static const unsigned char half[] U8X8_PROGMEM = { //полчаса
0x1C, 0x2A, 0x49, 0x79, 0x41, 0x22, 0x1C, };
#define light_width 7
#define light_height 7
static const unsigned char light[] U8X8_PROGMEM = { //подсветка
0x49, 0x2A, 0x14, 0x63, 0x14, 0x2A, 0x49, };
#define sound_width 8
#define sound_height 8
static const unsigned char sound[] U8X8_PROGMEM = { //звук
0x08, 0x4C, 0x8B, 0xA9, 0xA9, 0x8B, 0x4C, 0x08, };
// hardcoded time values
int time_minutes = 10;
int time_hours = 10;
int time_seconds = 45;
uint8_t buttonlast = false;
int8_t hourstart = 7, hourstop = 23, set = 1;
bool flagpres = false;
const char *week [7] = {"Воскресение","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"};//день недели 7-4 11-2 5-1
const char *month [12] = {"Января","Февраля","Марта","Апреля","Мая ","Июня","Июля","Августа","Сентября","Октября","Ноября","Декабря"};
void setup(void) { // Arduino setup
pinMode(KeyPrev, INPUT_PULLUP); //кнопки 3 шт.
pinMode(KeySelect, INPUT_PULLUP);
pinMode(KeyNext, INPUT_PULLUP);
u8g2.begin(); // begin the u8g2 library
u8g2.enableUTF8Print();
u8g2.setContrast(255); // set display contrast/brightness
}
void buttonControl(){ //обработчик кнопок
if(digitalRead(KeyNext) == LOW){ //button+
if(!flagpres){
buttonlast = KeyNext;
flagpres = true;
}
}
else if(digitalRead(KeyPrev) == LOW){ //button- poversav добавить к 2 кнопкам
if(!flagpres){
buttonlast = KeyPrev;
flagpres = true;
}
}
else if(digitalRead(KeySelect) == LOW){ //button select
if(!flagpres){
buttonlast = KeySelect;
flagpres = true;
}
}else{
if(flagpres){
if(buttonlast == KeyNext){
switch(set){
case 1: if(hourstart < 23) {
if(hourstart != hourstop){
hourstart++;
} else {hourstart = hourstart;}
} else
//if(hourstart == hourstop){
// if(hourstart == 23)
// hourstart--;
// if(hourstart == 0)
// hourstart++;
//} else
{ hourstart = 0; }
break;
case 2: if(hourstop < 23) {
hourstop++;
//if(hourstop <= hourstart){
//hourstop = hourstart+1;
//}
} else { hourstop = 0; } break;
}
}else
if(buttonlast == KeyPrev){
switch(set) {
case 1: if(hourstart > 0){
if(hourstart != hourstop) {
hourstart--;
} else {hourstart = hourstart;}
} else
//if(hourstart == hourstop){
// if(hourstart == 23)
// hourstart--;
// if(hourstart == 0)
// hourstart++;
//} else
{hourstart = 23;}
break;
case 2: if(hourstop > 0) {
hourstop--;
//if(hourstop <= hourstart){
// hourstop = hourstart+1;
// }
} else { hourstop = 23; } break;
}
}
else if(buttonlast == KeySelect){
if(set < 2){
set++;
} else{ set = 1;}
}
flagpres = false;
}
}
}
void loop(void) { // main Arduino loop
u8g2.firstPage(); // select the first page of the display (page is 128x8px), since we are using the page drawing method of the u8g2 library
do { // draw
/*u8g2.setFont(u8g2_font_6x13_t_cyrillic);
u8g2.setCursor(42, 11);
u8g2.print(week[4]);//день недели
u8g2.setCursor(115, 11);
u8g2.print(27); //секунды
//u8g2.setFont(u8g2_font_osb35_tn);//24х32рх альтернатива u8g2_font_osr35_tn
//u8g2.setFont(u8g2_font_osr35_tn);
u8g2.setFont(u8g2_font_mystery_quest_48_tn);//x+3px
u8g2.setCursor(2+3, 50);
u8g2.print(20); //часы
u8g2.drawFrame(2,13,56,39);
if(int(27)%2 == 0)
u8g2.drawStr(56+3, 48, " ");
else
u8g2.drawStr(56+3, 48, ":"); //вывод мигающего двоеточия
u8g2.setCursor(70+3, 50);
u8g2.print(57); //минуты
u8g2.drawFrame(70,13,56,39);
u8g2.setFont(u8g2_font_6x13_t_cyrillic);
u8g2.setCursor(30, 62);
u8g2.print(29); //число
u8g2.setCursor(50, 62);
u8g2.print(month[10-1]); //месяц
u8g2.setCursor(103, 62);
u8g2.print(2024);*/
u8g2.setFont(u8g2_font_6x13_t_cyrillic);
u8g2.drawUTF8(0, 10, "Кукушка");
//u8g2.drawUTF8(49, 10, "с");
u8g2.setCursor(49, 11);
u8g2.print(hourstart); //время начала куку
//u8g2.drawUTF8(66, 10, "-");
u8g2.drawHLine(66, 6, 5); //горизонтальная линия
u8g2.setCursor(77, 11);
u8g2.print(hourstop); //время конец куку
/*if(1) //режимы работы будильника
switch(1){
case 1: u8g2.drawUTF8(97, 11, "Ежедн");break;
case 2: u8g2.drawUTF8(97, 11, "Рабоч");break;
case 3: u8g2.drawUTF8(97, 11, "Выхдн");break;
case 4: u8g2.drawUTF8(97, 11, "Сегдн");break;
} else
if(0){
u8g2.drawUTF8(97, 11, "Отклч");
}
u8g2.drawUTF8(0, 24, "Полчаса");//сигнала в полчаса
u8g2.drawXBMP(75, 17, half_width, half_height, half);
if(1) {
u8g2.drawUTF8(97, 24, "Включ");
} else {
u8g2.drawUTF8(97, 24, "Отклч");
}
u8g2.drawUTF8(0, 37, "Громкость");//звук
u8g2.drawXBMP(75, 29, sound_width, sound_height, sound);
u8g2.setCursor(97, 37);
u8g2.print(20);
u8g2.drawUTF8(0, 49, "Эквалайзер");
u8g2.drawXBMP(75, 42, eq_width, eq_height, eq);
switch(1){
case 0: u8g2.drawUTF8(97, 49, "Норма");break;
case 1: u8g2.drawUTF8(97, 49, "Попса");break;
case 2: u8g2.drawUTF8(97, 49, "Роксс");break;
case 3: u8g2.drawUTF8(97, 49, "Джазз");break;
case 4: u8g2.drawUTF8(97, 49, "Класк");break;
}
u8g2.drawUTF8(0, 61, "Яркость"); //
u8g2.drawXBMP(75, 55, light_width, light_height, light);
u8g2.setCursor(97, 61);
u8g2.print(5);
u8g2.drawUTF8(122, 61, "А");
u8g2.drawFrame(47,0,15,13); //часы старт
u8g2.drawFrame(75,0,15,13); //часы стоп
u8g2.drawFrame(95,0,33,13); //дни
//u8g2.drawFrame(95,13,33,13); //полчаса звук
u8g2.drawFrame(95,26,15,13); //громкость
//u8g2.drawFrame(95,38,33,13); //эквалайзер
u8g2.drawFrame(95,50,15,13); //подсветка
*/
} while ( u8g2.nextPage() );
buttonControl();
}