#include "U8g2lib.h"
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0); // [full framebuffer, size = 1024 bytes]
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C (rotation, [reset [, clock, data]]) [full framebuffer, size = 1024 bytes]
//U8G2_SSD1306_128X64_NONAME_F_2ND_HW_I2C(rotation, [reset]) [full framebuffer, size = 1024 bytes]
// all the arrays below are generated from images using Image Magick
// scroll down to see the actual code
//#define MenuMain_width 38
//#define MenuMain_height 38
const unsigned char MenuMain_bits[] PROGMEM = {
0xFC, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x03, 0x00,
0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03,
0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00,
0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30,
0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00,
0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03,
0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00,
0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30,
0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00,
0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03,
0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00,
0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x30,
0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x0F, };
//#define Slider_width 128
//#define Slider_height 8
const unsigned char Slider_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
//#define SliderThing_width 8
//#define SliderThing_height 3
const unsigned char SliderThing_bits[] PROGMEM = {
0xFF, 0x81, 0xFF, };
//#define MenuSide_width 38
//#define MenuSide_height 38
const unsigned char MenuSide_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x0F, 0x02, 0x00,
0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02,
0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10,
0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00,
0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02,
0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10,
0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00,
0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02,
0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x10,
0xFC, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, };
//icons
//#define frequency_width 32
//#define frequency_height 32
const unsigned char frequency [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20,
0xf4, 0xff, 0xff, 0x2f, 0x14, 0x00, 0x00, 0x28, 0x14, 0x00, 0x00, 0x28, 0x14, 0x00, 0x02, 0x28,
0x14, 0x00, 0x02, 0x28, 0x14, 0x01, 0x02, 0x28, 0x14, 0x01, 0x02, 0x28, 0x94, 0x02, 0x05, 0x28,
0x94, 0x02, 0x05, 0x28, 0x54, 0x82, 0x84, 0x28, 0x54, 0x84, 0x44, 0x29, 0x54, 0x84, 0x48, 0x2a,
0x34, 0x84, 0x48, 0x2a, 0x14, 0x48, 0x28, 0x2c, 0x14, 0x48, 0x28, 0x28, 0x14, 0x48, 0x28, 0x28,
0x14, 0x50, 0x10, 0x28, 0x14, 0x50, 0x00, 0x28, 0x14, 0x20, 0x00, 0x28, 0x14, 0x20, 0x00, 0x28,
0x14, 0x20, 0x00, 0x28, 0x14, 0x20, 0x00, 0x28, 0x14, 0x00, 0x00, 0x28, 0xf4, 0xff, 0xff, 0x2f,
0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'bruteforce', 32x32px
const unsigned char bruteforce [] PROGMEM = {
0x00, 0xf0, 0x0f, 0x00, 0xaa, 0x08, 0x10, 0x55, 0x00, 0xe4, 0x27, 0x00, 0x00, 0x12, 0x48, 0x00,
0xf0, 0x09, 0x90, 0x0f, 0x08, 0x05, 0xa0, 0x10, 0xe4, 0x15, 0xa8, 0x27, 0x14, 0x35, 0xac, 0x28,
0x14, 0x75, 0xae, 0x28, 0x14, 0x65, 0xa6, 0x28, 0x14, 0x05, 0xa0, 0x28, 0x14, 0x05, 0xa0, 0x28,
0x14, 0x49, 0x92, 0x28, 0x14, 0x52, 0x4a, 0x28, 0x14, 0x52, 0x4a, 0x28, 0x14, 0xf4, 0x2f, 0x28,
0x14, 0x24, 0x24, 0x28, 0x14, 0xfc, 0x3f, 0x28, 0x14, 0x12, 0x48, 0x28, 0x14, 0x21, 0x84, 0x28,
0x94, 0xc0, 0x03, 0x29, 0x94, 0x88, 0x11, 0x29, 0x94, 0x88, 0x11, 0x29, 0x94, 0x88, 0x11, 0x29,
0x94, 0x08, 0x10, 0x29, 0xfe, 0xff, 0xff, 0x7f, 0x02, 0x20, 0x04, 0x40, 0x02, 0xe0, 0x07, 0x40,
0x02, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00
};
// 'jammer', 32x32px
const unsigned char jammer [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x01, 0x08, 0x00, 0x90, 0x00, 0x10,
0x00, 0x88, 0x04, 0x12, 0x00, 0x48, 0x04, 0x22, 0x00, 0x44, 0x22, 0x24, 0x00, 0x24, 0x22, 0x44,
0x00, 0x24, 0x22, 0x44, 0x00, 0x24, 0x62, 0x44, 0x00, 0x24, 0x62, 0x44, 0x00, 0x44, 0x62, 0x24,
0x00, 0x44, 0x64, 0x22, 0x00, 0x88, 0x60, 0x10, 0x00, 0x88, 0x60, 0x10, 0x00, 0x10, 0xf1, 0x08,
0x00, 0x10, 0xf0, 0x00, 0x00, 0x20, 0xf0, 0x01, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0xff, 0xff, 0x1f,
0x04, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x40, 0xf2, 0x9f, 0x0d, 0x40, 0xf2, 0x9f, 0x8d, 0x47,
0x02, 0x80, 0x8d, 0x47, 0xf2, 0x9f, 0x8d, 0x47, 0xf2, 0x9f, 0x0d, 0x40, 0x02, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x40, 0xfe, 0xff, 0xff, 0x7f, 0xf0, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00
};
// 'rx', 32x32px
const unsigned char rx [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x40, 0x02, 0x20, 0x00, 0x48, 0x04, 0x50, 0x00, 0x88, 0x04, 0x90, 0x00, 0x90, 0x08,
0x08, 0x01, 0x10, 0x09, 0x08, 0x02, 0x10, 0x09, 0x08, 0x84, 0x11, 0x09, 0x08, 0xc8, 0x10, 0x09,
0x08, 0x70, 0x90, 0x08, 0x08, 0x20, 0x88, 0x08, 0x08, 0x40, 0x40, 0x04, 0x08, 0x80, 0x40, 0x04,
0x10, 0x00, 0x21, 0x02, 0x10, 0x00, 0x02, 0x02, 0x20, 0x00, 0x04, 0x01, 0x40, 0x00, 0x08, 0x00,
0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x80, 0xe1, 0x03, 0x00,
0x40, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00,
0x08, 0x80, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};
//#define empty_width 32
//#define empty_height 32
const unsigned char empty [] PROGMEM = {
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xC0, 0x05, 0x00, 0x00, 0xA0,
0x09, 0x00, 0x00, 0x90, 0x11, 0x00, 0x00, 0x88, 0x21, 0x00, 0x00, 0x84,
0x41, 0x00, 0x00, 0x82, 0x81, 0x00, 0x00, 0x81, 0x01, 0x01, 0x80, 0x80,
0x01, 0x02, 0x40, 0x80, 0x01, 0x04, 0x20, 0x80, 0x01, 0x08, 0x10, 0x80,
0x01, 0x10, 0x08, 0x80, 0x01, 0x20, 0x04, 0x80, 0x01, 0x40, 0x02, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x80,
0x01, 0x20, 0x04, 0x80, 0x01, 0x10, 0x08, 0x80, 0x01, 0x08, 0x10, 0x80,
0x01, 0x04, 0x20, 0x80, 0x01, 0x02, 0x40, 0x80, 0x01, 0x01, 0x80, 0x80,
0x81, 0x00, 0x00, 0x81, 0x41, 0x00, 0x00, 0x82, 0x21, 0x00, 0x00, 0x84,
0x11, 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x90, 0x05, 0x00, 0x00, 0xA0,
0x03, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, };
const int NUM_ITEMS = 7; // 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
{ "Frequence Analyzer" },
{ "Receive Code" },
{ "Transmit Code" },
{ "Bruteforce" },
{ "Sub Ghz Jammer" },
{ "Wifi Deauther" },
{ "Deep Sleep" }
};
const unsigned char* bitmap_icons[NUM_ITEMS] = {
frequency,
rx,
empty,
bruteforce,
jammer,
empty,
empty
};
// 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_LEFT_PIN 12 // pin for LEFT button
#define BUTTON_SELECT_PIN 8 // pin for SELECT button
#define BUTTON_RIGHT_PIN 4 // pin for RIGHT button
int animation = 0;
int button_left_clicked = 0; // only perform action when button is clicked, and wait until another press
int button_select_clicked = 0; // same as above
int button_right_clicked = 0; // same as above
int item_selected = 0; // which item in the menu is selected
int correctShift (int item_selected, int shift) {
// set correct values for the previous and next items
int out = item_selected + shift;
if (out < 0) {out = NUM_ITEMS - 1;} // previous item would be below first = make it the last
if (out >= NUM_ITEMS) {out = 0;} // next item would be after last = make it the first
return out;
}
void shiftRight(int speed, int item_selected) {
animation = 1;
for(int i=0; i<speed; i++) {
u8g2.clearBuffer();
//Slider
u8g2.drawXBMP(0, 0, 128, 8, Slider_bits);
u8g2.drawXBMP(((120/(NUM_ITEMS-1))*item_selected)+map(i, 0, speed, 0, 120/(NUM_ITEMS-1)), 0, 8, 3, SliderThing_bits);
//Old Main menu
u8g2.drawXBMP(45-map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(48-map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[item_selected]);
//New right menu
u8g2.drawXBMP(165-map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(168-map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, 2)]);
//New Main menu
u8g2.drawXBMP(105-map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(108-map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, 1)]);
//Exiting left menu
u8g2.drawXBMP(-15-map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(-12-map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, -1)]);
//Text
u8g2.setFont(u8g_font_7x14B);
u8g2.drawStr(((126-u8g2.getStrWidth(menu_items[item_selected]))/2)+1-map(i, 0, speed, 0, 128), 63, menu_items[item_selected]);
u8g2.drawStr(((126-u8g2.getStrWidth(menu_items[correctShift(item_selected, 1)]))/2)+129-map(i, 0, speed, 0, 128), 63, menu_items[correctShift(item_selected, 1)]);
u8g2.sendBuffer(); // send buffer from RAM to display controller
}
animation = 0;
}
void shiftLeft(int speed, int item_selected) {
animation = 1;
for(int i=0; i<speed; i++) {
u8g2.clearBuffer();
//Slider
u8g2.drawXBMP(0, 0, 128, 8, Slider_bits);
u8g2.drawXBMP(((120/(NUM_ITEMS-1))*item_selected)-map(i, 0, speed, 0, 120/(NUM_ITEMS-1)), 0, 8, 3, SliderThing_bits);
//Old Main menu
u8g2.drawXBMP(45+map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(48+map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[item_selected]);
//New left menu
u8g2.drawXBMP(-75+map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(-72+map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, -2)]);
//New Main menu
u8g2.drawXBMP(-15+map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(-12+map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, -1)]);
//Exiting right menu
u8g2.drawXBMP(105+map(i, 0, speed, 0, 60), 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(108+map(i, 0, speed, 0, 60), 10, 32, 32, bitmap_icons[correctShift(item_selected, 1)]);
//Text
u8g2.setFont(u8g_font_7x14B);
u8g2.drawStr(((126-u8g2.getStrWidth(menu_items[item_selected]))/2)+1+map(i, 0, speed, 0, 128), 63, menu_items[item_selected]);
u8g2.drawStr(((126-u8g2.getStrWidth(menu_items[correctShift(item_selected, -1)]))/2)-127+map(i, 0, speed, 0, 128), 63, menu_items[correctShift(item_selected, -1)]);
u8g2.sendBuffer(); // send buffer from RAM to display controller
}
animation = 0;
}
void setup() {
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_LEFT_PIN, INPUT_PULLUP); // left button
pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP); // select button
pinMode(BUTTON_RIGHT_PIN, INPUT_PULLUP); // right button
}
void loop() {
// left and right buttons only work for the menu screen
if ((digitalRead(BUTTON_LEFT_PIN) == LOW) && (button_left_clicked == 0)) { // left button clicked - jump to previous menu item
shiftLeft(20, item_selected);
item_selected = item_selected - 1; // select previous item
button_left_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_RIGHT_PIN) == LOW) && (button_right_clicked == 0)) { // right button clicked - jump to next menu item
shiftRight(20, item_selected);
item_selected = item_selected + 1; // select next item
button_right_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_LEFT_PIN) == HIGH) && (button_left_clicked == 1)) { // unclick
button_left_clicked = 0;
}
if ((digitalRead(BUTTON_RIGHT_PIN) == HIGH) && (button_right_clicked == 1)) { // unclick
button_right_clicked = 0;
}
u8g2.clearBuffer();
if(!animation) {
//Slider
u8g2.drawXBMP(0, 0, 128, 8, Slider_bits);
u8g2.drawXBMP((120/(NUM_ITEMS-1))*item_selected, 0, 8, 3, SliderThing_bits);
//Main menu
u8g2.drawXBMP(45, 7, 38, 38, MenuMain_bits);
u8g2.drawXBMP(48, 10, 32, 32, bitmap_icons[item_selected]);
//Side menu
u8g2.drawXBMP(105, 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(108, 10, 32, 32, bitmap_icons[correctShift(item_selected, 1)]);
u8g2.drawXBMP(-15, 7, 38, 38, MenuSide_bits);
u8g2.drawXBMP(-12, 10, 32, 32, bitmap_icons[correctShift(item_selected, -1)]);
//Text
u8g2.setFont(u8g_font_7x14B);
u8g2.drawStr(((126-u8g2.getStrWidth(menu_items[item_selected]))/2)+1, 63, menu_items[item_selected]);
}
u8g2.sendBuffer();
}