// 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
#define VERT_PIN 4
#define HORZ_PIN 0
#define SEL_PIN 2
// 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
// hardcoded time values
int w = 8;
int d_width = 128/w;
int d_height = 128;
int m_width = 12;
int b_line = 20;
int x = m_width/2;
int y = d_height - b_line;
void setup(void) { // Arduino setup
u8g2.begin(); // begin the u8g2 library
u8g2.setContrast(255); // set display contrast/brightness
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
pinMode(SEL_PIN, INPUT_PULLUP);
}
// draw the background - fullscreen circle, dots for seconds, big tickmarks, numbers
void draw_background() {
u8g2.drawFrame(0, 0, (m_width+1)*w, d_height);
u8g2.drawFrame((m_width+1)*w+1, 0, (d_width-m_width-1)*w, d_height);
}
// draw thin hand = second hand
void draw_car(int x, int y, int d = 1) {
u8g2.drawLine(x*w-3, y+2*d, x*w, y); // draw the menu line
u8g2.drawLine(x*w+3, y+2*d, x*w, y); // draw the menu line
u8g2.drawLine(x*w-3, y+2*d, x*w+3, y+2*d); // draw the menu line
u8g2.drawBox(x*w-1, y+3*d, 3, 8*d);
u8g2.drawBox(x*w-3, y+8*d, 7, 2*d);
}
// draw thin hand = second hand
void draw_score(int hr, int vr) {
u8g2.setFont(u8g2_font_6x10_mn);
u8g2.setCursor((m_width+1)*w, 3*w);
u8g2.print(hr);
u8g2.setCursor((m_width+1)*w, 6*w);
u8g2.print(vr);
}
void loop(void) { // main Arduino loop
int horz = analogRead(HORZ_PIN);
int vert = analogRead(VERT_PIN);
bool selPressed = digitalRead(SEL_PIN) == LOW;
if (horz > 2048+150 && x > 1) {
x--;
} else if (horz < 2048-150 && x < m_width) {
x++;
}
// horz goes from 0 (right) to 1023 (left)
// vert goes from 0 (bottom) to 1023 (top)
// selPressed is true is the joystick is pressed
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
draw_background(); // draw the background - fullscreen circle, dots for seconds, big tickmarks, numbers
draw_car(x, y);
draw_score(horz, vert);
} while ( u8g2.nextPage() ); // go over all the pages until the whole display is updated
// for(;;);
}