bonjour le forum,
pour un projet de compteur de passages avec envoi du nombre par mail, j'utilise deux Arduino (le code pour l'envoi du mail prend à lui seul 90% de mémoire):
un Uno maître, pour le compteur et l'horloge / alarme;
un Uno R4 WiFi esclave, pour l'envoi du mail;
les deux fonctionnent bien séparément, mais pas quand ils sont reliés via les Rx-Tx (croisés, avec un Gnd commun); même pas avec les codes basiques ci-dessous (téléversés en ayant débranché les liaisons Tx/Rx)
Merci d'avance pour votre aide
J’ai déplacé votre sujet dans la catégorie générale francophone du forum qui est la plus appropriée - ce n'est pas un tuto...
À l’avenir, veuillez prendre un moment pour choisir la catégorie du forum qui correspond le mieux au sujet de votre message. En haut de chaque catégorie se trouve un sujet intitulé « À propos de la catégorie ___ » qui en explique la finalité.
merci jpbbricole
j'aurais bien voulu n'utiliser que le R4, mais le code pour le mail (ESP) prend déjà 91% de la mémoire, trop pour pouvoir y rajouter le code du compteur et du déclencheur d'envoi du mail
le code mail est dans le R4 wifi, et le R3 contient le code compteur et déclencheur
Je peux poster le code des deux, mais je pensais que tant que je n'avais pas solutionné le problème de communication avec les deux programmes test du début, c'était inutile de rajouter les autres...
Et je suis un peu pressé par le temps pour changer de carte...
merci beaucoup pour ton écoute! depuis plusieurs jours je tente pas mal d'essais infructueux
Voici le code prévu pour le Uno maître
#include "Arduino.h"
#include "Wire.h"
#include <RTClib.h>
#define ButtonState
#define SUNDAY 0
#define MONDAY 1
#define TUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6
#define JANUARY 1
#define FEBRUARY 2
#define MARCH 3
#define APRIL 4
#define MAY 5
#define JUNE 6
#define JULY 7
#define AUGUST 8
#define SEPTEMBER 9
#define OCTOBER 10
#define NOVEMBER 11
#define DECEMBER 12
RTC_DS3231 rtc;
const int buttonPin = 2; // contact (NO du relais de la barrière)IR
const int resetPin = 3;
int counter = 0; // compteur du nombre de passages
int buttonState = 0; // état du contact IR (Haut ou Bas)
int lastButtonState = 0; // dernier état du contact IR
void setup() {
while (!Serial) ;
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(resetPin, INPUT);
Wire.begin();
bool buttonPressed = false; // Boolean flag to track button press
// SETUP RTC MODULE
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
// Serial.flush();
while (1);
}
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // time du PC
rtc.adjust(DateTime(2025, 10, 9, 20, 59, 0)); // entrée manuelle time A M J h m s
}
void loop() {
buttonState = digitalRead(buttonPin); // lecture de l'état du contact IR
if (digitalRead(buttonPin) == HIGH) {
counter++;
Serial.println(counter);
delay (2000);
}
lastButtonState = buttonState; // enregistre l'état du contact IR comme dernier état
DateTime now = rtc.now();
// alarme envoi mail val counter
if (now.hour()== 21 && now.minute()== 0 && now.second()== 0) {
Serial.write("counter val"); // pour Tx au R4 envoi par mail
delay (1000);
}
// alarme reset
if (now.hour()== 21 && now.minute()== 1 && now.second()== 0) {
counter = 0; // reset counter
delay (1000);
Serial.println(counter);
}
et le code pour envoi du mail par le R4Wifi, pour lequel je n'ai pas encore travaillé à voir comment mettre dans le corps du mail la valeur "counter" envoyée par le R3
Voilà, je t'ai refait le Maser et le slave du post#1
Le Master envoie les données au slave, toutes les sendValeursTempo millisecondes et, pour le "scénario", counter est incrémenté toutes les counterTempo millisecondes.
Tu remarquera l'absence de temporisations en delay();, c'est à bannir dans ce genre de transactions. En effet cette fonction a le défaut de bloquer ton Arduino pendant la durée du délais.
Toutes les temporisations se font avec les millis (regarde cet exemple de clignotement de LED)
Si tu prévois de transmettre plus d'une valeur, dis le tout de suite afin que je structure tes communications en conséquence.
Il y a des lien dans le Slave, concernant les fonctions de réception.
Le programme Master:
int counter = 0; // Valeur à transmettre
const unsigned long sendValeursTempo = 3000; // Envoi toutes les xxx millisecondes
unsigned long sendValeursMillis = millis(); // Envoi toutes les xxx millisecondes, chrono
const unsigned long counterTempo = 750; // Incrément du compteur toutes les xxx millisecondes
unsigned long counterMillis = millis(); // Incrément du compteur toutes les xxx millisecondes, chrono
void setup()
{
Serial.begin(9600); // Rx (0) sur R4 Tx (1) Tx (1) sur R4 Rx (0)
}
void loop()
{
//--------------------------------- Counter
if (millis() - counterMillis >= counterTempo) // Si moment d'incrémenter counter
{
counter ++;
counterMillis = millis(); // Redémarrer le chrono
}
//--------------------------------- Envoi des données
if (millis() - sendValeursMillis >= sendValeursTempo) // Si moment d'envoyer les données
{
Serial.println(counter); // Envoi de la donnée
sendValeursMillis = millis(); // Redémarrer le chrono
}
}
Le programme Slave:
/*
readStringUntil(); https://docs.arduino.cc/language-reference/en/functions/communication/serial/readStringUntil/
trim(); https://docs.arduino.cc/built-in-examples/strings/StringLengthTrim/
toInt(); https://docs.arduino.cc/language-reference/en/variables/data-types/stringObject/Functions/toInt/
*/
int counter = 0; // Valeur reçue
void setup()
{
Serial.begin(115200); // Liaison USB
Serial1.begin(9600); // Liaison Master Rx (0) sur R3 Tx (1) Tx (1) sur R3 Rx (0)
}
void loop()
{
if (Serial1.available()) // Si réception du Master
{
String rxMaster = Serial1.readStringUntil('\n'); // Réception de Master
rxMaster.trim(); // Nettoyage de la chaîne reçue
counter = rxMaster.toInt(); // Extraction decounter
Serial.println("Nouvelle donnée reçue: " + String(counter));
}
}
merci jpbbricole pour cette réponse détaillée, que je vais étudier.
Une seule valeur est en jeu, celle du compteur (de passage de clients d'un petit magasin), donc une variable entière positive inférieure à 256.
Concernant les millis je vais regarder, mais déjà:
je dois déclencher deux actions quotidiennes, soit un envoi de la valeur du compteur à 21h, et un reset du compteur à 22.
Je suppose que je devrai mettre sendValeursTempo = 24 x 3600 x 1000 , et 25x... pour la 2ème?
Belle soirée, cordialement
Jp
Non, la fonction millis() ne te donne pas une heure, mais le nombre de millisecondes depuis le démarrage de l'Arduino, donc aucune référence de 21h ou autre.
Mais ce n'est pas nécessaire, puisque tu as une RTC et, dans ton post#11, il y a déjà des actions pour ces 2 événements.
// alarme envoi mail val counter
if (now.hour()== 21 && now.minute()== 0 && now.second()== 0) {
Serial.write("counter val"); // pour Tx au R4 envoi par mail
delay (1000);
}
Il te faut uniquement modifier la façon d'envoyer counter, comme vu dans le programme master du post#13
// alarme envoi mail val counter
if (now.hour()== 21 && now.minute()== 0 && now.second()== 0) {
Serial.println(counter); // Envoi de la donnée
// Serial.write("counter val"); // pour Tx au R4 envoi par mail
// delay (1000);
}
Il faut, bien sûre, côté Slave, adapter la réception comme l'exemple du post#13.
Tu remarquera que j'ai mis en remarque le delay(1000);
Quand il y a des communications, ces délais sont du "poison", à éviter pour autant que faire ce peut
Vous aurez une attente d'une seconde car si la loop() boucle très vite, la RTC dira qu'on est toujours à 21:00:00 car il y a 1000 ms pendant lesquelles ce test est vrai. l'attente de 1s est là pour que la prochaine fois que l'on passe dans le test, s'il avait été vrai auparavant, on soit à 21:00:01 au moins et donc on ne redéclenchera pas. (si on veut éviter le délai qui n'est certes pas ideal, il faut rajouter de l'info, par exemple si c'est une fois par jour on peut vérifier que le N° du jour a changé)
je n'ai pas lu le code, mais si ce n'est que du côté de l'émetteur ce n'est pas très grave - il envoie les données quand il veut .
Notez que vous utilisez readStringUntil
qui bloque la loop... mais c'est pour la bonne cause..
Avec Serial.println(counter); // Envoi de la donnée
pas de souci.
Mais on peut toujours mettre, par sécurité, un timout: Serial.setTimeout(20)
de 20 millisecondes, qui sera le temps d'attente maximum.
Sans timout, c'est 1000 millisecondes.
oui mais ensuite en ne sait pas dans le code si on a reçu tout le message
c'est pour cela que je n'aime pas trop les fonctions bloquantes avec timeout arduino, elles fonctionnent quand tout se passe bien, mais si la ligne série et bruitée ou qu'il y a un souci côté émetteur on va recevoir une donnée incomplète sans pouvoir le détecter