/*
Ce qui ce trouve entre les commentaires
"Pour la communication I2C et le tactile capacitif"
est à gardé sur Wokwi et à supprimé pour la bibliothèque TFT_eSPI
*/
#include <TFT_eSPI.h>
#include <SPI.h>
#include "arduino_base64.hpp"
TFT_eSPI tft = TFT_eSPI();
// Pour la communication I2C et le tactile capacitif
#include <Wire.h>
#include <Adafruit_FT6206.h>
Adafruit_FT6206 tsCapacitif;
bool isCapacitif = true;
// Pour la communication I2C et le tactile capacitif
#define TFTx 240
#define TFTy 320
#define BUTTON_SIZE 72
#define BUTTON_SPACING 10
#define BUTTON_RADIUS 10
#define ROWS ((TFTx + BUTTON_SPACING) / (BUTTON_SIZE + BUTTON_SPACING))
#define COLS ((TFTy + BUTTON_SPACING) / (BUTTON_SIZE + BUTTON_SPACING))
#define buttonNumber (ROWS * COLS)
// Nombres d'encodeurs rotatifs et définition des broches
#define numEncodRot 4
const int SW[numEncodRot] = {34, 33, 27, 5};
const int DT[numEncodRot] = {35, 25, 14, 17};
const int CLK[numEncodRot] = {32, 26, 12, 16};
int compteur[numEncodRot] = {0};
int oldSW[numEncodRot];
int oldCLK[numEncodRot];
const char* DEVICEID = "ESP-StreamDeck";
const char* PRODUCT_NAME = "ESP StreamDeck";
// Variables pour gérer l'état des boutons
bool buttonStates[buttonNumber] = {false};
void setup(void) {
Serial.begin(115200);
// Configuration des broches des encodeurs rotafifs
for (int i = 0; i < numEncodRot; i++) {
pinMode(SW[i], INPUT);
pinMode(DT[i], INPUT);
pinMode(CLK[i], INPUT);
oldSW[i] = digitalRead(SW[i]);
oldCLK[i] = digitalRead(CLK[i]);
}
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
// Pour la communication I2C et le tactile capacitif
if (isCapacitif) {
if (!tsCapacitif.begin()) {
Serial.println("Tactile capacitif non détecté !");
while (1);
}
} else {
// Initialisation du tactile
uint16_t calData[5] = { 300, 3600, 300, 3600, 6 };
tft.setTouch(calData);
}
// Pour la communication I2C et le tactile capacitif
drawButtons();
}
void loop() {
// Pour la communication I2C et le tactile capacitif
if (isCapacitif) {
if (tsCapacitif.touched()) {
TS_Point p = tsCapacitif.getPoint();
// Remap selon la rotation de l'écran
int x = map(p.y, 0, 320, 0, 320);
int y = map(p.x, 0, 240, 240, 0);
// Serial.print("Capacitif détecté à : ");
// Serial.print("X = "); Serial.print(x);
// Serial.print(", Y = "); Serial.println(y);
}
} else {
uint16_t x, y;
if (tft.getTouch(&x, &y)) {
Serial.print("Résistif détecté à : ");
Serial.print("X = "); Serial.print(x);
Serial.print(", Y = "); Serial.println(y);
}
}
// Pour la communication I2C et le tactile capacitif
handleCompanionMessages();
handleEncoder();
if (isCapacitif) {
handleButtonPressesCapacitif();
} else {
handleButtonPresses();
}
}
void drawButtons() {
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
int x = startX + col * (BUTTON_SIZE + BUTTON_SPACING);
int y = startY + row * (BUTTON_SIZE + BUTTON_SPACING);
tft.fillRoundRect(x, y, BUTTON_SIZE, BUTTON_SIZE, BUTTON_RADIUS, TFT_DARKGREY);
tft.drawRoundRect(x, y, BUTTON_SIZE, BUTTON_SIZE, BUTTON_RADIUS, TFT_WHITE);
}
}
}
void updateButtonColor(int key, uint16_t color) {
int row = key / COLS;
int col = key % COLS;
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
int x = startX + col * (BUTTON_SIZE + BUTTON_SPACING);
int y = startY + row * (BUTTON_SIZE + BUTTON_SPACING);
tft.fillRoundRect(x, y, BUTTON_SIZE, BUTTON_SIZE, BUTTON_RADIUS, color);
tft.drawRoundRect(x, y, BUTTON_SIZE, BUTTON_SIZE, BUTTON_RADIUS, TFT_WHITE);
}
void updateButtonText(int key, const char* text) {
int row = key / COLS;
int col = key % COLS;
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
int x = startX + col * (BUTTON_SIZE + BUTTON_SPACING) + BUTTON_SIZE / 2;
int y = startY + row * (BUTTON_SIZE + BUTTON_SPACING) + BUTTON_SIZE / 2;
tft.setTextColor(TFT_WHITE);
tft.setTextSize(1);
tft.setTextDatum(MC_DATUM);
tft.drawString(text, x, y);
}
void updateButtonImage(int key, const uint8_t* imageData, int width, int height) {
int row = key / COLS;
int col = key % COLS;
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
int x = startX + col * (BUTTON_SIZE + BUTTON_SPACING) + (BUTTON_SIZE - width) / 2;
int y = startY + row * (BUTTON_SIZE + BUTTON_SPACING) + (BUTTON_SIZE - height) / 2;
tft.pushImage(x, y, width, height, (uint16_t*)imageData);
}
void handleCompanionMessages() {
while (Serial.available()) {
String line = Serial.readStringUntil('\n');
Serial.println("Message reçu: " + line);
if (line.startsWith("KEY-STATE")) {
int keyIndex = line.indexOf("KEY=");
int colorIndex = line.indexOf("COLOR=");
int textIndex = line.indexOf("TEXT=");
int bitmapIndex = line.indexOf("BITMAP=");
if (keyIndex != -1 && colorIndex != -1) {
int ColorButtonNumber = line.substring(keyIndex + 4, line.indexOf(" ", keyIndex)).toInt();
String colorHex = line.substring(colorIndex + 7, colorIndex + 13);
uint32_t colorRGB = strtoul(colorHex.c_str(), NULL, 16);
uint8_t r = (colorRGB >> 16) & 0xFF;
uint8_t g = (colorRGB >> 8) & 0xFF;
uint8_t b = colorRGB & 0xFF;
uint16_t color = tft.color565(r, g, b);
updateButtonColor(ColorButtonNumber, color);
Serial.println("Bouton " + String(ColorButtonNumber) + " mise à jour avec la couleur #" + colorHex);
}
if (keyIndex != -1 && textIndex != -1) {
int buttonNumberText = line.substring(keyIndex + 4, line.indexOf(" ", keyIndex)).toInt();
int textEnd = line.indexOf(" ", textIndex);
String textBase64 = line.substring(textIndex + 5, textEnd);
uint8_t decodedText[base64::decodeLength(textBase64.c_str())];
base64::decode(textBase64.c_str(), decodedText);
updateButtonText(buttonNumberText, (const char*)decodedText);
Serial.println("Texte mis à jour pour le bouton " + String(buttonNumberText));
}
if (keyIndex != -1 && bitmapIndex != -1) {
int buttonNumberBitmap = line.substring(keyIndex + 4, line.indexOf(" ", keyIndex)).toInt();
int bitmapEnd = line.indexOf(" ", bitmapIndex);
String bitmapBase64 = line.substring(bitmapIndex + 7, bitmapEnd);
uint8_t decodedBitmap[base64::decodeLength(bitmapBase64.c_str())];
base64::decode(bitmapBase64.c_str(), decodedBitmap);
// Supposons que l'image est toujours 72x72 pour simplifier
updateButtonImage(buttonNumberBitmap, decodedBitmap, 72, 72);
Serial.println("Image mise à jour pour le bouton " + String(buttonNumberBitmap));
}
}
}
}
void handleButtonPressesCapacitif() {
if (tsCapacitif.touched()) {
TS_Point p = tsCapacitif.getPoint();
// Adapter les coordonnées en fonction de la rotation de l'écran
int x, y;
if (tft.getRotation() == 1) {
x = map(p.y, 0, 320, 0, tft.width());
y = map(p.x, 0, 240, tft.height(), 0);
} else if (tft.getRotation() == 3) {
x = map(p.y, 0, 320, tft.width(), 0);
y = map(p.x, 0, 240, 0, tft.height());
}
// Convertir les coordonnées tactiles en indices de boutons
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
if (x >= startX && x <= startX + COLS * (BUTTON_SIZE + BUTTON_SPACING) &&
y >= startY && y <= startY + ROWS * (BUTTON_SIZE + BUTTON_SPACING)) {
int col = (x - startX) / (BUTTON_SIZE + BUTTON_SPACING);
int row = (y - startY) / (BUTTON_SIZE + BUTTON_SPACING);
int buttonIndex = row * COLS + col;
if (!buttonStates[buttonIndex]) {
// Si le bouton était précédemment non appuyé, envoyer l'événement PRESSED
Serial.println("KEY-PRESS DEVICEID=" + String(DEVICEID) + " KEY=" + String(buttonIndex) + " PRESSED=1\n");
buttonStates[buttonIndex] = true; // Mettre à jour l'état du bouton
}
}
} else {
// Détection du relâchement des boutons
for (int i = 0; i < buttonNumber; i++) {
if (buttonStates[i]) {
// Si un bouton était précédemment appuyé, envoyer l'événement RELEASED
Serial.println("KEY-PRESS DEVICEID=" + String(DEVICEID) + " KEY=" + String(i) + " PRESSED=0\n");
buttonStates[i] = false; // Réinitialiser l'état du bouton
}
}
}
}
void handleButtonPresses() {
uint16_t x, y;
if (tft.getTouch(&x, &y)) { // Méthode pour récupérer les coordonnées tactiles avec TFT_eSPI
// Adapter les coordonnées en fonction de la rotation de l'écran
uint16_t x, y;
if (tft.getRotation() == 1) {
x = map(y, 0, 320, 0, tft.width());
y = map(x, 0, 240, tft.height(), 0);
} else if (tft.getRotation() == 3) {
x = map(y, 0, 320, tft.width(), 0);
y = map(x, 0, 240, 0, tft.height());
}
// Convertir les coordonnées tactiles en indices de boutons
int startX = (tft.width() - (COLS * BUTTON_SIZE + (COLS - 1) * BUTTON_SPACING)) / 2;
int startY = (tft.height() - (ROWS * BUTTON_SIZE + (ROWS - 1) * BUTTON_SPACING)) / 2;
if (x >= startX && x <= startX + COLS * (BUTTON_SIZE + BUTTON_SPACING) &&
y >= startY && y <= startY + ROWS * (BUTTON_SIZE + BUTTON_SPACING)) {
int col = (x - startX) / (BUTTON_SIZE + BUTTON_SPACING);
int row = (y - startY) / (BUTTON_SIZE + BUTTON_SPACING);
int buttonIndex = row * COLS + col;
if (!buttonStates[buttonIndex]) {
// Si le bouton était précédemment non appuyé, envoyer l'événement PRESSED
Serial.println("KEY-PRESS DEVICEID=" + String(DEVICEID) + " KEY=" + String(buttonIndex) + " PRESSED=1\n");
buttonStates[buttonIndex] = true; // Mettre à jour l'état du bouton
}
}
} else {
// Détection du relâchement des boutons
for (int i = 0; i < buttonNumber; i++) {
if (buttonStates[i]) {
// Si un bouton était précédemment appuyé, envoyer l'événement RELEASED
Serial.println("KEY-PRESS DEVICEID=" + String(DEVICEID) + " KEY=" + String(i) + " PRESSED=0\n");
buttonStates[i] = false; // Réinitialiser l'état du bouton
}
}
}
}
void handleEncoder() {
String message = "";
bool changed = false;
for (int i = 0; i < numEncodRot; i++) {
int etatCLK = digitalRead(CLK[i]);
int etatSW = digitalRead(SW[i]);
int etatDT = digitalRead(DT[i]);
if (etatSW != oldSW[i]) {
oldSW[i] = etatSW;
message += "KEY-PRESS DEVICEID=" + String(DEVICEID) + " KEY=" + String(buttonNumber + i) + " PRESSED=" + String(etatSW == LOW ? 1 : 0) + "\n";
changed = true;
}
if (etatCLK != oldCLK[i]) {
oldCLK[i] = etatCLK;
if (etatCLK == LOW) {
if (etatCLK != etatDT) {
compteur[i]++;
} else {
compteur[i]--;
}
message += "KEY-ROTATE DEVICEID=" + String(DEVICEID) + " KEY=" + String(buttonNumber + i) + " DIRECTION=" + String(compteur[i]) + "\n";
changed = true;
}
}
}
if (changed) {
Serial.print(message);
}
}
Loading
ili9341-cap-touch
ili9341-cap-touch