add code to read buttons and to read joystick X axises as 0 or 1

This commit is contained in:
2025-05-01 16:40:03 +02:00
parent d588ab6c6e
commit 2d060cbb15
3 changed files with 178 additions and 35 deletions

View File

@@ -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

View File

@@ -12,8 +12,10 @@
platform = espressif32 platform = espressif32
board = lolin_c3_mini board = lolin_c3_mini
framework = arduino framework = arduino
lib_deps = adafruit/Adafruit SSD1306@^2.5.13
[env:Xiao_c3] [env:Xiao_c3]
board = seeed_xiao_esp32c3 board = seeed_xiao_esp32c3
framework = arduino framework = arduino
platform = espressif32 platform = espressif32
lib_deps = adafruit/Adafruit SSD1306@^2.5.13

View File

@@ -2,19 +2,12 @@
#include <WiFi.h> #include <WiFi.h>
#include <esp_now.h> #include <esp_now.h>
// 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 MAXPWMVALUE = 1000;
const int MINPWMVALUE = 2000; const int MINPWMVALUE = 2000;
const uint8_t broadcastAddress[] = {0x8C, 0xBF, 0xEA, 0xCC, 0x8E, 0x5C}; const uint8_t broadcastAddress[] = {0x8C, 0xBF, 0xEA, 0xCC, 0x8E, 0x5C};
// Define the struct that will be sent //=====================================================================================//
// Struct declarations
typedef struct struct_message typedef struct struct_message
{ {
int PWMCH1; 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 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() void setup()
{ {
espNow(); espNow();
MUXSetup(); // Setup the multiplexer
Serial.begin(9600); Serial.begin(9600);
pinMode(D3, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);
pinMode(D9, OUTPUT);
pinMode(D0, INPUT);
} }
void loop() void loop()
{ {
//Debugging
// readAllMultiPlexer();
// printPWMValues();
// Set values to send // Set values to send
JoystickData.PWMCH1 = mapPot(analogReadMultiPlexer(0, 0, 0, 0, A0)); //Right joystick Y 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.PWMCH2 = mapPot(analogReadMultiPlexer(1, 0, 0, 0, A0)); // Right joystick X
JoystickData.PWMCH3 = mapPot(analogReadMultiPlexer(0, 0, 0, 1, A0)); // left joystick Y JoystickData.PWMCH3 = mapPot(analogReadMultiPlexer(0, 0, 0, 1, A0)); // left joystick Y
JoystickData.PWMCH4 = mapPot(analogReadMultiPlexer(1, 0, 0, 1, A0)); // left joystick X JoystickData.PWMCH4 = mapPot(analogReadMultiPlexer(1, 0, 0, 1, A0)); // left joystick X
Serial.print("PWMCH1: ");
Serial.println(JoystickData.PWMCH1); GUIParser();
Serial.print(" PWMCH2: ");
Serial.println(JoystickData.PWMCH2);
Serial.print(" PWMCH3: ");
Serial.println(JoystickData.PWMCH3);
Serial.print(" PWMCH4: ");
Serial.println(JoystickData.PWMCH4);
espNowLoop(); espNowLoop();
delay(10); // delay to avoid hammering the radio and to save power/heat 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); digitalWrite(D8, addressD);
return analogRead(pin); 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() void espNow()
{ // Set device as a Wi-Fi Station { // 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() void readAllMultiPlexer()
{ {
// we counting in binary // we counting in binary
@@ -148,15 +232,15 @@ void readAllMultiPlexer()
Serial.println(analogReadMultiPlexer(1, 1, 1, 1, A0)); Serial.println(analogReadMultiPlexer(1, 1, 1, 1, A0));
} }
void espNowLoop(){
// Send message via ESP-NOW void printPWMValues()
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&JoystickData, sizeof(JoystickData)); {
if (result == ESP_OK) Serial.print("PWMCH1: ");
{ Serial.print(JoystickData.PWMCH1);
// Serial.println("Sent with success"); Serial.print(" PWMCH2: ");
} Serial.print(JoystickData.PWMCH2);
else Serial.print(" PWMCH3: ");
{ Serial.print(JoystickData.PWMCH3);
// Serial.println("Error sending the data"); Serial.print(" PWMCH4: ");
} Serial.println(JoystickData.PWMCH4);
} }