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:
@@ -101,325 +101,325 @@ A portion of this code was taken from the machining week group project. But what
|
||||
|
||||

|
||||
|
||||
???
|
||||
```cpp
|
||||
// simple project using Arduino UNO and 128x64 OLED Display to display a menu
|
||||
// created by upir, 2022
|
||||
// youtube channel: https://www.youtube.com/upir_upir
|
||||
??? Code
|
||||
```cpp
|
||||
// simple project using Arduino UNO and 128x64 OLED Display to display a menu
|
||||
// created by upir, 2022
|
||||
// youtube channel: https://www.youtube.com/upir_upir
|
||||
|
||||
// YOUTUBE VIDEO: https://youtu.be/HVHVkKt-ldc
|
||||
// WOKWI PROJECT: https://wokwi.com/projects/353101459130291201
|
||||
// YOUTUBE VIDEO: https://youtu.be/HVHVkKt-ldc
|
||||
// WOKWI PROJECT: https://wokwi.com/projects/353101459130291201
|
||||
|
||||
// links from the video:
|
||||
// Flipper Zero menu - https://docs.flipperzero.one/basics/control#M5BZO
|
||||
// WOKWI start project progress bar - https://wokwi.com/projects/300867986768527882
|
||||
// image2cpp - https://javl.github.io/image2cpp/
|
||||
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
|
||||
// Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz
|
||||
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
|
||||
// Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le
|
||||
// Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9
|
||||
// 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 documentation: https://github.com/olikraus/u8glib/wiki/userreference
|
||||
// Photopea (online Photoshop-like tool): https://www.photopea.com/
|
||||
// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
|
||||
// Push buttons - https://s.click.aliexpress.com/e/_DmXS8B9
|
||||
// links from the video:
|
||||
// Flipper Zero menu - https://docs.flipperzero.one/basics/control#M5BZO
|
||||
// WOKWI start project progress bar - https://wokwi.com/projects/300867986768527882
|
||||
// image2cpp - https://javl.github.io/image2cpp/
|
||||
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
|
||||
// Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz
|
||||
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
|
||||
// Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le
|
||||
// Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9
|
||||
// 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 documentation: https://github.com/olikraus/u8glib/wiki/userreference
|
||||
// Photopea (online Photoshop-like tool): https://www.photopea.com/
|
||||
// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
|
||||
// Push buttons - https://s.click.aliexpress.com/e/_DmXS8B9
|
||||
|
||||
// Related videos:
|
||||
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
|
||||
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
|
||||
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
|
||||
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
|
||||
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
|
||||
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
|
||||
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
|
||||
// Related videos:
|
||||
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
|
||||
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
|
||||
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
|
||||
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
|
||||
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
|
||||
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
|
||||
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <U8g2lib.h>
|
||||
#include <Wire.h>
|
||||
#include <Graphics.h>
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||
#include <Arduino.h>
|
||||
#include <U8g2lib.h>
|
||||
#include <Wire.h>
|
||||
#include <Graphics.h>
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||
|
||||
//=====================================================================================//
|
||||
// Struct declarations
|
||||
typedef struct struct_message
|
||||
{
|
||||
int PWMCH1;
|
||||
int PWMCH2;
|
||||
int PWMCH3;
|
||||
int PWMCH4;
|
||||
} struct_message;
|
||||
struct_message JoystickData; // declare the struct as JoystickData
|
||||
//=====================================================================================//
|
||||
// Struct declarations
|
||||
typedef struct struct_message
|
||||
{
|
||||
int PWMCH1;
|
||||
int PWMCH2;
|
||||
int PWMCH3;
|
||||
int PWMCH4;
|
||||
} struct_message;
|
||||
struct_message JoystickData; // declare the struct as JoystickData
|
||||
|
||||
struct hardJoystickValues
|
||||
{
|
||||
int LXU; // Left joystick X axis up
|
||||
int LXD; // Left joystick X axis down
|
||||
int RXU; // Right joystick X axis up
|
||||
int RXD; // Right joystick X axis down
|
||||
};
|
||||
hardJoystickValues JoystickDataHard; // declare the struct as JoystickDataHard
|
||||
//=====================================================================================//
|
||||
//declarations
|
||||
void GUITestLoop();
|
||||
void MUXSetup();
|
||||
hardJoystickValues GUIParser();
|
||||
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin);
|
||||
int mapPot(int normalizedValue);
|
||||
struct hardJoystickValues
|
||||
{
|
||||
int LXU; // Left joystick X axis up
|
||||
int LXD; // Left joystick X axis down
|
||||
int RXU; // Right joystick X axis up
|
||||
int RXD; // Right joystick X axis down
|
||||
};
|
||||
hardJoystickValues JoystickDataHard; // declare the struct as JoystickDataHard
|
||||
//=====================================================================================//
|
||||
//declarations
|
||||
void GUITestLoop();
|
||||
void MUXSetup();
|
||||
hardJoystickValues GUIParser();
|
||||
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin);
|
||||
int mapPot(int normalizedValue);
|
||||
|
||||
|
||||
// Controller declarations
|
||||
const int MAXPWMVALUE = 1000;
|
||||
const int MINPWMVALUE = 2000;
|
||||
// Controller declarations
|
||||
const int MAXPWMVALUE = 1000;
|
||||
const int MINPWMVALUE = 2000;
|
||||
|
||||
// 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 MAX_ITEM_LENGTH = 20; // maximum characters for the item name
|
||||
// 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 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" }
|
||||
};
|
||||
// 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
|
||||
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" }
|
||||
};
|
||||
// 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 JoystickDataHard.LXU // pin for UP button
|
||||
#define BUTTON_SELECT_PIN buttonRight// pin for SELECT button
|
||||
#define BUTTON_DOWN_PIN JoystickDataHard.LXD // pin for DOWN button
|
||||
#define BUTTON_UP_PIN JoystickDataHard.LXU // pin for UP button
|
||||
#define BUTTON_SELECT_PIN buttonRight// pin for SELECT 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_select_clicked = 0; // same as above
|
||||
int button_down_clicked = 0; // same as above
|
||||
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_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 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
|
||||
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_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 = 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_delay = 0; // demo mode delay = used to slow down the screen switching
|
||||
|
||||
bool buttonRight;
|
||||
bool buttonLeft;
|
||||
void setup() {
|
||||
u8g2.begin();
|
||||
u8g2.setColorIndex(1); // set the color to white
|
||||
MUXSetup(); // Setup the multiplexer
|
||||
bool buttonRight;
|
||||
bool buttonLeft;
|
||||
void setup() {
|
||||
u8g2.begin();
|
||||
u8g2.setColorIndex(1); // set the color to white
|
||||
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
|
||||
|
||||
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();
|
||||
}
|
||||
} // end demo mode section
|
||||
|
||||
|
||||
if (current_screen == 0) { // MENU SCREEN
|
||||
|
||||
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
|
||||
// up and down buttons only work for the menu screen
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if ((BUTTON_UP_PIN == HIGH) && (button_up_clicked == 1)) { // unclick
|
||||
button_up_clicked = 0;
|
||||
}
|
||||
if ((BUTTON_DOWN_PIN == HIGH) && (button_down_clicked == 1)) { // unclick
|
||||
button_down_clicked = 0;
|
||||
}
|
||||
|
||||
} // end demo mode section
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
// up and down buttons only work for the menu screen
|
||||
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;
|
||||
}
|
||||
}
|
||||
// selected item background
|
||||
u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline);
|
||||
|
||||
if ((BUTTON_UP_PIN == HIGH) && (button_up_clicked == 1)) { // unclick
|
||||
button_up_clicked = 0;
|
||||
}
|
||||
if ((BUTTON_DOWN_PIN == HIGH) && (button_down_clicked == 1)) { // unclick
|
||||
button_down_clicked = 0;
|
||||
}
|
||||
// draw previous item as icon + label
|
||||
u8g2.setFont(u8g_font_7x14);
|
||||
u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
|
||||
u8g2.drawBitmap( 4, 2, 16/8, 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.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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
else if (current_screen == 1) { // SCREENSHOTS SCREEN
|
||||
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_screenshots[item_selected]); // draw screenshot
|
||||
}
|
||||
if ((BUTTON_SELECT_PIN == HIGH) && (button_select_clicked == 1)) { // unclick
|
||||
button_select_clicked = 0;
|
||||
else if (current_screen == 2) { // QR SCREEN
|
||||
u8g2.drawBitmap( 0, 0, 128/8, 64, bitmap_qr_codes[item_selected]); // draw qr code screenshot
|
||||
}
|
||||
|
||||
// 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
|
||||
} while ( u8g2.nextPage() ); // required for page drawing mode with u8g library
|
||||
|
||||
|
||||
u8g2.firstPage(); // required for page drawing mode for u8g library
|
||||
do {
|
||||
}
|
||||
|
||||
if (current_screen == 0) { // MENU SCREEN
|
||||
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
|
||||
}
|
||||
|
||||
// selected item background
|
||||
u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline);
|
||||
// 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(){
|
||||
|
||||
// draw previous item as icon + label
|
||||
u8g2.setFont(u8g_font_7x14);
|
||||
u8g2.drawStr(25, 15, menu_items[item_sel_previous]);
|
||||
u8g2.drawBitmap( 4, 2, 16/8, 16, bitmap_icons[item_sel_previous]);
|
||||
// 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)
|
||||
|
||||
// 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]);
|
||||
// Define deadzone threshold
|
||||
const int deadzone = 120;
|
||||
|
||||
// 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]);
|
||||
// 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;
|
||||
|
||||
// draw scrollbar background
|
||||
u8g2.drawBitmap(128-8, 0, 8/8, 64, bitmap_scrollbar_background);
|
||||
// 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;
|
||||
|
||||
// draw scrollbar handle
|
||||
u8g2.drawBox(125, 64/NUM_ITEMS * item_selected, 3, 64/NUM_ITEMS);
|
||||
// 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
|
||||
}
|
||||
|
||||
// draw upir logo
|
||||
u8g2.drawBitmap(128-16-4, 64-4, 16/8, 4, upir_logo);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
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
|
||||
}
|
||||
```
|
||||
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)
|
||||
https://www.tinytronics.nl/en/displays/oled/0.96-inch-oled-display-128*64-pixels-blue-i2c
|
||||
|
Reference in New Issue
Block a user