#include "U8glib.h"
#include "SevSeg.h"
#include "pitches.h"
SevSeg sevseg;
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
// all the arrays below are generated from images using image2cpp website
// scroll down to see the actual code
const unsigned char upir_logo [] PROGMEM = { // this is another way how to define images, using binary notation
B00010101, B11010111,
B00010101, B01000101,
B00010101, B10010110,
B00011001, B00010101
};
// ' icon_settings', 16x16px
const unsigned char bitmap_icon_settings [] PROGMEM = {
0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0x01, 0xe0, 0x01, 0xe6, 0x01, 0xfe, 0x03, 0xfe, 0x07, 0x7c,
0x0e, 0x78, 0x1c, 0xc0, 0x39, 0x80, 0x73, 0x00, 0x76, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x00, 0x00
};
// ' compress_icon', 16x16px
const unsigned char bitmap_compress_icon [] PROGMEM = {
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x00, 0x18, 0x42, 0x5a, 0x6a, 0x5a,
0x56, 0x7e, 0x6a, 0x42, 0x56, 0x7e, 0x6a, 0x7e, 0x56, 0x7e, 0x6a, 0x7e, 0x7e, 0x7e, 0x00, 0x00
};
// ' indent_icon', 16x16px
const unsigned char bitmap_indent_icon [] PROGMEM = {
0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x05, 0xa0, 0x03, 0xc0,
0x01, 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x38, 0x1c, 0x60, 0x06, 0x38, 0x1c, 0x0f, 0xf0, 0x00, 0x00
};
// ' cam_icon', 16x16px
const unsigned char bitmap_cam_icon [] PROGMEM = {
0x00, 0x00, 0x07, 0x00, 0x1f, 0xf8, 0x20, 0x04, 0x58, 0x02, 0x59, 0xe2, 0x43, 0x32, 0x46, 0x9a,
0x45, 0x0a, 0x44, 0x0a, 0x46, 0x1a, 0x43, 0x32, 0x41, 0xe2, 0x20, 0x04, 0x1f, 0xf8, 0x00, 0x00
};
// ' auto_icon', 16x16px
const unsigned char bitmap_auto_icon [] PROGMEM = {
0x00, 0x00, 0x03, 0xc0, 0x0e, 0x70, 0x18, 0x18, 0x31, 0x8c, 0x22, 0x44, 0x62, 0x46, 0x43, 0xc2,
0x42, 0x42, 0x62, 0x46, 0x22, 0x44, 0x30, 0x0c, 0x18, 0x18, 0x0e, 0x70, 0x03, 0xc0, 0x00, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 384)
const unsigned char* bitmap_icons[5] = {
bitmap_icon_settings,
bitmap_compress_icon,
bitmap_indent_icon,
bitmap_cam_icon,
bitmap_auto_icon
};
// '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
};
const int NUM_ITEMS = 5; // 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
{ "Settings" },
{ "Compress" },
{ "Indent" },
{ "Image" },
{ "Auto Mode" }
};
// 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 53 // pin for UP button
#define BUTTON_SELECT_PIN 49 // pin for SELECT button
#define BUTTON_DOWN_PIN 51 // 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_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 = menu, 1 = screenshot, 2 = qr
const int buttonPin = 11; // Change to the actual pin your button is connected to
const int ledPin = 10; // Change to the actual pin your LED is connected to
int buttonState = 0; // variable for reading the pushbutton status
#define BUZZER_PIN 12
int melody[] = {
NOTE_E5, NOTE_D5, NOTE_FS4, NOTE_GS4,
NOTE_CS5, NOTE_B4, NOTE_D4, NOTE_E4,
NOTE_B4, NOTE_A4, NOTE_CS4, NOTE_E4,
NOTE_A4
};
int durations[] = {
8, 8, 4, 4,
8, 8, 4, 4,
8, 8, 4, 4,
2
};
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(BUZZER_PIN, OUTPUT);
byte numDigits = 1;
byte digitPins[] = {};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
bool resistorsOnSegments = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
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;
}
}
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 ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) { // unclick
button_up_clicked = 0;
if (current_screen == 0) {current_screen = 1;} // menu items screen --> screenshots screen
else {current_screen = 0;} // qr codes screen --> menu items screen
}
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 ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) { // unclick
button_select_clicked = 0;
}
// set correct values for the previous and next items
item_sel_previous = item_selected - 1;
if (item_sel_previous < 0) {item_sel_previous = NUM_ITEMS - 1;} // previous item would be below first = make it the last
item_sel_next = item_selected + 1;
if (item_sel_next >= NUM_ITEMS) {item_sel_next = 0;} // next item would be after last = make it the first
u8g.firstPage(); // required for page drawing mode for u8g library
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);
// draw upir logo
u8g.drawBitmapP(128-16-4, 64-4, 16/8, 4, upir_logo);
}
else if (current_screen == 1) { // SCREENSHOTS SCREEN
//u8g.drawBitmapP( 0, 0, 128/8, 64, bitmap_screenshots[item_selected]); // draw screenshot
digitalWrite(ledPin, HIGH);
}
} while ( u8g.nextPage() ); // required for page drawing mode with u8g library
}