#include <RTClib.h>
#include <U8glib.h>
#include <DHT.h>
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
RTC_DS1307 rtc;
// all the arrays below are generated from images using image2cpp website
// ' icon_back', 16x16px
const unsigned char bitmap_icon_back [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x1f, 0xf0,
0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// ' icon-restart', 16x16px
const unsigned char bitmap_icon_restart [] PROGMEM = {
0x9f, 0xe0, 0xb8, 0x18, 0xf0, 0x04, 0xe0, 0x02, 0xf8, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
0x00, 0x01, 0x00, 0x01, 0x80, 0x01, 0xc0, 0x02, 0x40, 0x02, 0x20, 0x04, 0x18, 0x18, 0x07, 0xe0
};
// ' icon_alarm', 16x16px
const unsigned char bitmap_icon_alarm [] PROGMEM = {
0x00, 0x00, 0x1b, 0xd8, 0x32, 0x4c, 0x31, 0x8c, 0x16, 0x68, 0x04, 0x20, 0x24, 0x24, 0x44, 0x22,
0x48, 0x12, 0x50, 0x0a, 0x10, 0x08, 0x10, 0x08, 0x1f, 0xf8, 0x04, 0x20, 0x03, 0xc0, 0x00, 0x00
};
// ' icon_LED', 16x16px
const unsigned char bitmap_icon_LED [] PROGMEM = {
0x00, 0x00, 0x03, 0xc0, 0x04, 0x20, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x09, 0x90, 0x0f, 0xf0,
0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x00, 0x00, 0x00
};
// ' icon-test', 16x16px
const unsigned char bitmap_icon_test [] PROGMEM = {
0xff, 0xff, 0x80, 0x01, 0xaa, 0x01, 0x80, 0x01, 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x05,
0xbf, 0xa9, 0x80, 0x11, 0x80, 0x05, 0x80, 0x29, 0xbf, 0x91, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff
};
// ' icon_time', 16x16px
const unsigned char bitmap_icon_time [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x52, 0x29, 0x52, 0xa1, 0x52, 0x21,
0x52, 0x21, 0x52, 0xa2, 0x52, 0x24, 0x4c, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 384)
const unsigned char* bitmap_icons[6] = {
bitmap_icon_back,
bitmap_icon_restart,
bitmap_icon_alarm,
bitmap_icon_LED,
bitmap_icon_test,
bitmap_icon_time,
};
// 'scrollbar_background', 8x64px
const unsigned char bitmap_scrollbar_background [] PROGMEM = {
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
};
// 'item_sel_outline', 128x21px
const unsigned char bitmap_item_sel_outline [] PROGMEM = {
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
};
// ------------------ end generated bitmaps from image2cpp ---------------------------------
const int NUM_ITEMS = 6; // number of items in the list and also the number of screenshots and screenshots with QR codes (other screens)
const int MAX_ITEM_LENGTH = 20; // maximum characters for the item name
char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = { // array with item names
{ "Back" },
{ "Restart" },
{ "Alarm" },
{ "LED" },
{ "TEST" },
{ "Set time" }
};
// note - when changing the order of items above, make sure the other arrays referencing bitmaps
// also have the same order, for example array "bitmap_icons" for icons, and other arrays for screenshots and QR codes
#define piezo 5
#define LED 9
#define rst 13
#define BUTTON_UP_PIN 12 // pin for UP button
#define BUTTON_SELECT_PIN 11 // pin for SELECT button
#define BUTTON_DOWN_PIN 10// pin for DOWN button
#define DHTPIN 8
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
int button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
int button_select_clicked = 0; // same as above
int button_down_clicked = 0; // same as above
int selected = 0;
int alarmh = 0;
int alarmm = 0;
int alarms = 0;
int alarm = 0;
int alarmRadi = 0;
int seth = 0;
int setm = 0;
int item_selected = 0; // which item in the menu is selected
int item_sel_previous; // previous item - used in the menu screen to draw the item before the selected one
int item_sel_next; // next item - used in the menu screen to draw next item after the selected one
int current_screen = 1; // 0 = menu, 1 = after menu
void setup() {
u8g.setColorIndex(1); // set the color to white
// define pins for buttons
// INPUT_PULLUP means the button is HIGH when not pressed, and LOW when pressed
// since it´s connected between some pin and GND
pinMode(BUTTON_UP_PIN, INPUT_PULLUP); // up button
pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP); // select button
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP); // down button
pinMode(piezo, OUTPUT);
pinMode(rst, OUTPUT);
digitalWrite(rst, HIGH);
pinMode(LED, OUTPUT);
rtc.begin();
dht.begin();
noTone(piezo);
}
void loop() {
DateTime now = rtc.now();
int year = now.year();
int month = now.month();
int day = now.day();
int hour = now.hour();
int minute = now.minute();
int second = now.second();
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (alarmh == hour && alarmm == minute && alarm == 1){
digitalWrite(piezo, HIGH);
tone(piezo, 1600);
digitalWrite(LED, HIGH);
alarmRadi = 1;
}
if(alarmRadi == 1 && (digitalRead(BUTTON_UP_PIN) == LOW || digitalRead(BUTTON_DOWN_PIN) == LOW || digitalRead(BUTTON_SELECT_PIN) == LOW)){
digitalWrite(piezo, LOW);
noTone(piezo);
digitalWrite(LED, LOW);
alarmRadi = 0;
alarm = 0;
}
if (current_screen == 0) { // MENU SCREEN
// up and down buttons only work for the menu screen
if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) { // up button clicked - jump to previous menu item
item_selected = item_selected - 1; // select previous item
button_up_clicked = 1; // set button to clicked to only perform the action once
if (item_selected < 0) { // if first item was selected, jump to last item
item_selected = NUM_ITEMS-1;
}
if(selected == 0){
selected = 5;
selected = selected +1;
}
selected = selected -1;
}
else if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) { // down button clicked - jump to next menu item
item_selected = item_selected + 1; // select next item
button_down_clicked = 1; // set button to clicked to only perform the action once
if (item_selected >= NUM_ITEMS) { // last item was selected, jump to first menu item
item_selected = 0;
}
if(selected == 5){
selected = 0;
selected = selected -1;
}
selected = selected +1;
}
if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
}
if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
button_down_clicked = 0;
}
}
if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) { // select button clicked, jump between screens
button_select_clicked = 1; // set button to clicked to only perform the action once
if (current_screen == 0) {current_screen = 1;} // menu items screen --> after menu
else if(current_screen == 1 && selected == 2){current_screen = 2;} // set minutes in alarm
else {current_screen = 0;} // after menu --> menu items screen
}
if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) { // unclick
button_select_clicked = 0;
}
item_sel_previous = item_selected - 1;
if (item_sel_previous < 0) {item_sel_previous = NUM_ITEMS - 1;} // prošli će biti ispod prvog = učiniti ga zadnjim
item_sel_next = item_selected + 1;
if (item_sel_next >= NUM_ITEMS) {item_sel_next = 0;} // idući item će biti zadnji = učiniti ga prvim
u8g.firstPage(); // potrebno za crtanje stranica sa u8g librariem
do {
if (current_screen == 0) { // MENU SCREEN
// selected item background
u8g.drawBitmapP(0, 22, 128/8, 21, bitmap_item_sel_outline);
// draw previous item as icon + label
u8g.setFont(u8g_font_7x14);
u8g.drawStr(25, 15, menu_items[item_sel_previous]);
u8g.drawBitmapP( 4, 2, 16/8, 16, bitmap_icons[item_sel_previous]);
// draw selected item as icon + label in bold font
u8g.setFont(u8g_font_7x14B);
u8g.drawStr(25, 15+20+2, menu_items[item_selected]);
u8g.drawBitmapP( 4, 24, 16/8, 16, bitmap_icons[item_selected]);
// draw next item as icon + label
u8g.setFont(u8g_font_7x14);
u8g.drawStr(25, 15+20+20+2+2, menu_items[item_sel_next]);
u8g.drawBitmapP( 4, 46, 16/8, 16, bitmap_icons[item_sel_next]);
// draw scrollbar background
u8g.drawBitmapP(128-8, 0, 8/8, 64, bitmap_scrollbar_background);
// draw scrollbar handle
u8g.drawBox(125, 64/NUM_ITEMS * item_selected, 3, 64/NUM_ITEMS);
}
else if (current_screen == 1) { // nakon menu screenovi
if(selected == 0){
u8g.setFont(u8g_font_9x15);
u8g.drawStr(0, 10, (String(now.month()) + String("/") + String(now.day()) + String("/") + String(now.year())).c_str());
u8g.drawStr(28, 25, (String(now.hour()) + String(":") + String(now.minute()) + String(":") + String(now.second())).c_str());
u8g.setFont(u8g_font_cu12);
u8g.drawStr(0, 45, F("Temp: "));
u8g.drawStr(50, 45, String(temperature).c_str());
u8g.drawStr(80, 45, F(" \xB0" "C"));
u8g.drawStr(0, 60, F("Humidity: "));
u8g.drawStr(70, 60, String(humidity).c_str());
u8g.drawStr(100, 60, F(" %"));
if(digitalRead(BUTTON_UP_PIN) == LOW){
if(alarm == 0){
alarm = alarm + 1;
digitalWrite(LED, HIGH);
delay(1000);
digitalWrite(LED, LOW);
}
}
if(digitalRead(BUTTON_UP_PIN) == LOW){
if(alarm == 1){
alarm = alarm - 1;
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
}
}
if(alarm == 0){
u8g.drawStr(95, 11, F("OFF"));
}
if(alarm == 1){
u8g.drawStr(95, 11, F(" ON"));
}
}
if(selected == 1){
digitalWrite(rst, LOW);
}
if(selected == 2){
u8g.setFont(u8g_font_10x20r);
u8g.drawStr(43, 33, (String(alarmh) + String(":") + String(alarmm)).c_str());
if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0) && (digitalRead(BUTTON_DOWN_PIN) == HIGH)) {
alarmh = alarmh + 1;
button_up_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (alarmh > 23) {
alarmh = 0;
}
}
if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
}
if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0) && (digitalRead(BUTTON_UP_PIN) == HIGH)) {
alarmh = alarmh - 1;
button_down_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (alarmh < 0) {
alarmh = 23;
}
}
if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
button_down_clicked = 0;
}
}
if(selected == 3){
digitalWrite(LED, HIGH);
u8g.setFont(u8g_font_cu12);
u8g.drawStr(128/8, 32, F("Testing ..."));
if(digitalRead(BUTTON_SELECT_PIN) == LOW)
digitalWrite(LED, LOW);
}
if(selected == 4){
digitalWrite(piezo, HIGH);
tone(piezo, 1600);
u8g.setFont(u8g_font_cu12);
u8g.drawStr(128/8, 32, F("Testing ..."));
if(digitalRead(BUTTON_SELECT_PIN) == LOW){
digitalWrite(piezo, LOW);
noTone(piezo);
digitalWrite(piezo,HIGH);
}
}
if(selected == 5){
u8g.setFont(u8g_font_10x20r);
u8g.drawStr(43, 23, (String(seth) + String(":") + String(setm)).c_str());
if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0) && (digitalRead(BUTTON_DOWN_PIN) == HIGH)) {
seth = seth + 1;
button_up_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (seth > 23) {
seth = 0;
}
}
if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
}
if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0) && (digitalRead(BUTTON_UP_PIN) == HIGH)) {
seth = seth - 1;
button_down_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (seth < 0) {
seth = 23;
}
}
if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
button_down_clicked = 0;
}
}
}
else if(current_screen == 2){
if(selected == 2){
u8g.setFont(u8g_font_10x20r);
u8g.drawStr(43, 33, (String(alarmh) + String(":") + String(alarmm)).c_str());
if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0) && (digitalRead(BUTTON_DOWN_PIN) == HIGH)) {
alarmm = alarmm + 1;
button_up_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (alarmm > 59) {
alarmm = 0;
alarmh = alarmh + 1;
if(alarmh >23)
alarmh = 0;
}
}
if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
}
if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0) && (digitalRead(BUTTON_UP_PIN) == HIGH)) {
alarmm = alarmm - 1;
button_down_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (alarmm < 0) {
alarmm = 59;
alarmh = alarmh-1;
if(alarmh <0)
alarmh = 23;
}
}
if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
button_down_clicked = 0;
}
}
if(item_selected == 4){
u8g.setFont(u8g_font_10x20r);
u8g.drawStr(43, 23, (String(seth) + String(":") + String(setm)).c_str());
if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0) && (digitalRead(BUTTON_DOWN_PIN) == HIGH)) {
setm = setm + 1;
button_up_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (setm > 59) {
setm = 0;
seth = seth + 1;
if(seth >23)
seth = 0;
}
}
if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
}
if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0) && (digitalRead(BUTTON_UP_PIN) == HIGH)) {
setm = setm - 1;
button_down_clicked = 1; // samo da se jednom učini ako je tipka stisnuta
if (setm < 0) {
setm = 59;
seth = seth-1;
if(seth <0)
seth = 23;
}
}
if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) { // unclick
button_down_clicked = 0;
}
}
}
}
while ( u8g.nextPage() ); // potrebno za crtanje stranica sa u8g librariem
}
uno1:A5.2
uno1:A4.2
uno1:AREF
uno1:GND.1
uno1:13
uno1:12
uno1:11
uno1:10
uno1:9
uno1:8
uno1:7
uno1:6
uno1:5
uno1:4
uno1:3
uno1:2
uno1:1
uno1:0
uno1:IOREF
uno1:RESET
uno1:3.3V
uno1:5V
uno1:GND.2
uno1:GND.3
uno1:VIN
uno1:A0
uno1:A1
uno1:A2
uno1:A3
uno1:A4
uno1:A5
ssd1:GND
ssd1:VCC
ssd1:SCL
ssd1:SDA
dht1:VCC
dht1:SDA
dht1:NC
dht1:GND
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
bz1:1
bz1:2
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW
led2:A
led2:C