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 new file mode 100644 index 0000000..e147920 --- /dev/null +++ b/docs/Assignments/week_14_interface_application_programming/interface_application_programming/interface_application_programming.md @@ -0,0 +1,57 @@ +# interface_application_programming + +For this week I wanna make use of the Oled display on the controller I designed +![alt text](image.png) + +I've seen a lot of small devices have GUI's using these displays like this. and I've always been interested in making one of these. + +![alt text](image-1.png) +Credits: https://www.youtube.com/watch?v=HVHVkKt-ldc + +I am going to use that video and try to make a library out of it so it is modular and easy to use for other people. + +I first started out going to their description and downloading their program to upload to my esp. I quickly realized this code was outdated and broken. In the meantime a new library was released and he was using the older one. So I am trying to follow his video along with the newer library. + + + + +## Creating the graphics +The guy in the video used photopea to create the graphics since you can easily export them as bitmaps and bitmaps can instantly be shown on the display using the screen's library + +![alt text](image-3.png) +He first started out making the menu components each in different layers + +For now I am going to use his graphics since I am porting the program to a new library. + + +## Updating to the new library +I first opened an example of the new library (u8g2). In there I needed to select the screen I used. +![alt text](image-4.png) +If you don't know which screen you have it's best to give AI this list and describe your screen as best as you can and ask which one it thinks it is. + +After I uploaded the code this popped up. +![alt text](image-5.png) +So it worked! + + +Now it's time to patch up the old program. +I first copied the display initializer and updated the library include. +![alt text](image-6.png) + +Then I got a lot of compile errors at the drawbitmap function +![alt text](image-7.png) +I went into the reference of the library and searched for a similar function. + +![alt text](image-8.png) +Luckily I found one and the only thing I needed to do was remove a `P` at each of these function calls and pray nothing in the parameters of the function changed. + +![alt text](image-9.png) +After that it successfully uploaded and now it works! + +![alt text](image-10.png) + + +## Using the joysticks +I wanna use the joysticks to control the menu. Because at this time I don't have any way to control it. + +https://www.tinytronics.nl/en/displays/oled/0.96-inch-oled-display-128*64-pixels-blue-i2c diff --git a/src/controller/drone controller/platformio.ini b/src/controller/drone controller/platformio.ini index 13f448f..0adf078 100644 --- a/src/controller/drone controller/platformio.ini +++ b/src/controller/drone controller/platformio.ini @@ -12,8 +12,10 @@ platform = espressif32 board = lolin_c3_mini framework = arduino +lib_deps = adafruit/Adafruit SSD1306@^2.5.13 [env:Xiao_c3] board = seeed_xiao_esp32c3 framework = arduino platform = espressif32 +lib_deps = adafruit/Adafruit SSD1306@^2.5.13 diff --git a/src/controller/drone controller/src/main.cpp b/src/controller/drone controller/src/main.cpp index 0f709a5..7c7ba1d 100644 --- a/src/controller/drone controller/src/main.cpp +++ b/src/controller/drone controller/src/main.cpp @@ -2,19 +2,12 @@ #include #include -// declarations -int normalizePot(int pin, int minValue); -int mapPot(int normalizedValue); -int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin); -void espNow(); -void readAllMultiPlexer(); -void espNowLoop(); - const int MAXPWMVALUE = 1000; const int MINPWMVALUE = 2000; const uint8_t broadcastAddress[] = {0x8C, 0xBF, 0xEA, 0xCC, 0x8E, 0x5C}; -// Define the struct that will be sent +//=====================================================================================// +// Struct declarations typedef struct struct_message { int PWMCH1; @@ -26,35 +19,51 @@ struct_message JoystickData; // declare the struct as JoystickData esp_now_peer_info_t peerInfo; // create a class object of the ESPNow class +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 +}; + +//=====================================================================================// +// declarations +int normalizePot(int pin, int minValue); +int mapPot(int normalizedValue); +int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin); +void espNow(); +void readAllMultiPlexer(); +void espNowLoop(); +void printPWMValues(); +int digitalReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin); +hardJoystickValues GUIParser(); +void MUXSetup(); + + + void setup() { espNow(); + MUXSetup(); // Setup the multiplexer Serial.begin(9600); - pinMode(D3, OUTPUT); - pinMode(D6, OUTPUT); - pinMode(D7, OUTPUT); - pinMode(D8, OUTPUT); - pinMode(D9, OUTPUT); - pinMode(D0, INPUT); } void loop() { + //Debugging + // readAllMultiPlexer(); + // printPWMValues(); + + // Set values to send 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 - Serial.print("PWMCH1: "); - Serial.println(JoystickData.PWMCH1); - Serial.print(" PWMCH2: "); - Serial.println(JoystickData.PWMCH2); - Serial.print(" PWMCH3: "); - Serial.println(JoystickData.PWMCH3); - Serial.print(" PWMCH4: "); - Serial.println(JoystickData.PWMCH4); - + + GUIParser(); espNowLoop(); delay(10); // delay to avoid hammering the radio and to save power/heat } @@ -89,6 +98,16 @@ int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD digitalWrite(D8, addressD); return analogRead(pin); } +//For some reason the digitalRead function does not work with the multiplexer. Maybe because the Resistance is too high. Even though analogRead returns 4095 +int digitalReadMultiPlexer(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 digitalRead(pin); +} void espNow() { // Set device as a Wi-Fi Station @@ -111,6 +130,71 @@ void espNow() } } +void espNowLoop(){ + // Send message via ESP-NOW + esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&JoystickData, sizeof(JoystickData)); + if (result == ESP_OK) + { + // Serial.println("Sent with success"); + } + else + { + // Serial.println("Error sending the data"); + } +} + +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 +} + +///////////////////////////////////////////// +// Debugging Functions // +///////////////////////////////////////////// + + void readAllMultiPlexer() { // we counting in binary @@ -148,15 +232,15 @@ void readAllMultiPlexer() Serial.println(analogReadMultiPlexer(1, 1, 1, 1, A0)); } -void espNowLoop(){ - // Send message via ESP-NOW - esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&JoystickData, sizeof(JoystickData)); - if (result == ESP_OK) - { - // Serial.println("Sent with success"); - } - else - { - // Serial.println("Error sending the data"); - } + +void printPWMValues() +{ + Serial.print("PWMCH1: "); + Serial.print(JoystickData.PWMCH1); + Serial.print(" PWMCH2: "); + Serial.print(JoystickData.PWMCH2); + Serial.print(" PWMCH3: "); + Serial.print(JoystickData.PWMCH3); + Serial.print(" PWMCH4: "); + Serial.println(JoystickData.PWMCH4); } \ No newline at end of file