diff --git a/docs/Assignments/week_14_interface_application_programming/interface_application_programming/interface_application_programming.md b/docs/Assignments/week_14_interface_application_programming/interface_application_programming/interface_application_programming.md index a4ec2da..cd0f96a 100644 --- a/docs/Assignments/week_14_interface_application_programming/interface_application_programming/interface_application_programming.md +++ b/docs/Assignments/week_14_interface_application_programming/interface_application_programming/interface_application_programming.md @@ -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 ![alt text](image.png) @@ -102,324 +102,324 @@ A portion of this code was taken from the machining week group project. But what ![alt text](image-11.png) ??? - ```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 + ```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 - #include - #include - #include - U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); + #include + #include + #include + #include + 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 - - } // 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 - 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; + 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 } - } - 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 - // selected item background - u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline); + // 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; + } + } - // 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]); + 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 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() - { - 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 - } + // 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 - // 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) + u8g2.firstPage(); // required for page drawing mode for u8g library + do { - // Define deadzone threshold - const int deadzone = 120; + if (current_screen == 0) { // MENU SCREEN - // 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; + // selected item background + u8g2.drawBitmap(0, 22, 128/8, 21, bitmap_item_sel_outline); - // 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 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]); - // 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 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]); - 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); - } + // 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]); - int mapPot(int normalizedValue) - { - return map(normalizedValue, 400, 2500, MINPWMVALUE, MAXPWMVALUE); // map the normalized value to the PWM range - } - ``` + // 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 + + + } + + 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) https://www.tinytronics.nl/en/displays/oled/0.96-inch-oled-display-128*64-pixels-blue-i2c