mirror of
https://gitlab.waag.org/make/fablab/interns/2025/sam.git
synced 2025-08-03 11:54:58 +00:00
styling
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# interface_application_programming
|
# interface and application programming
|
||||||
|
|
||||||
For this week I wanna make use of the Oled display on the controller I designed
|
For this week I wanna make use of the Oled display on the controller I designed
|
||||||

|

|
||||||
@@ -102,324 +102,324 @@ A portion of this code was taken from the machining week group project. But what
|
|||||||

|

|
||||||
|
|
||||||
???
|
???
|
||||||
```cpp
|
```cpp
|
||||||
// simple project using Arduino UNO and 128x64 OLED Display to display a menu
|
// simple project using Arduino UNO and 128x64 OLED Display to display a menu
|
||||||
// created by upir, 2022
|
// created by upir, 2022
|
||||||
// youtube channel: https://www.youtube.com/upir_upir
|
// youtube channel: https://www.youtube.com/upir_upir
|
||||||
|
|
||||||
// YOUTUBE VIDEO: https://youtu.be/HVHVkKt-ldc
|
// YOUTUBE VIDEO: https://youtu.be/HVHVkKt-ldc
|
||||||
// WOKWI PROJECT: https://wokwi.com/projects/353101459130291201
|
// WOKWI PROJECT: https://wokwi.com/projects/353101459130291201
|
||||||
|
|
||||||
// links from the video:
|
// links from the video:
|
||||||
// Flipper Zero menu - https://docs.flipperzero.one/basics/control#M5BZO
|
// Flipper Zero menu - https://docs.flipperzero.one/basics/control#M5BZO
|
||||||
// WOKWI start project progress bar - https://wokwi.com/projects/300867986768527882
|
// WOKWI start project progress bar - https://wokwi.com/projects/300867986768527882
|
||||||
// image2cpp - https://javl.github.io/image2cpp/
|
// image2cpp - https://javl.github.io/image2cpp/
|
||||||
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
|
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
|
||||||
// Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz
|
// Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz
|
||||||
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
|
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
|
||||||
// Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le
|
// Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le
|
||||||
// Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9
|
// Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9
|
||||||
// Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx
|
// Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx
|
||||||
// u8g fonts (fonts available for u8g library): https://nodemcu-build.com/u8g-fonts.php
|
// u8g fonts (fonts available for u8g library): https://nodemcu-build.com/u8g-fonts.php
|
||||||
// u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference
|
// u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference
|
||||||
// Photopea (online Photoshop-like tool): https://www.photopea.com/
|
// Photopea (online Photoshop-like tool): https://www.photopea.com/
|
||||||
// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
|
// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
|
||||||
// Push buttons - https://s.click.aliexpress.com/e/_DmXS8B9
|
// Push buttons - https://s.click.aliexpress.com/e/_DmXS8B9
|
||||||
|
|
||||||
// Related videos:
|
// Related videos:
|
||||||
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
|
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
|
||||||
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
|
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
|
||||||
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
|
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
|
||||||
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
|
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
|
||||||
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
|
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
|
||||||
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
|
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
|
||||||
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
|
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
|
||||||
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <U8g2lib.h>
|
#include <U8g2lib.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <Graphics.h>
|
#include <Graphics.h>
|
||||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||||
|
|
||||||
//=====================================================================================//
|
//=====================================================================================//
|
||||||
// Struct declarations
|
// Struct declarations
|
||||||
typedef struct struct_message
|
typedef struct struct_message
|
||||||
{
|
{
|
||||||
int PWMCH1;
|
int PWMCH1;
|
||||||
int PWMCH2;
|
int PWMCH2;
|
||||||
int PWMCH3;
|
int PWMCH3;
|
||||||
int PWMCH4;
|
int PWMCH4;
|
||||||
} struct_message;
|
} struct_message;
|
||||||
struct_message JoystickData; // declare the struct as JoystickData
|
struct_message JoystickData; // declare the struct as JoystickData
|
||||||
|
|
||||||
struct hardJoystickValues
|
struct hardJoystickValues
|
||||||
{
|
{
|
||||||
int LXU; // Left joystick X axis up
|
int LXU; // Left joystick X axis up
|
||||||
int LXD; // Left joystick X axis down
|
int LXD; // Left joystick X axis down
|
||||||
int RXU; // Right joystick X axis up
|
int RXU; // Right joystick X axis up
|
||||||
int RXD; // Right joystick X axis down
|
int RXD; // Right joystick X axis down
|
||||||
};
|
};
|
||||||
hardJoystickValues JoystickDataHard; // declare the struct as JoystickDataHard
|
hardJoystickValues JoystickDataHard; // declare the struct as JoystickDataHard
|
||||||
//=====================================================================================//
|
//=====================================================================================//
|
||||||
//declarations
|
//declarations
|
||||||
void GUITestLoop();
|
void GUITestLoop();
|
||||||
void MUXSetup();
|
void MUXSetup();
|
||||||
hardJoystickValues GUIParser();
|
hardJoystickValues GUIParser();
|
||||||
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin);
|
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin);
|
||||||
int mapPot(int normalizedValue);
|
int mapPot(int normalizedValue);
|
||||||
|
|
||||||
|
|
||||||
// Controller declarations
|
// Controller declarations
|
||||||
const int MAXPWMVALUE = 1000;
|
const int MAXPWMVALUE = 1000;
|
||||||
const int MINPWMVALUE = 2000;
|
const int MINPWMVALUE = 2000;
|
||||||
|
|
||||||
// Screen declarations
|
// Screen declarations
|
||||||
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 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
|
const int MAX_ITEM_LENGTH = 20; // maximum characters for the item name
|
||||||
|
|
||||||
char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = { // array with item names
|
char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = { // array with item names
|
||||||
{ "3D Cube" },
|
{ "3D Cube" },
|
||||||
{ "Battery" },
|
{ "Battery" },
|
||||||
{ "Dashboard" },
|
{ "Dashboard" },
|
||||||
{ "Fireworks" },
|
{ "Fireworks" },
|
||||||
{ "GPS Speed" },
|
{ "GPS Speed" },
|
||||||
{ "Big Knob" },
|
{ "Big Knob" },
|
||||||
{ "Park Sensor" },
|
{ "Park Sensor" },
|
||||||
{ "Turbo Gauge" }
|
{ "Turbo Gauge" }
|
||||||
};
|
};
|
||||||
// note - when changing the order of items above, make sure the other arrays referencing bitmaps
|
// 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
|
// also have the same order, for example array "bitmap_icons" for icons, and other arrays for screenshots and QR codes
|
||||||
|
|
||||||
#define BUTTON_UP_PIN JoystickDataHard.LXU // pin for UP button
|
#define BUTTON_UP_PIN JoystickDataHard.LXU // pin for UP button
|
||||||
#define BUTTON_SELECT_PIN buttonRight// pin for SELECT button
|
#define BUTTON_SELECT_PIN buttonRight// pin for SELECT button
|
||||||
#define BUTTON_DOWN_PIN JoystickDataHard.LXD // pin for DOWN button
|
#define BUTTON_DOWN_PIN JoystickDataHard.LXD // pin for DOWN button
|
||||||
|
|
||||||
#define DEMO_PIN D0 // pin for demo mode, use switch or wire to enable or disable demo mode, see more details below
|
#define DEMO_PIN D0 // pin for demo mode, use switch or wire to enable or disable demo mode, see more details below
|
||||||
|
|
||||||
|
|
||||||
int button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
|
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_select_clicked = 0; // same as above
|
||||||
int button_down_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_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_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 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
|
int current_screen = 0; // 0 = menu, 1 = screenshot, 2 = qr
|
||||||
|
|
||||||
int demo_mode = 0; // when demo mode is set to 1, it automatically goes over all the screens, 0 = control menu with buttons
|
int demo_mode = 0; // when demo mode is set to 1, it automatically goes over all the screens, 0 = control menu with buttons
|
||||||
int demo_mode_state = 0; // demo mode state = which screen and menu item to display
|
int demo_mode_state = 0; // demo mode state = which screen and menu item to display
|
||||||
int demo_mode_delay = 0; // demo mode delay = used to slow down the screen switching
|
int demo_mode_delay = 0; // demo mode delay = used to slow down the screen switching
|
||||||
|
|
||||||
bool buttonRight;
|
bool buttonRight;
|
||||||
bool buttonLeft;
|
bool buttonLeft;
|
||||||
void setup() {
|
void setup() {
|
||||||
u8g2.begin();
|
u8g2.begin();
|
||||||
u8g2.setColorIndex(1); // set the color to white
|
u8g2.setColorIndex(1); // set the color to white
|
||||||
MUXSetup(); // Setup the multiplexer
|
MUXSetup(); // Setup the multiplexer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
JoystickData.PWMCH1 = mapPot(analogReadMultiPlexer(0, 0, 0, 0, A0)); //Right joystick Y
|
|
||||||
JoystickData.PWMCH2 = mapPot(analogReadMultiPlexer(1, 0, 0, 0, A0)); // Right joystick X
|
|
||||||
JoystickData.PWMCH3 = mapPot(analogReadMultiPlexer(0, 0, 0, 1, A0)); // left joystick Y
|
|
||||||
JoystickData.PWMCH4 = mapPot(analogReadMultiPlexer(1, 0, 0, 1, A0)); // left joystick X
|
|
||||||
buttonRight = abs(analogReadMultiPlexer(0, 0, 1, 0, A0)/4095); // right button
|
|
||||||
buttonLeft = abs(analogReadMultiPlexer(1, 0, 1, 0, A0)/4095); // left button
|
|
||||||
|
|
||||||
JoystickDataHard = GUIParser();
|
|
||||||
GUITestLoop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GUITestLoop(){
|
|
||||||
|
|
||||||
// when pin 13 is LOW (DEMO_PIN), enable demo mode
|
|
||||||
// this could be done either by using a switch
|
|
||||||
// or simply by connecting the wire between pin 13 and GND
|
|
||||||
// (those pins are next to each other)
|
|
||||||
if (digitalRead(DEMO_PIN) == LOW) {
|
|
||||||
demo_mode = 0; // enable demo mode
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
demo_mode = 0; // disable demo mode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (demo_mode == 1) { // when demo mode is active, automatically switch between all the screens and menu items
|
|
||||||
demo_mode_delay++; // increase demo mode delay
|
|
||||||
if (demo_mode_delay > 15) { // after some time, switch to another screen - change this value to make it slower/faster
|
|
||||||
demo_mode_delay = 0;
|
|
||||||
demo_mode_state++; // increase counter
|
|
||||||
if (demo_mode_state >= NUM_ITEMS*3) {demo_mode_state=0;} // jump back to the first screen
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demo_mode_state % 3 == 0) {current_screen = 0; item_selected = demo_mode_state/3; } // menu screen
|
|
||||||
else if (demo_mode_state % 3 == 1) {current_screen = 1; item_selected = demo_mode_state/3;} // screenshots screen
|
|
||||||
else if (demo_mode_state % 3 == 2) {current_screen = 2; item_selected = demo_mode_state/3;} // qr codes screen
|
|
||||||
|
|
||||||
} // end demo mode section
|
|
||||||
|
|
||||||
|
|
||||||
if (current_screen == 0) { // MENU SCREEN
|
void loop() {
|
||||||
|
JoystickData.PWMCH1 = mapPot(analogReadMultiPlexer(0, 0, 0, 0, A0)); //Right joystick Y
|
||||||
|
JoystickData.PWMCH2 = mapPot(analogReadMultiPlexer(1, 0, 0, 0, A0)); // Right joystick X
|
||||||
|
JoystickData.PWMCH3 = mapPot(analogReadMultiPlexer(0, 0, 0, 1, A0)); // left joystick Y
|
||||||
|
JoystickData.PWMCH4 = mapPot(analogReadMultiPlexer(1, 0, 0, 1, A0)); // left joystick X
|
||||||
|
buttonRight = abs(analogReadMultiPlexer(0, 0, 1, 0, A0)/4095); // right button
|
||||||
|
buttonLeft = abs(analogReadMultiPlexer(1, 0, 1, 0, A0)/4095); // left button
|
||||||
|
|
||||||
// up and down buttons only work for the menu screen
|
JoystickDataHard = GUIParser();
|
||||||
if ((BUTTON_UP_PIN == LOW) && (button_up_clicked == 0)) { // up button clicked - jump to previous menu item
|
GUITestLoop();
|
||||||
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;
|
|
||||||
|
void GUITestLoop(){
|
||||||
|
|
||||||
|
// when pin 13 is LOW (DEMO_PIN), enable demo mode
|
||||||
|
// this could be done either by using a switch
|
||||||
|
// or simply by connecting the wire between pin 13 and GND
|
||||||
|
// (those pins are next to each other)
|
||||||
|
if (digitalRead(DEMO_PIN) == LOW) {
|
||||||
|
demo_mode = 0; // enable demo mode
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
demo_mode = 0; // disable demo mode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (demo_mode == 1) { // when demo mode is active, automatically switch between all the screens and menu items
|
||||||
|
demo_mode_delay++; // increase demo mode delay
|
||||||
|
if (demo_mode_delay > 15) { // after some time, switch to another screen - change this value to make it slower/faster
|
||||||
|
demo_mode_delay = 0;
|
||||||
|
demo_mode_state++; // increase counter
|
||||||
|
if (demo_mode_state >= NUM_ITEMS*3) {demo_mode_state=0;} // jump back to the first screen
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if ((BUTTON_DOWN_PIN == LOW) && (button_down_clicked == 0)) { // down button clicked - jump to next menu item
|
if (demo_mode_state % 3 == 0) {current_screen = 0; item_selected = demo_mode_state/3; } // menu screen
|
||||||
item_selected = item_selected + 1; // select next item
|
else if (demo_mode_state % 3 == 1) {current_screen = 1; item_selected = demo_mode_state/3;} // screenshots screen
|
||||||
button_down_clicked = 1; // set button to clicked to only perform the action once
|
else if (demo_mode_state % 3 == 2) {current_screen = 2; item_selected = demo_mode_state/3;} // qr codes screen
|
||||||
if (item_selected >= NUM_ITEMS) { // last item was selected, jump to first menu item
|
|
||||||
item_selected = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((BUTTON_UP_PIN == HIGH) && (button_up_clicked == 1)) { // unclick
|
} // end demo mode section
|
||||||
button_up_clicked = 0;
|
|
||||||
}
|
|
||||||
if ((BUTTON_DOWN_PIN == HIGH) && (button_down_clicked == 1)) { // unclick
|
|
||||||
button_down_clicked = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ((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 --> screenshots screen
|
|
||||||
else if (current_screen == 1) {current_screen = 2;} // screenshots screen --> qr codes screen
|
|
||||||
else {current_screen = 0;} // qr codes screen --> menu items screen
|
|
||||||
}
|
|
||||||
if ((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
|
|
||||||
|
|
||||||
|
|
||||||
u8g2.firstPage(); // required for page drawing mode for u8g library
|
|
||||||
do {
|
|
||||||
|
|
||||||
if (current_screen == 0) { // MENU SCREEN
|
if (current_screen == 0) { // MENU SCREEN
|
||||||
|
|
||||||
// selected item background
|
// up and down buttons only work for the menu screen
|
||||||
u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline);
|
if ((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 ((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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// draw previous item as icon + label
|
if ((BUTTON_UP_PIN == HIGH) && (button_up_clicked == 1)) { // unclick
|
||||||
u8g2.setFont(u8g_font_7x14);
|
button_up_clicked = 0;
|
||||||
u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
|
}
|
||||||
u8g2.drawBitmap( 4, 2, 16/8, 16, bitmap_icons[item_sel_previous]);
|
if ((BUTTON_DOWN_PIN == HIGH) && (button_down_clicked == 1)) { // unclick
|
||||||
|
button_down_clicked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 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.drawBitmap( 4, 24, 16/8, 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.drawBitmap( 4, 46, 16/8, 16, bitmap_icons[item_sel_next]);
|
|
||||||
|
|
||||||
// draw scrollbar background
|
|
||||||
u8g2.drawBitmap(128-8, 0, 8/8, 64, bitmap_scrollbar_background);
|
|
||||||
|
|
||||||
// draw scrollbar handle
|
|
||||||
u8g2.drawBox(125, 64/NUM_ITEMS * item_selected, 3, 64/NUM_ITEMS);
|
|
||||||
|
|
||||||
// draw upir logo
|
|
||||||
u8g2.drawBitmap(128-16-4, 64-4, 16/8, 4, upir_logo);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (current_screen == 1) { // SCREENSHOTS SCREEN
|
|
||||||
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_screenshots[item_selected]); // draw screenshot
|
|
||||||
}
|
}
|
||||||
else if (current_screen == 2) { // QR SCREEN
|
|
||||||
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_qr_codes[item_selected]); // draw qr code screenshot
|
|
||||||
}
|
|
||||||
|
|
||||||
} while ( u8g2.nextPage() ); // required for page drawing mode with u8g library
|
|
||||||
|
|
||||||
|
|
||||||
}
|
if ((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 --> screenshots screen
|
||||||
|
else if (current_screen == 1) {current_screen = 2;} // screenshots screen --> qr codes screen
|
||||||
|
else {current_screen = 0;} // qr codes screen --> menu items screen
|
||||||
|
}
|
||||||
|
if ((BUTTON_SELECT_PIN == HIGH) && (button_select_clicked == 1)) { // unclick
|
||||||
|
button_select_clicked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void MUXSetup()
|
// set correct values for the previous and next items
|
||||||
{
|
item_sel_previous = item_selected - 1;
|
||||||
pinMode(D3, OUTPUT); // MUX enable
|
if (item_sel_previous < 0) {item_sel_previous = NUM_ITEMS - 1;} // previous item would be below first = make it the last
|
||||||
pinMode(D6, OUTPUT); // MUX address A
|
item_sel_next = item_selected + 1;
|
||||||
pinMode(D7, OUTPUT); // MUX address B
|
if (item_sel_next >= NUM_ITEMS) {item_sel_next = 0;} // next item would be after last = make it the first
|
||||||
pinMode(D9, OUTPUT); // MUX address C
|
|
||||||
pinMode(D8, OUTPUT); // MUX address D
|
|
||||||
pinMode(A0, INPUT); // MUX input
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to parse joystick data to hard values
|
|
||||||
//If joystick is Up then the value is 1 of var A
|
|
||||||
//If joystick is Down then the value is 1 of var B
|
|
||||||
//If joystick is in the middle A and B are 0
|
|
||||||
hardJoystickValues GUIParser(){
|
|
||||||
|
|
||||||
// Define joystick offsets (calibrated resting values)
|
u8g2.firstPage(); // required for page drawing mode for u8g library
|
||||||
const int offsetPWMCH1 = 1090; // Resting value for PWMCH1 (right joystick Y-axis)
|
do {
|
||||||
const int offsetPWMCH2 = 1072; // Resting value for PWMCH2 (right joystick X-axis)
|
|
||||||
const int offsetPWMCH3 = 1043; // Resting value for PWMCH3 (left joystick X-axis)
|
|
||||||
const int offsetPWMCH4 = 1476; // Resting value for PWMCH4 (left joystick Y-axis)
|
|
||||||
|
|
||||||
// Define deadzone threshold
|
if (current_screen == 0) { // MENU SCREEN
|
||||||
const int deadzone = 120;
|
|
||||||
|
|
||||||
// Adjust joystick values by subtracting offsets
|
// selected item background
|
||||||
int adjustedPWMCH1 = JoystickData.PWMCH1 - offsetPWMCH1;
|
u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline);
|
||||||
int adjustedPWMCH2 = JoystickData.PWMCH2 - offsetPWMCH2;
|
|
||||||
int adjustedPWMCH3 = JoystickData.PWMCH3 - offsetPWMCH3;
|
|
||||||
int adjustedPWMCH4 = JoystickData.PWMCH4 - offsetPWMCH4;
|
|
||||||
|
|
||||||
// Apply deadzone
|
// draw previous item as icon + label
|
||||||
if (abs(adjustedPWMCH1) < deadzone) adjustedPWMCH1 = 0; //abs to avoid negatives
|
u8g2.setFont(u8g_font_7x14);
|
||||||
if (abs(adjustedPWMCH2) < deadzone) adjustedPWMCH2 = 0;
|
u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
|
||||||
if (abs(adjustedPWMCH3) < deadzone) adjustedPWMCH3 = 0;
|
u8g2.drawBitmap( 4, 2, 16/8, 16, bitmap_icons[item_sel_previous]);
|
||||||
if (abs(adjustedPWMCH4) < deadzone) adjustedPWMCH4 = 0;
|
|
||||||
|
|
||||||
// Map joystick values to hard values
|
// draw selected item as icon + label in bold font
|
||||||
int LXU = 0; // Left joystick X axis up
|
u8g2.setFont(u8g_font_7x14B);
|
||||||
int LXD = 0; // Left joystick X axis down
|
u8g2.drawStr(25, 15+20+2, menu_items[item_selected]);
|
||||||
if (adjustedPWMCH1 > 0) {
|
u8g2.drawBitmap( 4, 24, 16/8, 16, bitmap_icons[item_selected]);
|
||||||
LXU = 1; // Joystick is up
|
|
||||||
} else if (adjustedPWMCH1 < 0) {
|
|
||||||
LXD = 1; // Joystick is down
|
|
||||||
}
|
|
||||||
return {LXU, LXD, 0, 0}; // Return the values as a struct
|
|
||||||
}
|
|
||||||
|
|
||||||
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin)
|
// draw next item as icon + label
|
||||||
{
|
u8g2.setFont(u8g_font_7x14);
|
||||||
digitalWrite(D3, LOW);
|
u8g2.drawStr(25, 15+20+20+2+2, menu_items[item_sel_next]);
|
||||||
digitalWrite(D6, addressA);
|
u8g2.drawBitmap( 4, 46, 16/8, 16, bitmap_icons[item_sel_next]);
|
||||||
digitalWrite(D7, addressB);
|
|
||||||
digitalWrite(D9, addressC);
|
|
||||||
digitalWrite(D8, addressD);
|
|
||||||
return analogRead(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mapPot(int normalizedValue)
|
// draw scrollbar background
|
||||||
{
|
u8g2.drawBitmap(128-8, 0, 8/8, 64, bitmap_scrollbar_background);
|
||||||
return map(normalizedValue, 400, 2500, MINPWMVALUE, MAXPWMVALUE); // map the normalized value to the PWM range
|
|
||||||
}
|
// draw scrollbar handle
|
||||||
```
|
u8g2.drawBox(125, 64/NUM_ITEMS * item_selected, 3, 64/NUM_ITEMS);
|
||||||
|
|
||||||
|
// draw upir logo
|
||||||
|
u8g2.drawBitmap(128-16-4, 64-4, 16/8, 4, upir_logo);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (current_screen == 1) { // SCREENSHOTS SCREEN
|
||||||
|
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_screenshots[item_selected]); // draw screenshot
|
||||||
|
}
|
||||||
|
else if (current_screen == 2) { // QR SCREEN
|
||||||
|
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_qr_codes[item_selected]); // draw qr code screenshot
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ( u8g2.nextPage() ); // required for page drawing mode with u8g library
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MUXSetup()
|
||||||
|
{
|
||||||
|
pinMode(D3, OUTPUT); // MUX enable
|
||||||
|
pinMode(D6, OUTPUT); // MUX address A
|
||||||
|
pinMode(D7, OUTPUT); // MUX address B
|
||||||
|
pinMode(D9, OUTPUT); // MUX address C
|
||||||
|
pinMode(D8, OUTPUT); // MUX address D
|
||||||
|
pinMode(A0, INPUT); // MUX input
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to parse joystick data to hard values
|
||||||
|
//If joystick is Up then the value is 1 of var A
|
||||||
|
//If joystick is Down then the value is 1 of var B
|
||||||
|
//If joystick is in the middle A and B are 0
|
||||||
|
hardJoystickValues GUIParser(){
|
||||||
|
|
||||||
|
// Define joystick offsets (calibrated resting values)
|
||||||
|
const int offsetPWMCH1 = 1090; // Resting value for PWMCH1 (right joystick Y-axis)
|
||||||
|
const int offsetPWMCH2 = 1072; // Resting value for PWMCH2 (right joystick X-axis)
|
||||||
|
const int offsetPWMCH3 = 1043; // Resting value for PWMCH3 (left joystick X-axis)
|
||||||
|
const int offsetPWMCH4 = 1476; // Resting value for PWMCH4 (left joystick Y-axis)
|
||||||
|
|
||||||
|
// Define deadzone threshold
|
||||||
|
const int deadzone = 120;
|
||||||
|
|
||||||
|
// Adjust joystick values by subtracting offsets
|
||||||
|
int adjustedPWMCH1 = JoystickData.PWMCH1 - offsetPWMCH1;
|
||||||
|
int adjustedPWMCH2 = JoystickData.PWMCH2 - offsetPWMCH2;
|
||||||
|
int adjustedPWMCH3 = JoystickData.PWMCH3 - offsetPWMCH3;
|
||||||
|
int adjustedPWMCH4 = JoystickData.PWMCH4 - offsetPWMCH4;
|
||||||
|
|
||||||
|
// Apply deadzone
|
||||||
|
if (abs(adjustedPWMCH1) < deadzone) adjustedPWMCH1 = 0; //abs to avoid negatives
|
||||||
|
if (abs(adjustedPWMCH2) < deadzone) adjustedPWMCH2 = 0;
|
||||||
|
if (abs(adjustedPWMCH3) < deadzone) adjustedPWMCH3 = 0;
|
||||||
|
if (abs(adjustedPWMCH4) < deadzone) adjustedPWMCH4 = 0;
|
||||||
|
|
||||||
|
// Map joystick values to hard values
|
||||||
|
int LXU = 0; // Left joystick X axis up
|
||||||
|
int LXD = 0; // Left joystick X axis down
|
||||||
|
if (adjustedPWMCH1 > 0) {
|
||||||
|
LXU = 1; // Joystick is up
|
||||||
|
} else if (adjustedPWMCH1 < 0) {
|
||||||
|
LXD = 1; // Joystick is down
|
||||||
|
}
|
||||||
|
return {LXU, LXD, 0, 0}; // Return the values as a struct
|
||||||
|
}
|
||||||
|
|
||||||
|
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin)
|
||||||
|
{
|
||||||
|
digitalWrite(D3, LOW);
|
||||||
|
digitalWrite(D6, addressA);
|
||||||
|
digitalWrite(D7, addressB);
|
||||||
|
digitalWrite(D9, addressC);
|
||||||
|
digitalWrite(D8, addressD);
|
||||||
|
return analogRead(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mapPot(int normalizedValue)
|
||||||
|
{
|
||||||
|
return map(normalizedValue, 400, 2500, MINPWMVALUE, MAXPWMVALUE); // map the normalized value to the PWM range
|
||||||
|
}
|
||||||
|
```
|
||||||
This is the full code of the screen. The schematic for the pcb can be found in [the final project page](/docs/final_project/final_project.md)
|
This is the full code of the screen. The schematic for the pcb can be found in [the final project page](/docs/final_project/final_project.md)
|
||||||
https://www.tinytronics.nl/en/displays/oled/0.96-inch-oled-display-128*64-pixels-blue-i2c
|
https://www.tinytronics.nl/en/displays/oled/0.96-inch-oled-display-128*64-pixels-blue-i2c
|
||||||
|
Reference in New Issue
Block a user