#include <SPI.h>
#include <TFT_eSPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <EEPROM.h>
// Define the EEPROM address where the calibration data will be stored
#define CALIBRATION_DATA_ADDR 0
// This part is implemented by Gueraiche Larbi to control the Nema 34 Stepper motor
# define PUL 4 //PIN PUL+
# define DIR 5 //PIN DIR+
# define EN 6 //PIN ENA+
int SPR = 200; // 200 steps per round
int NDiv =1 ;
int NSteps=16*SPR/NDiv; // Number of steps for 1/16 microstep in order to reduce motor vibrations.
// The used mode with DM860D is the half current
// Potentiometer is set as P
// NDiv is set as the number od divisions
// Pitch is set as Pitch
// Diameter of the gear is set as Dia
TFT_eSPI tft = TFT_eSPI(); // https://github.com/Bodmer/TFT_eSPI
// Création de 2 objets boutons
#define NOMBRE_BOUTONS 2
TFT_eSPI_Button bouton[NOMBRE_BOUTONS];
/***************************************************************************
Bouton coulissant sur un écran tactile TFT SPI 2.4" 320 X 240 pixels
Pour plus d'infos:
https://electroniqueamateur.blogspot.com/2021/04/utilisation-dun-ecran-tactile-tft-spi_25.html
******************************************************************************/
#define VALEUR_MAX 480 // valeur affichée quand le bouton est poussé à l'extrême droite
#define LARGEUR 10 // largeur du bouton
#define HAUTEUR 20 // hauteur du bouton
#define POSY 200 // position verticale du bouton coulissant
#define LIMITE_GAUCHE 10 // extrémité gauche au 20e pixel
#define LIMITE_DROITE 150 // extrémité droite au 100e pixel
uint16_t x_precedent = 160 ; // position horizontale précédemment touchée (160 est le centre de l'écran)
// routine qui redessine le contenu de l'écran
void dessineContenu(uint16_t posx) {
uint16_t postxt;
// on ne permet pas que le bouton dépasse les limites établies
if (posx < LIMITE_GAUCHE) {
posx = LIMITE_GAUCHE;
}
if (posx > LIMITE_DROITE) {
posx = LIMITE_DROITE;
}
// on efface le bouton, là où il se trouvait précédemment
tft.fillRect(x_precedent - LARGEUR / 2, POSY - HAUTEUR / 2 - 2 , LARGEUR, HAUTEUR + 4, TFT_BLUE);
// on dessine la ligne horizontale
tft.drawLine(LIMITE_GAUCHE, POSY, LIMITE_DROITE, POSY, TFT_WHITE);
// on dessine le bouton à sa nouvelle position
tft.fillRect(posx - LARGEUR / 2, POSY - HAUTEUR / 2, LARGEUR, HAUTEUR, TFT_YELLOW);
// on efface l'ancienne valeur numérique
postxt = 40;
tft.setTextColor(TFT_BLUE);
postxt += tft.drawFloat(calcule_valeur(x_precedent), 1, postxt, 150, 2);
// on écrit la nouvelle valeur numérique
postxt = 40;
tft.setTextColor(TFT_GREEN);
postxt += tft.drawFloat(calcule_valeur(posx), 1, postxt, 150, 2);
x_precedent = posx;
}
// routine qui calcule la valeur numérique qui correspond à la position du bouton coulissant
float calcule_valeur (uint16_t valeur_brute) {
float valeur_convertie;
valeur_convertie = 1.0 * (valeur_brute - LIMITE_GAUCHE) / ( LIMITE_DROITE - LIMITE_GAUCHE) * VALEUR_MAX;
return valeur_convertie;
}
uint16_t calData[5];
void initialTouchCalibration()
{
tft.fillScreen(TFT_BLACK);
tft.setCursor(25, 70);
tft.setTextFont(2);
tft.setTextSize(2);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println("Touchez l'ecran a ");
tft.setCursor(15, 110);
tft.println("chaque coin indique.");
tft.setTextFont(1);
tft.println();
// Perform the touch calibration and get the calibration data
tft.calibrateTouch(calData, TFT_YELLOW, TFT_BLACK, 20);
// Store the calibration data in EEPROM
for (int i = 0; i < 5; i++) {
EEPROM.put(CALIBRATION_DATA_ADDR + i * sizeof(uint16_t), calData[i]);
}
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration terminee!");
}
void storeCalibrationData(uint16_t calData[5])
{
// Store the calibration data in EEPROM
for (int i = 0; i < 5; i++) {
EEPROM.put(CALIBRATION_DATA_ADDR + i * sizeof(uint16_t), calData[i]);
}
}
bool loadCalibrationData(uint16_t calData[5])
{
// Read the calibration data from EEPROM
for (int i = 0; i < 5; i++) {
EEPROM.get(CALIBRATION_DATA_ADDR + i * sizeof(uint16_t), calData[i]);
}
// Check if the data was successfully loaded
// You can add additional validation if needed
return true; // Change this based on your validation criteria
}
void drawCenteredButtonText(TFT_eSPI_Button &button) {
int16_t x, y, w, h;
button.getRect(&x, &y, &w, &h);
// Calculate the center position for text
int16_t textX = x + (w - tft.textWidth(button.label())) / 2;
int16_t textY = y + (h - tft.fontHeight(2)) / 2;
// Set text color and size
tft.setTextColor(TFT_WHITE);
tft.setTextSize(2);
// Print the button text at the center
tft.setTextDatum(MC_DATUM);
tft.drawString(button.label(), textX, textY);
}
void setup(void)
{
tft.init();
tft.setRotation(1); // portrait: 0 ou 2, paysage: 1 ou 3.
//touch_calibrate(); // procédure de calibration de l'écran tactile
// Initialize your hardware and display settings
if (loadCalibrationData(calData)) {
// Calibration data exists, load and apply it
tft.setTouch(calData);
} else {
// Calibration data doesn't exist, perform initial calibration
initialTouchCalibration();
}
tft.begin();
tft.fillScreen(TFT_BLUE);
tft.setCursor(15, 20);
tft.setTextSize(0.2);
tft.setTextColor(TFT_YELLOW);
tft.setTextSize(2);
tft.setRotation(1);
tft.print("Hyb-Dividing Head Shield");
tft.setCursor(15, 60);
tft.setTextSize(0.2);
tft.setTextColor(TFT_GREEN);
tft.setTextSize(2);
tft.setRotation(1);
tft.print("N-Divisions");
// création de deux boutons
// premier bouton: son centre est positionné à x = 60 et y = 125, largeur 60,
// hauteur 40, contour en noir, remplissage rouge, texte en blanc, taille de texte 2.
bouton[0].initButton(&tft, 60, 125, 60, 40, TFT_BLACK, TFT_RED, TFT_WHITE, "<<", 2);
bouton[0].drawButton();
drawCenteredButtonText(bouton[0]);
// deuxième bouton: son centre est positionné à x = 130 et y = 125, largeur 60,
// hauteur 40, contour en noir, remplissage vert, texte en blanc, taille de texte 1.
bouton[1].initButton(&tft, 130, 125, 60, 40, TFT_BLACK, TFT_GREEN, TFT_WHITE, ">>", 2);
bouton[1].drawButton();
drawCenteredButtonText(bouton[1]);
dessineContenu(160);
//Stepper motor WT86STH118-6004A (Nema 34) Pins configuaration by Larbi Gueraiche
pinMode (PUL, OUTPUT);
pinMode (DIR, OUTPUT);
pinMode (EN, OUTPUT);
}
void loop() {
uint16_t t_x = 0, t_y = 0; // coordonnées touchées par l'utilisateur
boolean pressed = tft.getTouch(&t_x, &t_y); // vrai si contact avec l'écran
// On vérifie si la position du contact correspond à celle d'un bouton
for (uint8_t numero = 0; numero < NOMBRE_BOUTONS; numero++) {
if (pressed && bouton[numero].contains(t_x, t_y)) {
bouton[numero].press(true);
} else {
bouton[numero].press(false);
}
}
// Vérifions maintenant si l'état d'un des boutons a changé
for (uint8_t numero = 0; numero < NOMBRE_BOUTONS; numero++) {
// si le bouton vient d'être relâché, on le redessine avec sa forme normale
// if (bouton[numero].justReleased()) {
// bouton[numero].drawButton();
// }
// si le bouton vient d'être pressé...
if (bouton[numero].justPressed()) {
bouton[numero].drawButton(true); // on le redessine avec les couleurs inversées
// ...puis on fait ce que l'utilisateur a demandé:
switch (numero) {
case 0: // Turn WT86STH118-6004A Nema 34 Stepper motor forward
digitalWrite(EN,LOW);
digitalWrite(DIR,LOW); //Forward steps
for (int i=1; i<NSteps; i--) {
digitalWrite(PUL,HIGH);
delayMicroseconds(1000);
digitalWrite(PUL,LOW);
delayMicroseconds(1000);
}
delay(100);
digitalWrite(EN,HIGH);
break;
case 1: // Turn WT86STH118-6004A Nema 34 Stepper motor backward
digitalWrite(EN,LOW);
digitalWrite(DIR,HIGH); //Backward steps
for (int i=1; i<NSteps; i++)
{
digitalWrite(PUL,HIGH);
delayMicroseconds(1000);
digitalWrite(PUL,LOW);
delayMicroseconds(1000);
}
delay(100);
digitalWrite(EN,HIGH);
break;
}
delay(10); // anti-rebond
}
}
if (pressed) { // Si on touche l'écran
// Vérifiez si le toucher est à l'intérieur du rectangle du bouton coulissant
if (t_x >= (x_precedent - LARGEUR / 2) && t_x <= (x_precedent + LARGEUR / 2) &&
t_y >= (POSY - HAUTEUR / 2) && t_y <= (POSY + HAUTEUR / 2)) {
if (t_x != x_precedent) { // Si on a changé de position
dessineContenu(t_x);
}
}
}
}
// procédure de calibration de l'écran tactile
// void touch_calibrate()
// {
// uint16_t calData[5];
// uint8_t calDataOK = 0;
// tft.fillScreen(TFT_BLACK);
// tft.setCursor(25, 70);
// tft.setTextFont(2);
// tft.setTextSize(2);
// tft.setTextColor(TFT_WHITE, TFT_BLACK);
// tft.println("Touchez l'ecran a ");
// tft.setCursor(15, 110);
// tft.println("chaque coin indique.");
// tft.setTextFont(1);
// tft.println();
// tft.calibrateTouch(calData, TFT_YELLOW, TFT_BLACK, 20);
// tft.setTextColor(TFT_GREEN, TFT_BLACK);
// tft.println("Calibration terminee!");
// }
Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1
Loading
ili9341-cap-touch
ili9341-cap-touch