#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define button_pin 2
Adafruit_SSD1306 Oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
RTC_DS1307 rtc;
const float BETA = 3950;
unsigned long t1 = 0;
unsigned long time = 0;
bool a = false;
int s = 0;
int time_wait_button = 5; //5 seconds
int mode = 0;
int i = 0;
int c = 0;
int poz = 1;
int broj = 1;
int kretanjeY = 30;
int sec1 = 0;
int min1 = 0;
unsigned long msec = 0;
unsigned long mili = 0;
int pres = 0;
int fase = 0;
int start = 0;
unsigned long tim = 0;
const float val_pi = 3.14159267 ;
const int center_of_clock_x_axis = 64; // center of oled
const int center_of_clock_y_axis = 32; // center of oled
int o = 1;
float celsius = 0;
// variables used to calculate coordinates of points on the circle
int x;
int y;
int z;
int b;
// variables to store previous values read off RTC module
int seconds = 0;
int minutes;
int hours;
String current_mins = "";
String current_hours = "";
String current_secs = "";
String current_time = "";
int c_mins = 0;
int c_hours = 0;
int c_secs = 0;
#define blue_pin 5
#define red_pin 3
#define green_pin 4
void setup()
{
Serial.begin(9600);
pinMode(blue_pin, OUTPUT);
pinMode(red_pin, OUTPUT);
pinMode(green_pin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(button_pin), button_isr, CHANGE);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
/// set data from serial and send to variables to show on oled
char buf[6];
char tmp;
int cnt = 0;
int h, m, s;
Serial.print("Enter time in 24-hour format [hhmmss]: ");
while (cnt < 6)
{
while (Serial.available() == 0) {};
tmp = Serial.read();
if ((tmp >= '0') and (tmp <= '9'))
{
buf[cnt] = tmp;
cnt++;
Serial.print(tmp);
}
}
Serial.println();
h = ((buf[0] - '0') * 10) + (buf[1] - '0');
m = ((buf[2] - '0') * 10) + (buf[3] - '0');
s = ((buf[4] - '0') * 10) + (buf[5] - '0');
if ((h > 23) or (m > 59) or (s > 59))
Serial.println("ERROR: Invalid time");
else
{
Serial.println(h);
Serial.println(m);
Serial.println(s);
Serial.print("New time set to ");
if (h < 10)
Serial.print("0");
Serial.print(h, DEC);
Serial.print(":");
if (m < 10)
Serial.print("0");
Serial.print(m, DEC);
Serial.print(":");
if (s < 10)
Serial.print("0");
Serial.print(s, DEC);
Serial.println("...");
}
rtc.adjust(DateTime(2022, 9, 10, h, m, s)); // pass variables from serial to set time using library fucntion
// SSD1306_SWITCHCAPVCC = generate Oled voltage from 3.3V internally
Oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32
Oled.clearDisplay();
face_clock(); // fucntion that we used to make clock face
Oled.display();
}
void draw_second_hand(int second, int mode)
{
y = (24 * cos(val_pi - (2 * val_pi) / 60 * second)) + center_of_clock_y_axis;
x = (24 * sin(val_pi - (2 * val_pi) / 60 * second)) + center_of_clock_x_axis;
if (mode == 1) Oled.drawCircle(x, y, 2, SSD1306_WHITE);
else Oled.drawCircle(x, y, 2, SSD1306_BLACK);
}
void draw_hour_hand(int hour, int minute, int mode)
{
// calculations got from internet to make an hour hand
y = (18 * cos(val_pi - (2 * val_pi) / 12 * hour - (2 * val_pi) / 720 * minute)) + center_of_clock_y_axis;
x = (18 * sin(val_pi - (2 * val_pi) / 12 * hour - (2 * val_pi) / 720 * minute)) + center_of_clock_x_axis;
b = (18 * cos(val_pi - (2 * val_pi) / 12 * hour - (2 * val_pi) / 720 * minute)) + center_of_clock_y_axis + 1;
z = (18 * sin(val_pi - (2 * val_pi) / 12 * hour - (2 * val_pi) / 720 * minute)) + center_of_clock_x_axis + 1;
if (mode == 1) {
Oled.drawLine(center_of_clock_x_axis, center_of_clock_y_axis, x, y, SSD1306_WHITE);
Oled.drawLine(center_of_clock_x_axis + 1, center_of_clock_y_axis + 1, z, b, SSD1306_WHITE);
}
else {
Oled.drawLine(center_of_clock_x_axis, center_of_clock_y_axis, x, y, SSD1306_BLACK);
Oled.drawLine(center_of_clock_x_axis + 1, center_of_clock_y_axis + 1, z, b, SSD1306_BLACK);
}
}
void draw_minute_hand(int minute, int mode)
{
// calculations got from internet to make an minute hand
y = (24 * cos(val_pi - (2 * val_pi) / 60 * minute)) + center_of_clock_y_axis;
x = (24 * sin(val_pi - (2 * val_pi) / 60 * minute)) + center_of_clock_x_axis;
if (mode == 1)Oled.drawLine(center_of_clock_x_axis, center_of_clock_y_axis, x, y, SSD1306_WHITE); else Oled.drawLine(center_of_clock_x_axis, center_of_clock_y_axis, x, y, SSD1306_BLACK);
}
void face_clock(void)
{
// draw the center of the clock
Oled.drawCircle(center_of_clock_x_axis, center_of_clock_y_axis, 3, SSD1306_WHITE);
Oled.fillCircle(center_of_clock_x_axis, center_of_clock_y_axis, 3, SSD1306_WHITE);
// draw hour pointers around the face of a clock
for (int i = 0; i < 12; i++) {
y = (32 * cos(val_pi - (2 * val_pi) / 12 * i)) + center_of_clock_y_axis;
x = (32 * sin(val_pi - (2 * val_pi) / 12 * i)) + center_of_clock_x_axis;
b = (28 * cos(val_pi - (2 * val_pi) / 12 * i)) + center_of_clock_y_axis;
z = (28 * sin(val_pi - (2 * val_pi) / 12 * i)) + center_of_clock_x_axis;
Oled.drawLine(z, b, x, y, SSD1306_WHITE);
}
// print string "12" at the top of the face of the clock
Oled.drawCircle(26 * sin(val_pi) + center_of_clock_x_axis, (26 * cos(val_pi)) + center_of_clock_y_axis, 6, SSD1306_BLACK);
Oled.fillCircle(26 * sin(val_pi) + center_of_clock_x_axis, (26 * cos(val_pi)) + center_of_clock_y_axis, 5, SSD1306_BLACK);
Oled.setTextSize(1); // Normal 1:1 val_pixel scale
Oled.setTextColor(SSD1306_WHITE); // Draw white text
Oled.setCursor(center_of_clock_x_axis - 3, 0); // Start at top-left corner
Oled.println(F("12"));
}
void draw_face_clock_reset(void)
{
Oled.drawCircle(center_of_clock_x_axis, center_of_clock_y_axis, 3, SSD1306_WHITE);
Oled.fillCircle(center_of_clock_x_axis, center_of_clock_y_axis, 3, SSD1306_WHITE);
Oled.setCursor(center_of_clock_x_axis - 3, 0);
Oled.println(F("12"));
}
void loop()
{
int analogValue = analogRead(A0);
celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
DateTime now = rtc.now();
char buf1[] = "hh";
char buf2[] = "mm";
char buf3[] = "ss";
current_hours = now.toString(buf1);
current_mins = now.toString(buf2);
current_secs = now.toString(buf3);
c_mins = current_mins.toInt(); // current mins from rtc
c_hours = current_hours.toInt() ; // current hours from rtc
c_secs = current_secs.toInt(); // current secs from rtc
// Serial.println(mode);
if (time >= 2 && time < 3 && s == 1)
{
s = 0;
mode = 0;
Serial.println("clock mode!");
Oled.clearDisplay();
Oled.display();
delay(1000);
}
if (time >= 3 && time < 4 && s == 1)
{
s = 0;
mode = 1;
Serial.println("Stop watch mode!");
Oled.clearDisplay();
Oled.display();
delay(1000);
}
if (time >= 4 && time < 5 && s == 1)
{
s = 0;
mode = 2;
Serial.println("Alarm mode!");
Oled.clearDisplay();
Oled.display();
delay(1000);
}
if (time >= 5 && s == 1)
{
s = 0;
mode = 3;
Serial.println("temp_display mode!");
Oled.clearDisplay();
Oled.display();
delay(1000);
}
if (mode == 0)
{
if (c_secs != seconds) // make oled display seconds hand moving by clearing and displaying simultaneously
{
Oled.clearDisplay();
Oled.setTextSize(0.5);
Oled.setTextColor(WHITE);
Oled.setCursor(0, 0);
char buffe[] = "hh:mm";
current_time = now.toString(buffe);
Oled.print(current_time);
face_clock();
draw_face_clock_reset();
draw_second_hand(c_secs, 0);
draw_minute_hand(c_mins, 0);
draw_hour_hand(c_hours, c_mins, 0);
draw_second_hand(c_secs, 1);
draw_minute_hand(c_mins, 1);
draw_hour_hand(c_hours, c_mins, 1);
seconds = c_secs;
minutes = c_mins;
hours = c_hours;
Oled.display();
}
}
if (mode == 1)
{
if (c == 1)
{
c = 0;
Serial.println("in stop watch");
Oled.clearDisplay();
Oled.display();
}
Oled.clearDisplay();
if (digitalRead(2) == 1)
{
if (pres == 0)
{
fase = fase + 1;
pres = 1;
if (fase > 2)
fase = 0;
}
} else
{
pres = 0;
}
if (fase == 0)
{
Oled.clearDisplay();
Oled.setTextSize(2);
Oled.setTextColor(WHITE);
Oled.setCursor(40, 32);
Oled.print("Start");
sec1 = 0;
min1 = 0;
tim = 0;
mili = 0;
msec = 0;
start = 0;
}
if (fase == 1)
{
Oled.clearDisplay();
Oled.setTextSize(2);
Oled.setTextColor(WHITE);
if (start == 0)
{
start = 1;
tim = millis();
}
msec = (millis() - tim);
min1 = msec / 60000;
if ((msec / 1000) > 59)
{
sec1 = (msec / 1000) - (min1 * 60);
} else {
sec1 = msec / 1000;
}
mili = (msec % 1000) / 10;
Oled.setCursor(38, 20);
if (min1 <= 9)
{
Oled.print("0");
Oled.print(min1);
}
else
{
Oled.print(min1);
}
Oled.print(":");
if (sec1 <= 9)
{
Oled.print("0");
Oled.print(sec1);
} else {
Oled.print(sec1);
}
Oled.setTextSize(2);
Oled.setTextColor(WHITE);
Oled.setCursor(45, 50);
if (mili <= 9)
{
Oled.print("0");
Oled.print(mili);
} else {
Oled.print(mili);
}
}
if (fase == 2)
{
Oled.clearDisplay();
Oled.setTextSize(2);
Oled.setCursor(38, 20);
if (min1 <= 9)
{
Oled.print("0");
Oled.print(min1);
} else {
Oled.print(min1);
}
Oled.print(":");
if (sec1 <= 9)
{
Oled.print("0");
Oled.print(sec1);
} else {
Oled.print(sec1);
}
Oled.setTextSize(2);
Oled.setTextColor(WHITE);
Oled.setCursor(45, 50);
if (mili <= 9)
{
Oled.print("0");
Oled.print(mili);
} else {
Oled.print(mili);
}
}
Oled.display();
}
if (mode == 2)
{
char buf[4];
char tmp;
int cnt = 0;
int h, m;
if (c == 1)
{
c = 0;
Serial.println("Alarm Mode!");
Serial.print("Enter time in 24-hour format to set the alarm! [hhmm]: ");
while (cnt < 4)
{
while (Serial.available() == 0) {};
tmp = Serial.read();
if ((tmp >= '0') and (tmp <= '9'))
{
buf[cnt] = tmp;
cnt++;
Serial.print(tmp);
}
}
Serial.println();
h = ((buf[0] - '0') * 10) + (buf[1] - '0');
m = ((buf[2] - '0') * 10) + (buf[3] - '0');
if ((h > 23) or (m > 59))
Serial.println("ERROR: Invalid time");
else
{
Serial.println(h);
Serial.println(m);
Serial.print("New Alarm set to ");
if (h < 10)
Serial.print("0");
Serial.print(h, DEC);
Serial.print(":");
if (m < 10)
Serial.print("0");
Serial.print(m, DEC);
}
}
// Serial.println("h is: " + String(h));
// Serial.println("m is: " + String(m));
// Serial.println("rtc h is: " + String(c_hours));
// Serial.println("rtc m is: " + String(c_mins));
if (h == c_hours && m == c_mins)
{
tone(8, 262, 250);
delay(500);
noTone(8);
}
}
if (mode == 3)
{
if (digitalRead(2) == 1)
{
if (pres == 0)
{
fase = fase + 1;
pres = 1;
if (fase > 1)
fase = 0;
}
} else
{
pres = 0;
}
if (fase == 0)
{
Oled.clearDisplay();
Oled.setTextSize(2);
Oled.setTextColor(WHITE);
Oled.setCursor(0, 0);
String current_temp = String(celsius) + " C*";
Oled.print(current_temp);
Oled.display();
if (celsius < 26)
{
digitalWrite(blue_pin, HIGH);
digitalWrite(red_pin, LOW);
digitalWrite(green_pin, LOW);
}
if (celsius < 40 && celsius >= 26)
{
digitalWrite(blue_pin, LOW);
digitalWrite(red_pin, LOW);
digitalWrite(green_pin, HIGH);
}
if (celsius >= 40)
{
digitalWrite(blue_pin, LOW);
digitalWrite(red_pin, HIGH);
digitalWrite(green_pin, LOW);
}
}
if (fase == 1)
{
Oled.clearDisplay();
Oled.display();
digitalWrite(blue_pin, LOW);
digitalWrite(red_pin, LOW);
digitalWrite(green_pin, LOW);
}
}
}
void button_isr()
{
if (digitalRead(button_pin) == HIGH)
{
t1 = millis();
}
else
{
time = (millis() - t1) / 1000;
// Serial.println(time);
s = 1;
c = 1;
}
}