#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <ezButton.h>
//U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R1);
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
#define SW_RIGHT_JOYSTICK 4
#define SW_LEFT_JOYSTICK 5
#define SW_TURBO 6
#define RJY_PIN A0 // Right Joystick Y pin
#define RJX_PIN A1 // Right Joystick X pin
#define LJY_PIN A2 // Left Joystick Y pin
#define LJX_PIN A3 // Left Joystick X pin
ezButton buttonLJ(SW_LEFT_JOYSTICK);
ezButton buttonRJ(SW_RIGHT_JOYSTICK);
ezButton buttonTurbo(SW_TURBO);
int RJXValue = 0; // To store value of the X axis
int RJYValue = 0; // To store value of the Y axis
int LJXValue = 0; // To store value of the X axis
int LJYValue = 0; // To store value of the Y axis
int buttonLJValue = 0;
int buttonRJValue = 0;
int buttonTurboValue = 0;
// '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_sel_outline', 128x21px
const unsigned char bitmap_item_sel_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,
};
// 'icon_3dcube', 16x16px
const unsigned char bitmap_icon_3dcube[] PROGMEM = {
0x00,
0x00,
0x80,
0x01,
0xE0,
0x06,
0x98,
0x18,
0x86,
0x60,
0x8A,
0x50,
0xA2,
0x45,
0x82,
0x40,
0xA2,
0x44,
0x82,
0x40,
0xA2,
0x45,
0x8A,
0x50,
0x86,
0x60,
0x98,
0x18,
0xE0,
0x06,
0x80,
0x01,
};
// 'icon_battery', 16x16px
const unsigned char bitmap_icon_battery[] PROGMEM = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xFC,
0x1F,
0x02,
0x20,
0xDA,
0x66,
0xDA,
0x66,
0xDA,
0x66,
0x02,
0x20,
0xFC,
0x1F,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
// 'icon_dashboard', 16x16px
const unsigned char bitmap_icon_dashboard[] PROGMEM = {
0xE0,
0x07,
0x18,
0x18,
0x84,
0x24,
0x0A,
0x40,
0x12,
0x50,
0x21,
0x80,
0xC1,
0x81,
0x45,
0xA2,
0x41,
0x82,
0x81,
0x81,
0x05,
0xA0,
0x02,
0x40,
0xD2,
0x4B,
0xC4,
0x23,
0x18,
0x18,
0xE0,
0x07,
};
// 'icon_fireworks', 16x16px
const unsigned char bitmap_icon_fireworks[] PROGMEM = {
0x00,
0x00,
0x00,
0x10,
0x00,
0x29,
0x08,
0x10,
0x08,
0x00,
0x36,
0x00,
0x08,
0x08,
0x08,
0x08,
0x00,
0x00,
0x00,
0x63,
0x00,
0x00,
0x00,
0x08,
0x20,
0x08,
0x50,
0x00,
0x20,
0x00,
0x00,
0x00,
};
// 'icon_gps_speed', 16x16px
const unsigned char bitmap_icon_gps_speed[] PROGMEM = {
0x00,
0x00,
0xC0,
0x0F,
0x00,
0x10,
0x80,
0x27,
0x00,
0x48,
0x00,
0x53,
0x60,
0x54,
0xE0,
0x54,
0xE0,
0x51,
0xE0,
0x43,
0xE0,
0x03,
0x50,
0x00,
0xF8,
0x00,
0x04,
0x01,
0xFE,
0x03,
0x00,
0x00,
};
// 'icon_knob_over_oled', 16x16px
const unsigned char bitmap_icon_knob_over_oled[] PROGMEM = {
0x00,
0x00,
0xF8,
0x0F,
0xC8,
0x0A,
0xD8,
0x0D,
0x88,
0x0A,
0xF8,
0x0F,
0xC0,
0x01,
0x80,
0x00,
0x00,
0x00,
0x90,
0x04,
0x92,
0x24,
0x04,
0x10,
0x00,
0x80,
0x01,
0x40,
0x00,
0x00,
0x00,
0x00,
};
// 'icon_parksensor', 16x16px
const unsigned char bitmap_icon_parksensor[] PROGMEM = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x3F,
0x00,
0x44,
0x00,
0xA4,
0x00,
0x9F,
0x00,
0x00,
0x81,
0x30,
0xA1,
0x48,
0xA9,
0x4B,
0xA9,
0x30,
0xA0,
0x00,
0x80,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
// 'icon_turbo', 16x16px
const unsigned char bitmap_icon_turbo[] PROGMEM = {
0x00,
0x70,
0xE0,
0x8F,
0x18,
0x80,
0x04,
0x80,
0x02,
0x80,
0xC2,
0x8F,
0x21,
0x72,
0x51,
0x05,
0x91,
0x44,
0x51,
0x45,
0x21,
0x42,
0xC2,
0x21,
0x02,
0x20,
0x04,
0x10,
0x18,
0x0C,
0xE0,
0x03,
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 384)
const unsigned char* bitmap_icons[8] = {
bitmap_icon_3dcube,
bitmap_icon_battery,
bitmap_icon_dashboard,
bitmap_icon_fireworks,
bitmap_icon_gps_speed,
bitmap_icon_knob_over_oled,
bitmap_icon_parksensor,
bitmap_icon_turbo
};
const int NUM_ITEMS = 8; // 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
{ "3D Cube" },
{ "Battery" },
{ "Dashboard" },
{ "Fireworks" },
{ "GPS Speed" },
{ "Big Knob" },
{ "Park Sensor" },
{ "Turbo Gauge" }
};
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
void setup() {
Serial.begin(9600);
// set debounce time to 50 milliseconds
buttonLJ.setDebounceTime(50);
buttonRJ.setDebounceTime(50);
buttonTurbo.setDebounceTime(50);
// display config
//u8g2.setColorIndex(1); // set the color to white
u8g2.begin();
//u8g2.setContrast(255);
//u8g2.setBitmapMode(1);
}
void loop() {
dispaly();
buttonLJ.loop();
buttonRJ.loop();
buttonTurbo.loop();
// Read the button value
buttonLJValue = buttonLJ.getState();
buttonRJValue = buttonRJ.getState();
buttonTurboValue = buttonTurbo.getState();
if (buttonLJ.isPressed()) {
Serial.println("The left joystick button is pressed");
}
if (buttonLJ.isReleased()) {
Serial.println("The left joystick button is released");
}
if (buttonRJ.isPressed()) {
Serial.println("The right joystick button is pressed");
}
if (buttonRJ.isReleased()) {
Serial.println("The right joystick button is released");
}
if (buttonTurbo.isPressed()) {
Serial.println("The turbo joystick button is pressed");
}
if (buttonTurbo.isReleased()) {
Serial.println("The turbo joystick button is released");
}
// read analog X and Y analog values
RJXValue = correctJValue(analogRead(RJX_PIN));
RJYValue = correctJValue(analogRead(RJY_PIN));
LJXValue = correctJValue(analogRead(LJX_PIN));
LJYValue = correctJValue(analogRead(LJY_PIN));
// print data to Serial Monitor on Arduino IDE
Serial.print("LJXValue = ");
Serial.print(LJXValue);
Serial.print(", LJYValue = ");
Serial.print(LJYValue);
Serial.print(", RJXValue = ");
Serial.print(RJXValue);
Serial.print(", RJYValue = ");
Serial.print(RJYValue);
Serial.print(" : buttonLJValue = ");
Serial.print(buttonLJValue);
Serial.print(" : buttonRJValue = ");
Serial.print(buttonRJValue);
Serial.print(" : buttonTurboValue = ");
Serial.println(buttonTurboValue);
delay(200);
}
int correctJValue(int val) {
val = constrain(val, 150, 900);
return map(val, 150, 900, 0, 1023);
}
void dispaly() {
u8g2.clearBuffer(); // clear buffer for storing display content in RAM
drawHeader();
drawMenu();
u8g2.sendBuffer(); // send buffer from RAM to display controller
}
void drawHeader() {
u8g2.setFont(u8g2_font_8x13B_mn);
u8g2.drawStr(57, 20, "12");
u8g2.drawStr(112, 69, "3");
u8g2.drawStr(61, 120, "6");
u8g2.drawStr(9, 69, "9");
}
void drawMenu() {
// 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
// selected item background
//u8g2.drawXBMP(0, 22, 128, 21, bitmap_item_sel_outline);
// // draw previous item as icon + label
// u8g2.setFont(u8g_font_7x14);
// u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
// u8g2.drawXBMP(4, 2, 16, 16, bitmap_icons[item_sel_previous]);
// // draw selected item as icon + label in bold font
// u8g2.setFont(u8g_font_7x14B);
// u8g2.drawStr(25, 15 + 20 + 2, menu_items[item_selected]);
// u8g2.drawXBMP(4, 24, 16, 16, bitmap_icons[item_selected]);
// // draw next item as icon + label
// u8g2.setFont(u8g_font_7x14);
// u8g2.drawStr(25, 15 + 20 + 20 + 2 + 2, menu_items[item_sel_next]);
// u8g2.drawXBMP(4, 46, 16, 16, bitmap_icons[item_sel_next]);
// // draw scrollbar background
u8g2.drawXBMP(128 - 8, 0, 8, 64, bitmap_scrollbar_background);
// // draw scrollbar handle
u8g2.drawBox(50, 128 / NUM_ITEMS * item_selected, 50, 128 / NUM_ITEMS);
}