mirror of
https://gitlab.waag.org/make/fablab/interns/2025/sam.git
synced 2025-08-03 11:54:58 +00:00
add code to read buttons and to read joystick X axises as 0 or 1
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# interface_application_programming
|
||||
|
||||
For this week I wanna make use of the Oled display on the controller I designed
|
||||

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

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

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

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

|
||||
So it worked!
|
||||
|
||||
|
||||
Now it's time to patch up the old program.
|
||||
I first copied the display initializer and updated the library include.
|
||||

|
||||
|
||||
Then I got a lot of compile errors at the drawbitmap function
|
||||

|
||||
I went into the reference of the library and searched for a similar function.
|
||||
|
||||

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

|
||||
After that it successfully uploaded and now it works!
|
||||
|
||||

|
||||
|
||||
|
||||
## 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
|
@@ -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
|
||||
|
@@ -2,19 +2,12 @@
|
||||
#include <WiFi.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 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);
|
||||
}
|
Reference in New Issue
Block a user