#include <Arduino.h>
#include "U8g2lib.h"
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0); // [full framebuffer, size = 1024 bytes]
// all the arrays below are generated from images using Image Magick
// scroll down to see the actual code
// 'bulb', 16x16px
const unsigned char icon_bitmap_bulb [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0xc8, 0x13, 0x20, 0x04, 0x10, 0x08, 0x90, 0x09, 0x16, 0x69,
0x20, 0x05, 0x20, 0x05, 0xc8, 0x13, 0x44, 0x22, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0x00, 0x00
};
// 'vibrate', 16x16px
const unsigned char icon_bitmap_vibrate [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x47, 0x24, 0x24, 0x28, 0x14, 0x24, 0x24,
0x22, 0x44, 0x24, 0x24, 0x28, 0x14, 0x24, 0x24, 0xe2, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'speaker', 16x16px
const unsigned char icon_bitmap_speaker [] PROGMEM = {
0x00, 0x00, 0x80, 0x01, 0x40, 0x21, 0x20, 0x41, 0x1c, 0x49, 0x04, 0x51, 0x02, 0x55, 0x02, 0x55,
0x02, 0x55, 0x04, 0x51, 0x1c, 0x49, 0x20, 0x41, 0x40, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 144)
const unsigned char* bitmap_icons[3] = {
icon_bitmap_bulb,
icon_bitmap_speaker,
icon_bitmap_vibrate
};
// 'scrollbar_background', 8x64px
const unsigned char bitmap_scrollbar_background [] PROGMEM = {
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
0x00, 0x40, 0x00, 0x00,
};
// 'item_select_outline', 128x21px
const unsigned char bitmap_item_select_outline [] PROGMEM = {
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF8, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
};
// ------------------ end generated bitmaps from image2cpp ---------------------------------
const int NUM_ITEMS_MENU = 3; // number of items in the list and also the number of screenshots and screenshots with QR codes (other screens)
const int MAX_ITEM_LENGTH_MENU = 20; // maximum characters for the item name
char menu_items_menu [NUM_ITEMS_MENU] [MAX_ITEM_LENGTH_MENU] = { // array with item names
{ "Colour" },
{ "Sound" },
{ "Motion" }
};
const int NUM_ITEMS_COLOUR_SETTING = 4;
const int MAX_ITEM_LENGTH_COLOUR_SETTING = 20;
char menu_items_colour_setting [NUM_ITEMS_COLOUR_SETTING][MAX_ITEM_LENGTH_COLOUR_SETTING] = { // array with item names
{"No Colour"},
{"Red"},
{"Green"},
{"Blue"}
};
const int NUM_ITEMS_SOUND_SETTING = 2;
const int MAX_ITEM_LENGTH_SOUND_SETTING = 20;
char menu_items_sound_setting [NUM_ITEMS_SOUND_SETTING][MAX_ITEM_LENGTH_SOUND_SETTING] = { // array with item names
{"Recorded"},
{"Level"}
};
const int NUM_ITEMS_MOTION_SETTING = 2;
const int MAX_ITEM_LENGTH_MOTION_SETTING = 20;
char menu_items_motion_setting [NUM_ITEMS_MOTION_SETTING][MAX_ITEM_LENGTH_MOTION_SETTING] = { // array with item names
{"Start"},
{"Stop"}
};
// 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 BUTTON_UP_PIN 12 // pin for UP button
#define BUTTON_SELECT_PIN 8 // pin for SELECT button
#define BUTTON_DOWN_PIN 4 // pin for DOWN button
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 item_select = 0;
int item_select_main_menu = 0; // which item in the main menu is selected
int item_select_setting = 0; // which item in the setting menu is selected
int item_select_previous; // previous item - used in the menu screen to draw the item before the selected one
int item_select_next; // next item - used in the menu screen to draw next item after the selected one
int current_screen = 0; // 0 = menu, 1 = screenshot, 2 = qr
char saved_trig, saved_default, saved_menu_option;
void setup() {
Serial.begin(9600);
u8g2.setColorIndex(1); // set the color to white
u8g2.begin();
u8g2.setBitmapMode(1);
// 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
}
void colourMode() {
}
void soundMode() {
}
void motionMode() {
}
int upDownButtonFunction(int NUM_ITEMS) {
// 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_select = item_select - 1; // select previous item
button_up_clicked = 1; // set button to clicked to only perform the action once
if (item_select < 0) { // if first item was selected, jump to last item
item_select = NUM_ITEMS - 1;
}
}
else if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) { // down button clicked - jump to next menu item
item_select = item_select + 1; // select next item
button_down_clicked = 1; // set button to clicked to only perform the action once
if (item_select >= NUM_ITEMS) { // last item was selected, jump to first menu item
item_select = 0;
}
}
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;
}
return item_select;
}
void loop() {
if (current_screen == 0) { // MENU SCREEN
item_select_main_menu = upDownButtonFunction(NUM_ITEMS_MENU);
}
else if (current_screen == 1) {
item_select_setting = upDownButtonFunction(NUM_ITEMS_MENU);
}
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 --> setting screen
}
else if (current_screen == 1) {
current_screen = 0; // setting screen --> execute screen
}
}
if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) { // unclick
button_select_clicked = 0;
}
// set correct values for the previous and next items
item_select_previous = item_select_main_menu - 1;
if (item_select_previous < 0) {
item_select_previous = NUM_ITEMS_MENU - 1; // previous item would be below first = make it the last
}
item_select_next = item_select_main_menu + 1;
if (item_select_next >= NUM_ITEMS_MENU) {
item_select_next = 0; // next item would be after last = make it the first
}
u8g2.clearBuffer(); // clear buffer for storing display content in RAM
if (current_screen == 0) { // MENU SCREEN
// selected item background
u8g2.drawXBMP(0, 22, 128, 21, bitmap_item_select_outline);
// draw previous item as icon + label
u8g2.setFont(u8g_font_7x14);
u8g2.drawStr(25, 15, menu_items_menu[item_select_previous]);
u8g2.drawXBMP( 4, 2, 16, 16, bitmap_icons[item_select_previous]);
// draw selected item as icon + label in bold font
u8g2.setFont(u8g_font_7x14B);
u8g2.drawStr(25, 15 + 20 + 2, menu_items_menu[item_select_main_menu]);
u8g2.drawXBMP( 4, 24, 16, 16, bitmap_icons[item_select_main_menu]);
// Serial.println(menu_items_menu[item_select_main_menu]);
// draw next item as icon + label
u8g2.setFont(u8g_font_7x14);
u8g2.drawStr(25, 15 + 20 + 20 + 2 + 2, menu_items_menu[item_select_next]);
u8g2.drawXBMP( 4, 46, 16, 16, bitmap_icons[item_select_next]);
// draw scrollbar background
u8g2.drawXBMP(128 - 8, 0, 8, 64, bitmap_scrollbar_background);
// draw scrollbar handle
u8g2.drawBox(125, 64 / NUM_ITEMS_MENU * item_select_main_menu, 3, 64 / NUM_ITEMS_MENU);
}
else if (current_screen == 1) { // SETTING STIMULI HERE
// draw selected item as icon + label in bold font
u8g2.setFont(u8g_font_7x14B);
u8g2.drawStr(25, 15, menu_items_menu[item_select_main_menu]);
u8g2.drawXBMP( 4, 2, 16, 16, bitmap_icons[item_select_main_menu]);
if (menu_items_menu[item_select_main_menu][0] == 'C'){
}else if (menu_items_menu[item_select_main_menu][0] == 'S'){
}else if (menu_items_menu[item_select_main_menu][0] == 'M'){
}
// 0. Colour
// |
// |trigger?
// |--no color/red/green/blue
// 1. Sound
// |
// |trigger?
// |--recorded sound (average value)
// |--decibal level
// 2. Motion
// |
// |trigger?
// |--vibration stop & start
}
else if (current_screen == 2) { // EXECUTE FUNCTION HERE
// 0. Colour
// 1. Sound
// 2. Motion
}
u8g2.sendBuffer(); // send buffer from RAM to display controller
}
Loading
ssd1306
ssd1306