C'est quoi ce sketch ?
C'est ainsi qu'Arduino appelle ses programmes; donc je vous soumets ci-dessous le programme que j'ai crée pour faire fonctionner mon minuteur ! Le gros avantage des programmes en open sources, c'est que l'on n'a pas à réinventer chaque fois le fil à couper le beurre... On puise dans ce qui existe déjà et on y ajoute sa sauce, si bien qu'en quelques lignes on peut déjà avoir un résultat spectaculaire.
Comme vous le voyez chaque ligne est commentée, ce qui facilite vraiment la compréhension de ce que j'ai voulu faire. Et qui va vous permettre de personnaliser votre réalisation, jusque dans vos délires les plus inattendus .
// Bernard Leclerc 03/2017 Ae1
// Définition des pinuches de l'écran
#define TFT_PIN_CS 10 // Arduino-Pin an Display CS
#define TFT_PIN_DC 9 // Arduino-Pin an A0
#define TFT_PIN_RST 8 // Arduino Reset-Pin
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <SPI.h>
#include <Adafruit_GFX.h> // Adafruit Grafique Library
#include <Adafruit_ST7735.h> // Adafruit ST7735 Library
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_RST); // Display-Library Setup
// Declaration des entrees et des variables
int relay = 7;
int led = 3;
int adv = 5;
int ok = 6;
int mn = 0;
int sk = 0;
int x =0;
// Declaration du port serie pour la synthese vocale
SoftwareSerial mySoftwareSerial(4,2); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void setup()
{
digitalWrite(relay, HIGH); // Automaintien de l'alimentation par le relais
analogWrite(led, 200);// Allume l'écran en PWM a 80%
pinMode(adv, INPUT_PULLUP);// Attribut Bouton "Avance" avec résistance de tirage à vcc
pinMode(ok, INPUT_PULLUP);// Attribut Bouton "OK"avec résistance de tirage à vcc
tft.initR(INITR_BLACKTAB); // Initialisation ST7735-Chip
mySoftwareSerial.begin(9600);
Serial.begin(115200);
if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3.
while(true);
}
//Reglage du volume et envoi du 1er message
myDFPlayer.volume(25); //Reglage du volume de 0 à 30
myDFPlayer.play(1); //Envoi le premier message
}
void loop()
{
tft.fillScreen(ST7735_BLACK);// couleur du fond d'ecran
delay(200); // 0,2 secondes d'attente
//Ecriture du titre
tft.setTextSize(2); // reglage grandeur de caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(24,4); // Définir la position du texte
tft.setTextColor(ST7735_WHITE);// couleur du texte
tft.print("MINUTES"); // texte ecrit
delay(200); // 0,2 secondes d'attente
//Tracé de la ligne verte
tft.drawLine(10,24,118,24,ST7735_GREEN);// drawLine(x_start,y_start,x_end,y_end,couleur);
//Ecriture du Copyright
tft.setTextSize(1);// Réglage nouvelle grandeur de caracteres
tft.setTextColor(ST7735_GREEN);// Reglage Nouvelle couleur de text
tft.setCursor(18,140);// Position du nouveau texte
tft.print("bernard.leclerc");// Ecriture du texte première ligne
tft.setCursor(30,148);// Position du nouveau texte seconde ligne
tft.print("@wanadoo.fr");// Ecriture du texte seconde ligne
delay(200); // 0,2 secondes d'attente
goto minutes;
// reglage des minutes à decompter
minutes:
tft.setTextSize(5); // reglage grandeur de caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(30,50); // Définir la position du texte
tft.setTextColor(ST7735_BLUE);// Couleur du texte
tft.print(mn);// Variable de texte ecrit
delay(300); // 0,2 secondes d'attente
//Controle de l'état du bouton incrementation
if (!digitalRead(adv)) { //Si le bouton est appuye
mn = mn + 1; //Les minutes sont incrementees
tft.fillRect(30,50,60,35,ST7735_BLACK); //et on efface la partie d'ecran pour preparer une nouvelle ecriture
}
//Controle de l'état du bouton validation
if (!digitalRead(ok)) { //Si le bouton est appuye
myDFPlayer.play(2); //Envoi le second message
tft.fillRect(30,50,60,35,ST7735_BLACK); //et on efface la partie d'ecran pour preparer une nouvelle ecriture
tft.fillRect(24,4,100,15,ST7735_BLACK); // sur l'entete et la valeur
tft.setTextSize(2); // reglage grandeur des caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(18,4); // Définir la position du texte
tft.setTextColor(ST7735_WHITE);// Couleur du texte
tft.print("SECONDES"); // texte ecrit
delay(300); // 0,2 secondes d'attente
goto secondes; //Etape suivante
}
goto minutes;//On boucle jusqu'a action sur 'ok'
// reglage des secondes à decompter
secondes:
tft.setTextSize(5); // reglage grandeur de caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(30,50); // Définir la position du texte
tft.setTextColor(ST7735_RED);// set couleur du texte
tft.print(sk);// variable du texte ecrit
delay(300); // 0,2 secondes d'attente
//Controle de l'état du bouton incrementation
if (!digitalRead(adv)) { //Si le bouton est appuye
sk = sk + 5; // les secondes sont incrementé de 5 unitees
tft.fillRect(30,50,60,35,ST7735_BLACK); //et on efface la partie d'ecran pour preparer une nouvelle ecriture
}
// Si l'afichage des secondes depasse la minute
if (sk > 59) {
sk = 0; //on remet a zero
}
//Controle de l'état du bouton validation
if (!digitalRead(ok)){ //Si le bouton est appuye
myDFPlayer.play(3); //Envoi le troisième message
tft.fillRect(30,50,60,35,ST7735_BLACK); //et on efface la partie d'ecran pour preparer une nouvelle ecriture
tft.fillRect(4,4,130,15,ST7735_BLACK); // sur l'entete et la valeur
tft.setTextSize(2); // reglage grandeur caractère
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(40,4); // Définir la position du texte
tft.setTextColor(ST7735_WHITE);// Couleur du texte
tft.print("TIME"); // texte ecrit
delay(300); // 0,2 secondes d'attente
goto decompte; //Etape suivante
}
goto secondes; //On boucle jusqu'a action sur 'ok'
//Lancement du décompte
decompte:
//affichage des minutes pour le décompte
tft.fillRect(40,40,60,80,ST7735_BLACK); //et on efface la partie d'ecran pour preparer une nouvelle ecriture
tft.setTextSize(5); // reglage grandeur de caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(40,40); // Définir la position du texte
tft.setTextColor(ST7735_BLUE);// Couleur du texte
tft.print(mn);//texte ecrit
delay(200); // 0,2 secondes d'attente
//affichage des secondes pour le décompte
tft.setTextSize(5); // reglage grandeur des caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setCursor(40,80); // Définir la position du texte
tft.setTextColor(ST7735_RED);// Couleur du texte
tft.print(sk);//texte ecrit
delay(790); // delay à ajuster XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//Décrementation du temps
sk = sk - 1; // On soustrait 1 seconde
if(mn<1 && sk<1) { // Le temps est écoule
goto arret;
}
if(sk < 1) { // Décrementation des minutes si les secondes sont écoulées
sk = 59; // Remise des secondes à 59
mn = mn - 1;
}
// Gestion du rétroeclairage pour economiser la batterie
if(mn < 1) {
analogWrite(led, 200);// Allume l'écran en PWM a 80%
}
else {
analogWrite(led,55);// Reduit l'eclairage a 15% avant la dernière minute
}
//Arret forcé si les deux boutons sont appuyes simultanement
if (!digitalRead (adv) && !digitalRead (ok)) {
digitalWrite(relay, LOW); // Coupure de l'alimentation
}
goto decompte;
arret:
myDFPlayer.play(4); //Envoi le quatrième message
tft.fillScreen(ST7735_BLACK);// couleur du fond d'ecran
delay(200); // 0,2 secondes d'attente
tft.setTextSize(4); // reglage grandeur de caracteres
tft.setTextWrap(true); // Enveloppement Signature?
tft.setTextColor(ST7735_BLUE);// Couleur du texte
tft.setCursor(20,10); // Définir la position du texte
tft.print("Ho!");//texte ecrit
tft.setCursor(00,60); // Définir la position du texte
tft.print("C'est");//texte ecrit
tft.setCursor(20,110); // Définir la position du texte
tft.print("CUIT");//texte ecrit
delay(200); // 0,2 secondes d'attente
//Messages Finaux avec arret forcé
do
{
delay(50); // delay de la boucle
x = x + 1;
if (!digitalRead (adv) && !digitalRead (ok)) {
digitalWrite(relay, LOW); // Coupure de l'alimentation
}
} while (x < 400); // Et on boucle 400 fois
myDFPlayer.play(5); //Envoi le cinqième message
delay(200); // 0,2 secondes d'attente
// Autre message si pas arreté
x = 0; //Remise à Zero de la boucle
do
{
delay(50); // delay de la boucle
x = x + 1;
if (!digitalRead (adv) && !digitalRead (ok)) {
digitalWrite(relay, LOW); // Coupure de l'alimentation
}
} while (x < 400); // Et on boucle 400 fois
myDFPlayer.play(6); //Envoi le sixième message
delay (10000);
digitalWrite(relay, LOW); // Coupure de l'alimentation
}
Afin de réduire la consommation, et de prolonger la durée de vie de la pile, j'utilise une sortie PWM (à Modulation de Largeur d'Impulsion) pour réduire le rétro-éclairage de l'écran, pendant la phase de décomptage du temps et tant que celui-ci est supérieur à 1 minute !
Egalement, pendant cette même phase de décomptage, une pression simultanée sur les deux boutons (ADV et OK) permet de forcer l'arrêt ! En cas d'erreur de réglage du temps ou pour arrêter prématurément le minuteur, que ce soit en cours ou en fin de cycle .
Il reste énormément de place dans l'Arduino, pour ajouter des lignes et des fonctions, car dans l'état qu'il est ce sketch n'occupe que 39% de la capacité de stockage de la mémoire programme ... Donc on peut encore en mettre .
Pour des raisons de respect de la vie privée, je ne vous joindrai pas les fichiers sonores que j'ai chargé dans ma synthèse vocale ! L'intérêt de ce minuteur est justement de le faire parler avec la voix et les expressions d'une (ou plusieurs) personne (s) que vous souhaitez entendre encore pendant quelques années . Il suffit pour cela d'un PC , et si vous êtes un maniaque de la qualité, d'un bon micro pour enregistrer les phrases à prononcer (on peut y inclure le mode d'emploi, par exemple). On pauffine l'intelligibilité avec un logiciel genre Audacity pour crée des fichiers MP3 (sans tag) appelés 001, 002, 003 ... placés sur une carte micro SD sous un répertoire 01.
Pour copier les fichiers sonores dans la carte SD, faites un formatage complet de celle-ci (Fat32) et attendez bien la fin de la copie ... J'ai eu quelques aventures là dessus qui m'ont pris pas mal de temps avant de voir que je ne respectais pas les règles minimums .

La Synthèse vocale: La petite carte mémoire est glissée ensuite dans le support prévu à cet effet sur le circuit de la DFPlayer Mini, et doit y demeurer !
Vue de l'électronique terminée:

L'écran TFT vient prendre place sur le circuit Arduino ! Attention lors des manipulations, ces écrans sont assez fragiles...
La mise en boite :

Lors de la mise en boite des circuits, il est prudent de respecter les isolations des éléments métalliques en contact avec le circuit imprimé et surtout les picots de composants ... Bien isoler le corps de la pile à pression de 9 volts ! celui-ci est en tôle. Pour ma part , j'ai mis un carton d'isolation et un ruban adhésif autour.

L'enceinte acoustique est montée sur le panneau arrière, ainsi que les boutons de commande .
Je dis enceinte acoustique car si l'on veut un minimum d'intelligibilité dans la voix, on ne peut pas se contenter d'utiliser un haut-parleur sans charge .Vous reconnaîtrez sur la photo une mini box ou haut-parleur de PC.
Ci-dessous, l'ensemble des fichiers pour réalisation :
Timer synth (59.01 Ko)