Update esp32c3-joystick.ino

This commit is contained in:
Ghassan Yusuf 2025-07-14 16:24:17 +03:00
parent 13ffddeb56
commit c2a36bd17f

View File

@ -1,84 +1,304 @@
//========================================================
// Header Include
//========================================================
// Header File
#include <WiFi.h> #include <WiFi.h>
#include "header.h" #include <WiFiManager.h>
#include <FS.h>
#include <SPIFFS.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//======================================================== // Pin definitions (adjust as needed)
// SETUP #define BTN_RED1 0
//======================================================== #define BTN_RED2 1
#define BTN_BLUE1 2
#define BTN_BLUE2 3
#define BTN_CENTER 4 // Use a free GPIO for WiFi reset/config
#define LED_PIN 5
#define MOTOR_PIN 6
#define CONFIG_FILE "/config.json"
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// --- Paste your full logo_bmp[] array here ---
// TAKEONE LOGO (Your existing logo data)
static const unsigned char PROGMEM logo_bmp[] = {
// ... (logo data remains the same) ...
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xce, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x00, 0x00,
0xff, 0xf0, 0x3f, 0x00, 0x7c, 0x3f, 0x8f, 0xfc, 0x1f, 0xff, 0xfb, 0x60, 0x7c, 0x07, 0xc3, 0xff,
0xff, 0xf0, 0x3f, 0x80, 0x7c, 0x7f, 0x8f, 0xfc, 0x1f, 0xff, 0xfe, 0x60, 0x7e, 0x07, 0xc3, 0xff,
0xff, 0xf0, 0x7f, 0x80, 0x7c, 0xff, 0x0f, 0xfc, 0x1f, 0xff, 0xfc, 0xc0, 0x7f, 0x07, 0xc3, 0xff,
0xff, 0xf0, 0x7f, 0xc0, 0x7c, 0xfe, 0x0f, 0xfc, 0x0f, 0xff, 0xf9, 0x80, 0x7f, 0x07, 0xc3, 0xff,
0xff, 0xf0, 0x7f, 0xc0, 0x7d, 0xfc, 0x0f, 0x80, 0x07, 0xff, 0xfb, 0x00, 0x7f, 0x87, 0xc3, 0xe0,
0x1f, 0x80, 0xff, 0xc0, 0x7f, 0xf8, 0x0f, 0x80, 0x07, 0xff, 0xf2, 0x00, 0x7f, 0xc7, 0xc3, 0xe0,
0x1f, 0x80, 0xff, 0xe0, 0x7f, 0xf0, 0x0f, 0xfc, 0x07, 0xff, 0xf4, 0x00, 0x7f, 0xe7, 0xc3, 0xff,
0x1f, 0x80, 0xfb, 0xe0, 0x7f, 0xe0, 0x0f, 0xfc, 0x07, 0xff, 0xf4, 0x00, 0x7f, 0xe7, 0xc3, 0xff,
0x1f, 0x81, 0xfb, 0xe0, 0x7f, 0xc0, 0x0f, 0xfc, 0x3f, 0xff, 0xf4, 0x00, 0x7d, 0xf7, 0xc3, 0xff,
0x1f, 0x81, 0xf1, 0xf0, 0x7f, 0xe0, 0x0f, 0xfc, 0x3f, 0xff, 0xf6, 0x00, 0x7c, 0xff, 0xc3, 0xff,
0x1f, 0x83, 0xf1, 0xf0, 0x7f, 0xf0, 0x0f, 0xfc, 0x3f, 0xff, 0xf2, 0x00, 0x7c, 0x7f, 0xc3, 0xe0,
0x1f, 0x83, 0xe0, 0xf8, 0x7f, 0xf8, 0x0f, 0x80, 0x3f, 0xff, 0xb9, 0x00, 0x7c, 0x7f, 0xc3, 0xe0,
0x1f, 0x83, 0xff, 0xf8, 0x7d, 0xfc, 0x0f, 0x80, 0x3f, 0xff, 0x1c, 0x80, 0x7c, 0x3f, 0xc3, 0xe0,
0x1f, 0x87, 0xff, 0xf8, 0x7c, 0xfe, 0x0f, 0xfc, 0x3f, 0xfe, 0x7e, 0x40, 0x7c, 0x1f, 0xc3, 0xff,
0x1f, 0x87, 0xff, 0xfc, 0x7c, 0x7f, 0x0f, 0xfc, 0x1f, 0xfe, 0xf7, 0xe0, 0x7c, 0x0f, 0xc3, 0xff,
0x1f, 0x8f, 0xc0, 0xfe, 0x7c, 0x3f, 0x8f, 0xfc, 0x1f, 0xff, 0xe7, 0xf0, 0x7c, 0x0f, 0xc3, 0xff,
0x1f, 0x8f, 0xc0, 0xfe, 0x7c, 0x3f, 0x8f, 0xfc, 0x0f, 0xff, 0xcf, 0xf8, 0x7c, 0x07, 0xc1, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf9, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char server_ip[40] = "192.168.1.100";
char server_port[6] = "8080";
char device_name[40] = "joypad-1";
WiFiManagerParameter custom_server("server", "Server IP", server_ip, 40);
WiFiManagerParameter custom_port("port", "Port", server_port, 6);
WiFiManagerParameter custom_name("devname", "Device Name", device_name, 40);
WiFiClient tcpClient;
bool shouldSaveConfig = false;
void saveConfigCallback() { shouldSaveConfig = true; }
void oled_clear() {
display.clearDisplay();
display.display();
}
void oled_text(int size, int x, int y, String msg) {
display.setTextSize(size);
display.setTextColor(SSD1306_WHITE);
display.setCursor(x, y);
display.println(msg);
display.display();
}
void oled_logo() {
oled_clear();
display.drawBitmap(0, 0, logo_bmp, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
oled_text(1, 110, 14, ".bh");
oled_text(1, 1, 44, "sports-tech");
delay(3000);
oled_clear();
}
void loadConfig() {
if (SPIFFS.exists(CONFIG_FILE)) {
File f = SPIFFS.open(CONFIG_FILE, "r");
if (f) {
DynamicJsonDocument doc(256);
DeserializationError err = deserializeJson(doc, f);
if (!err) {
strlcpy(server_ip, doc["server"] | server_ip, sizeof(server_ip));
strlcpy(server_port, doc["port"] | server_port, sizeof(server_port));
strlcpy(device_name, doc["devname"] | device_name, sizeof(device_name));
}
f.close();
}
}
}
void saveConfig() {
DynamicJsonDocument doc(256);
doc["server"] = server_ip;
doc["port"] = server_port;
doc["devname"] = device_name;
File f = SPIFFS.open(CONFIG_FILE, "w");
if (f) {
serializeJson(doc, f);
f.close();
}
}
void wifiReset() {
oled_clear();
oled_text(1, 0, 0, "WiFi Reset...");
WiFiManager wm;
wm.resetSettings();
delay(500);
ESP.restart();
}
bool wasPressed(uint8_t pin) {
static uint8_t prev[16] = {0};
bool pressed = !digitalRead(pin);
if (pressed && !prev[pin]) { prev[pin] = 1; return true; }
if (!pressed) prev[pin] = 0;
return false;
}
void buzz() {
digitalWrite(MOTOR_PIN, HIGH); delay(120);
digitalWrite(MOTOR_PIN, LOW);
}
void connect_server() {
if (tcpClient.connected()) return;
oled_clear();
oled_text(1, 0, 0, "Connecting TCP...");
while (!tcpClient.connect(server_ip, atoi(server_port))) {
oled_text(1, 0, 16, "Retry...");
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
delay(500);
}
digitalWrite(LED_PIN, LOW);
oled_clear();
oled_text(1, 0, 0, "TCP Connected!");
delay(1000);
oled_clear();
}
void send_button(const char* btn) {
DynamicJsonDocument doc(256);
doc["device"] = device_name;
doc["type"] = "score";
doc["button"] = btn;
String msg;
serializeJson(doc, msg);
tcpClient.println(msg);
Serial.println(msg);
oled_clear();
oled_text(2, 0, 0, btn);
oled_text(1, 0, 24, "Sent!");
delay(700); // show feedback
oled_clear();
}
// WiFiManager AP mode callback
void configModeCallback (WiFiManager *myWiFiManager) {
oled_clear();
oled_text(1, 0, 0, "WiFi Portal");
oled_text(1, 0, 16, "SSID:");
oled_text(1, 0, 32, myWiFiManager->getConfigPortalSSID());
oled_text(1, 0, 48, "192.168.4.1");
}
void setup() { void setup() {
// Serial Port
Serial.begin(115200); Serial.begin(115200);
Serial.println(); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH);
pinMode(MOTOR_PIN, OUTPUT); digitalWrite(MOTOR_PIN, LOW);
// Display pinMode(BTN_RED1, INPUT_PULLUP);
displayInit(); // Starting The Display pinMode(BTN_RED2, INPUT_PULLUP);
displayIdentity(); // Display Identity pinMode(BTN_BLUE1, INPUT_PULLUP);
pinMode(BTN_BLUE2, INPUT_PULLUP);
pinMode(BTN_CENTER, INPUT_PULLUP);
// WiFi display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
setupWiFiAndConfig("TAKEONE"); oled_logo();
// displayStatus("TCP Connect", server, port);
// Buttons Start
BlueBody.begin(); // Connect your button between pin 2 and GND
BlueHead.begin(); // Connect your button between pin 3 and GND
RedBody.begin(); // Connect your button between pin 4 and GND
RedHead.begin(); // Connect your button between pin 4 and GND
YellowButton.begin(); // Connect your button between pin 4 and GND
// Stop
Serial.println();
oled_clear();
oled_text(1, 0, 0, "Mounting FS...");
if (!SPIFFS.begin(true)) {
oled_clear();
oled_text(1, 0, 0, "SPIFFS Fail!");
delay(2000);
ESP.restart();
} }
//======================================================== loadConfig();
// LOOP
//======================================================== WiFiManager wm;
wm.setSaveConfigCallback(saveConfigCallback);
wm.setAPCallback(configModeCallback);
wm.addParameter(&custom_server);
wm.addParameter(&custom_port);
wm.addParameter(&custom_name);
// --- Generate unique SSID ---
uint32_t chipId = (uint32_t)(ESP.getEfuseMac() & 0xFFFFFF);
char ap_ssid[32];
snprintf(ap_ssid, sizeof(ap_ssid), "JOYPAD %06X", chipId);
oled_clear();
oled_text(1, 0, 0, "WiFi Connect...");
if (!wm.autoConnect(ap_ssid)) {
oled_clear();
oled_text(1, 0, 0, "WiFi Failed!");
delay(3000);
ESP.restart();
}
strlcpy(server_ip, custom_server.getValue(), sizeof(server_ip));
strlcpy(server_port, custom_port.getValue(), sizeof(server_port));
strlcpy(device_name, custom_name.getValue(), sizeof(device_name));
if (shouldSaveConfig) saveConfig();
oled_clear();
oled_text(1, 0, 0, "WiFi OK!");
oled_text(1, 0, 16, WiFi.localIP().toString());
delay(1500);
connect_server();
}
void loop() { void loop() {
// WiFi Reset button (hold center button at any time)
// Monitor if (wasPressed(BTN_CENTER)) {
// monitorConnection(); oled_clear();
oled_text(1, 0, 0, "WiFi Reset...");
// Buttons wifiReset();
read_buttons();
} }
//======================================================== // TCP connection maintenance
// Read Button if (!tcpClient.connected()) {
//======================================================== connect_server();
void read_buttons() {
if(BlueBody.pressed()) {
Serial.println("Blue Body");
} }
if(BlueHead.pressed()) { // Button actions
Serial.println("Blue Head"); if (wasPressed(BTN_RED1)) { send_button("RED1"); buzz(); }
} if (wasPressed(BTN_RED2)) { send_button("RED2"); buzz(); }
if (wasPressed(BTN_BLUE1)) { send_button("BLU1"); buzz(); }
if (wasPressed(BTN_BLUE2)) { send_button("BLU2"); buzz(); }
if(RedBody.pressed()) { // Show device name, IP, port, and TCP status
Serial.println("Red Body"); static unsigned long lastStatus = 0;
if (millis() - lastStatus > 3000) {
oled_clear();
oled_text(1, 0, 0, device_name);
oled_text(1, 0, 16, WiFi.localIP().toString());
oled_text(1, 0, 32, "Port: " + String(server_port));
oled_text(1, 0, 48, tcpClient.connected() ? "TCP: OK" : "TCP: ...");
lastStatus = millis();
} }
if(RedHead.pressed()) {
Serial.println("Red Head");
} }
if(YellowButton.pressed()) {
Serial.println("Yellow");
resetWiFiAndConfig();
}
}
//========================================================
// OLED Display
//========================================================