#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
// U8GLIB_SSD1306_128X64 u8g(13, 11, 8, 9, 10); // SPI connection
// for SPI connection, use this wiring:
// GND > GND
// VCC > 5V
// SCL > 13
// SDA > 11
// RES > 10
// DC > 9
// CS > 8
const int NUM_MAIN_ITEMS = 10; // number off main menu list
const int MAX_MAIN_ITEM_LENGTH = 20; // max char of main menu
char main_menu_items [NUM_MAIN_ITEMS] [MAX_MAIN_ITEM_LENGTH] = {
{ "GPS" },
{ "LORA" },
{ "Date & Time" },
{ "Battery" },
{ "Position Log" },
{ "Wifi & BT" },
{ "Tag Name & ID" },
{ "About Project" },
{ "dummy2" },
{ "dummy3" }
};
const int NUM_SUB_MENU1 = 3;
const int MAX_SUB_MENU1_LENGTH = 20;
char sub_menu1_items [NUM_SUB_MENU1] [MAX_SUB_MENU1_LENGTH] = {
{ "FIX LOACATION :" },
{ "dummy 1"},
{ "dummy 2"}
};
const int NUM_SUB_MENU2 = 3;
const int MAX_SUB_MENU2_LENGTH = 20;
char sub_menu2_items [NUM_SUB_MENU2] [MAX_SUB_MENU2_LENGTH] = {
{ "Connection Status :" },
{ "Signal Strength :" },
{ "dummy 2" }
};
char lora_status_text[2][10] = {
{ "Connected" },
{ "connecting" }
}
const int NUM_SUB_MENU3 = 3;
const int MAX_SUB_MENU3_LENGTH = 20;
char sub_menu3_items [NUM_SUB_MENU3] [MAX_SUB_MENU3_LENGTH] = {
{ "Date :" },
{ "Time :" },
{ "Sync Date & Time" }
};
const int NUM_SUB_MENU4 = 3;
const int MAX_SUB_MENU4_LENGTH = 20;
char sub_menu4_items [NUM_SUB_MENU4] [MAX_SUB_MENU4_LENGTH] = {
{ "Status :"},
{ "Percentage :" },
{ "Voltage :" }
};
char battery_status_text[3][10] = {
{ "Charging" },
{ "Charged" },
{ "On Battery" }
};
#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 VOLTAGE_READ_PIN A0
//#define LED_PIN 13 // pin for demo mode, use switch or wire to enable or disable demo mode, see more details below
bool button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
bool button_select_clicked = 0; // same as above
bool button_down_clicked = 0; // same as above
bool button_select_long_press = 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 = 0; // 0 = main menu, 1 = submenu1
#define main_menu 0
#define sub_menu1 1
#define sub_menu2 2
#define sub_menu3 3
#define sub_menu4 4
#define sub_menu5 5
#define sub_menu6 6
#define sub_menu7 7
#define sub_menu8 8
int main_menu_item_selected = 0;
int main_menu_item_previous;
int main_menu_item_next;
int select_sampling_time = 2000;
uint32_t last_select_sampling_time;
uint32_t last_analog_read_time;
//int analog_read_sampling_time=200; //sampling each 200ms
//int time_elapsed = 0;
uint32_t last_millis;
// project global variable
int battery_level=99;
int battery_status=0;
float battery_voltage= 12.55;
int read_battery_voltage;
int current_draw;
int read_voltage;
bool wifi_status;
bool bluetooth_status;
int wifi_signal_strength;
void setup() {
Serial.begin(115200);
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()
pinMode(LED_BUILTIN, OUTPUT);
//pinMode(DEMO_PIN, INPUT_PULLUP);
u8g.firstPage();
u8g.setFont(u8g_font_7x14);
u8g.drawStr(25, 15, main_menu_items[1]);
}
void loop() {
char s_battery_level[4];
char s_battery_voltage[6];
//scan for button pressed // in main menu
//if(current_screen == main_menu)
//{
if(digitalRead(BUTTON_UP_PIN) == LOW && button_up_clicked == false) //scan for click event
{
if(current_screen == main_menu)
{
main_menu_item_selected = main_menu_item_selected - 1;
button_up_clicked = true; // 1 execution for 1 click // flag for click event
if (main_menu_item_selected < 0)
{
main_menu_item_selected = NUM_MAIN_ITEMS - 1;
}
}
}
else if(digitalRead(BUTTON_DOWN_PIN) == LOW && button_down_clicked == false)
{
if(current_screen == main_menu)
{
main_menu_item_selected = main_menu_item_selected + 1;
button_down_clicked = true;
if(main_menu_item_selected >= NUM_MAIN_ITEMS)
{
main_menu_item_selected = 0;
}
}
}
else if(digitalRead(BUTTON_SELECT_PIN) == LOW && button_select_clicked == false)
{
if(current_screen == main_menu)
{
if(main_menu_item_selected == 0)
{
current_screen = sub_menu1; //GPS menu
Serial.println("sub_menu1");
}
else if (main_menu_item_selected == 1)
{
current_screen = sub_menu2; //lora menu
Serial.println("sub_menu2");
}
else if (main_menu_item_selected == 2) //date & time
{
current_screen = sub_menu3;
Serial.println("sub_menu3");
//current_screen = sub_menu3; //test menu
}
else if (main_menu_item_selected == 3)
{
current_screen = sub_menu4;
Serial.println("sub_menu4");
}
else if (main_menu_item_selected == 4)
{
current_screen = sub_menu5;
Serial.println("sub_menu5");
}
}
else if (current_screen == sub_menu1)
{
}
else if (current_screen == sub_menu2)
{
}
button_select_clicked = true;
last_select_sampling_time = millis(); //for back to main menu command // hold select button for 2s
}
else if(digitalRead(BUTTON_SELECT_PIN) == LOW && button_select_clicked == true)
{
Serial.print(millis()); Serial.print(" "); Serial.println(millis()-last_select_sampling_time);
if(current_screen == sub_menu1 || current_screen == sub_menu2 || current_screen == sub_menu3 || current_screen == sub_menu4 || current_screen == sub_menu5)
{
if((millis()-last_select_sampling_time)>select_sampling_time) // press select button for 2s for back to main menu
{
Serial.println("Back to main menu");
current_screen = main_menu;
}
}
}
if(digitalRead(BUTTON_UP_PIN) == HIGH && button_up_clicked == true) // clear of flag button up click event
{
button_up_clicked = false;
}
if(digitalRead(BUTTON_DOWN_PIN) == HIGH && button_down_clicked == true) // clear of flag button down click event
{
button_down_clicked = false;
}
if(digitalRead(BUTTON_SELECT_PIN) == HIGH && button_select_clicked == true)
{
button_select_clicked = false;
}
//}
//display correction of next and previous value
if (current_screen == main_menu)
{
main_menu_item_previous = main_menu_item_selected - 1;
main_menu_item_next = main_menu_item_selected + 1;
if (main_menu_item_previous < 0) {main_menu_item_previous = NUM_MAIN_ITEMS - 1;}
if (main_menu_item_next>=NUM_MAIN_ITEMS) {main_menu_item_next=0;}
}
// drawing procesure using u8glib // "picture loop" procedure from library
u8g.firstPage();
do {
if (current_screen == main_menu)
{
u8g.setFont(u8g_font_7x14); // draw the first line text
u8g.drawStr(25, 15, main_menu_items[main_menu_item_previous]);
u8g.setFont(u8g_font_7x14B); // draw the middle line text
u8g.drawStr(25, 15+20+2, main_menu_items[main_menu_item_selected]);
u8g.setFont(u8g_font_7x14); // draw the last line text
u8g.drawStr(25, 15+20+20+2+2, main_menu_items[main_menu_item_next]);
}
else if (current_screen == sub_menu1) //GPS MENU
{
u8g.setFont(u8g_font_7x14B); // draw the middle line text
u8g.drawStr(5, 10, main_menu_items[main_menu_item_selected]);
u8g.setFont(u8g_font_baby);
u8g.drawStr(5, 20, sub_menu1_items[0]);
}
else if (current_screen == sub_menu2) //lora menu
{
u8g.setFont(u8g_font_7x14B); // draw the middle line text
u8g.drawStr(5, 10, main_menu_items[main_menu_item_selected]);
u8g.setFont(u8g_font_baby);
u8g.drawStr(5, 20, sub_menu2_items[0]);
}
else if (current_screen == sub_menu3)
{
}
else if (current_screen == sub_menu4) //sub menu battery
{
u8g.setFont(u8g_font_7x14B);
u8g.drawStr(5, 10, main_menu_items[main_menu_item_selected]); //print title page
u8g.setFont(u8g_font_baby);
u8g.drawStr(10, 20, sub_menu4_items[0]); //print battery status label
u8g.drawStr(15, 28, battery_status_text[battery_status]); //print battery actual stat
u8g.drawStr(10, 36, sub_menu4_items[1]); //print percentage label
u8g.drawStr(15, 44, s_battery_level); u8g.drawStr(40, 44, "%"); // print actual percentage
u8g.drawStr(10, 52, sub_menu4_items[2]); //print voltage label
u8g.drawStr(15, 60, s_battery_voltage); u8g.drawStr(40, 60, "V"); //print actual voltage
}
}
while ( u8g.nextPage() );
// end of drawing procedure from u8glib
itoa(battery_level, s_battery_level, 10);
dtostrf(battery_voltage, 5, 2, s_battery_voltage);
//Serial.println(s_battery_level);
int read_analog_sampling_time = 1000; //read analog sampling time
int time_elepased_analog_read = millis()-last_analog_read_time;
if (time_elepased_analog_read > read_analog_sampling_time)
{
int analog_read = analogRead(VOLTAGE_READ_PIN);
read_voltage = analog_read;
last_analog_read_time = millis();
//Serial.println(analog_read);
}
//test led toogle every blinktime (ms)
int blinktime=500;
int time_elapsed = millis() - last_millis;
if(time_elapsed < blinktime){
digitalWrite(LED_BUILTIN, HIGH);
}
else if(time_elapsed>=blinktime && time_elapsed<blinktime*2){
digitalWrite(LED_BUILTIN, LOW);
}
else
{
last_millis = millis();
}
}