Retour de Bébert. Je mets au point un anémomètre avec un appareil du commerce qui envoie les impulsions à un émetteur arduino NANO. Avec un second NANO, le récepteur reçoit toutes les secondes le nombre d’impulsions reçues ; soit la fréquence qui sert de base pour les calculs de vitesse instantanée, vitesse moyenne, vitesse moyenne des 10 dernières minutes etc… L’écran LCD I2C 20x 4 affiche correctement les valeurs attendues.
Comme je dois ajouter au récepteur l’horloge temps réel DS3231 et un lecteur de carte SD pour les enregistrements, le NANO va faire une indigestion. Je suis donc en train de passer au MEGA 2560. Pour l'instant, je veux vérifier que cela fonctionne comme avec le NANO avant d'aller plus loin.
Or, avec le MEGA il faut utiliser la bibliothèque « AltSoftSerial.h » pin 48 et 46 pour le TX et le RX au lieu de la bibliothèque « SoftWareSerial.h ». Chose faite. Malheureusement, le moniteur du récepteur m’affiche toujours un « 0 » suivi de la bonne valeur de fréquence. Ce qui empêche l’affichage de la vitesse instantanée calculée qui reste à 0 même si la bonne valeur suit instantanément (ici : 50Hz affichée correctement au départ)
Je sais que la bibliothèque « SoftWareSerial.h » ne permettrait que la réception et non l'émission avec le MEGA. Cela me suffirait. Mais pourquoi ce "0" envoyé en premier. Faut-il changer les 9600 bauds ??? Y-a-til un problème de synchro ?
Ci-joint le loop du récepteur
void loop()
{
float freq = 0; // Déclaration de la donnée reçue
if (hc12.available()) // Si réception OK DE LA FREQUENCE
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
freq = hc12.parseFloat(); //Décodage de la réception : freq = NB_PULSE reçus de l'émetteur en 1s
temps_precedent = micros(); // Pour la mesure d'absence d'affichage en fin de loop
NB_PULSE_10s_INCREMENT = NB_PULSE_10s_INCREMENT + freq; // incrémente le nombre de front descendants observés en 10s (remis à 0 après 10s dans "Calculateur 10 min)
Serial.println(freq);
//Serial.println(NB_PULSE_10s_INCREMENT);
memoire_vmax_zero = 0; // permet de ne mettre à 0 la v instantannée max qu'une seule fois lorsque plus de 2.5s sans signal anemomètre
// Conversion fréquence en vitesse
if (freq == 0.0)
{
v = 0;
}
else if (freq <= 3.0)
{
v = 0.8 * freq ;
}
else
{
v = 3 + 0.8 * freq ;
}
// Calcul v_max_inst
if (affiche == 1)
{ // s'il y a eu affichage de la v_max_inst, elle est remise à zero
v_max_inst = 0; // remise à zero v_max_inst, de ce fait elle évolura entre l'affichage qui vient d'avoir lieu et le nouvel affichage à venir (toutes les 500ms)
affiche = 0; // on déclare que l'affichage est à faire pour la prochaine v max inst
}
if (v == 0)
{
v_max_inst = 0;
}
if (v > v_max_inst && v < 200)
{
v_max_inst = v; // évolution de la vitesse instantannée (je prends la vitesse instantanée maximale obtenue entre 2 affichages (affichage toutes les 500ms)
}
if (v > v_max_inst_bargraph && v < 200)
{
v_max_inst_bargraph = v; // évolution de la vitesse instantannée (je prends la vitesse instantanée maximale obtenue entre 2 affichages (affichage toutes les 500ms)
}
if (v > v_max && v < 200)
{
v_max = v; // évolution vitesse max.
}
//(1.8*v_precedente)) était 1.5 // calcul v max obtenue sur durée bloc de 10s, le coeff
//1.5 évite les aberrations de vitesse doublée qu'il y avait parfois
if (v > v_max_bloc_10s && v < 200)
{
v_max_bloc_10s = v; // évolution vitesse max. sert AUX CALCULS DES RAFALES
}
//pourcentage=(v);
pourcentage = (v_max_inst_bargraph);
percent = byte(pourcentage);
t_ecoule_bargraph = TEMPS_milli - t_debut_bargraph;
if (t_ecoule_bargraph > cadence_bargraph)
{
draw_progressbar(percent);
t_debut_bargraph = millis();
}
//Serial.print("v prec : ");
//Serial.print(v_precedente);
//Serial.print(" | v : ");
//Serial.print(v);
//Serial.print(" | v max : ");
//Serial.print(v_max);
//Serial.print(" | nb calc : ");
//Serial.print(nb_v_calc);
//Serial.print(" | dep : ");
//Serial.println(depassement);
if (v < 200)
{
v_precedente = v;
}
}//FIN IF hc12.available() ///////////////////////////// FIN IF HC12 AVAILABLE (remplace le ANEMO) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TEMPS_milli = millis(); // instant (ms) nécessaires pour cadence d'affichage
TEMPS_micros = micros(); // instant (µs) nécessaires remise à zero v instantanée "V_max_inst" si plus de 2 s sans signal
CALCULATEUR_10mn(); // appelle fonction de calcul des éléments sur 10mn d'observation
t_ecoule_affichage = TEMPS_milli - t_debut_affichage; // pour gérer cadence affichage
//////////////////////////////////////////////////////////////////////////////////
if (t_ecoule_affichage > cadence_affichage) // affichage selon cadence choisie mais au début, tant qu'il n'y a pas eu assez de front descendants, n'affiche rien
{
AFFICHEUR(); // appelle fonction d'affichage (appelée tts les 1s)
duree_v_nulle = TEMPS_micros - temps_precedent; // temps écoulé depuis le dernier front montant (sert à la mise à zero de la vitesse si pas de signal pendant plus de 2s
if ((duree_v_nulle > duree_remise_zero) && memoire_vmax_zero == 0) // si plus de 2 s sans signal anemo, v max est mise à 0 et affiche une seule fois
{
v_max_inst = 0;
memoire_vmax_zero = 1; // variable mémoire qui permet de ne mettre à zero la vitesse instantannée qu'une seule fois. Est remise à 0 quand nouveau front montant
percent = 0;
draw_progressbar(percent);
}
} //// FIN IF temps d'affichage dépassé /////////////////////////////////////
} ///// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP ////////// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP ///////////// FIN LOOP
Ravi de solliciter votre sympathique groupe. Merci pour votre aide.
Bonjour jpbbricole,
Merci pour cette réponse.
Si je ne charge pas la bibliothèque et que j'utilise le Serial0 avec TX en 1 et RX en 0, le HC-12 n'est pas déclaré et je ne peux lancer le "hc12.begin(9600)". J'ai toujours utilisé l'une ou l'autre des bibliothèques ave succès.
Mon seul problème est de savoir pourquoi ce "0" s'affiche avant la fréquence reçue qui s'affiche ensuite. Je n'ai pourtant aucune autre commande serial.print que celle de la fréquence. Mystère !
Bien cordialement.
Si on a des ports série "hard" comme dans le Mega, c'est perdre son temps que d'employer une bobliothèque pour en émuler.
Avec un Mega, il faut utiliser Serial1 ou Serial2 ou Serial3.
// Déclaratiion HC-12 avec AltSoftSerial.h
//#include <AltSoftSerial.h>
#define pinTX 18
#define pinRX 16
//AltSoftSerial hc12(pinRX,pinTX); // pour le MEGA : 1 -TX et 0 -RX !
Voici le debut du loop
void loop()
{
float freq = 0; // Déclaration de la donnée reçue
hc12.begin(pinTX,pinRX); // essai
if (hc12.available()) // Si réception OK DE LA FREQUENCE
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
freq = hc12.parseFloat(); //Décodage de la réception : freq = NB_PULSE reçus de l'émetteur en 1s
temps_precedent = micros(); // Pour la mesure d'absence d'affichage en fin de loop
NB_PULSE_10s_INCREMENT = NB_PULSE_10s_INCREMENT + freq; // incrémente le nombre de front descendants observés en 10s (remis à 0 après 10s dans "Calculateur 10 min)
Serial.println(freq);
Voici le message d'erreur reçu :
Compiling .pio\build\megaatmega2560\src\HC12_ANEMO_INTERRUPT_61_MEGA_F-Def-1s_Recepteur.cpp.o
src\HC12_ANEMO_INTERRUPT_61_MEGA_F-Def-1s_Recepteur.cpp: In function 'void setup()':
src\HC12_ANEMO_INTERRUPT_61_MEGA_F-Def-1s_Recepteur.cpp:697:3: error: 'hc12' was not declared in this scope
hc12.begin(9600); // Initialisation du HC-12
^~~~
La question est alors de savoir comment déclarer le HC12;
MERCI
Il semble que ta première version fonctionne, mais qu'une fois sur 2 il y a 0 comme valeur (milles excuses, je n'avais pas vu ce "détail" , donc, ce n'est pas du côté de la bibliothèque qu'il faut chercher, mais dans ce qui se passe dans loop().
A titre de cimparaison, je te donne ce que ChatGPT offre comme exemple:
// Pins for Serial1 on Arduino Mega
#define HC12_RX 19 // RX1 pin on Mega
#define HC12_TX 18 // TX1 pin on Mega
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
// Initialize Serial1 for HC-12 communication
Serial1.begin(9600);
Serial.println("HC-12 Ready");
}
void loop() {
// Check if data is available from HC-12
if (Serial1.available()) {
String receivedData = "";
// Read the data from HC-12
while (Serial1.available()) {
char c = Serial1.read();
receivedData += c;
}
// Print the received data to the Serial Monitor
Serial.println("Received from HC-12: " + receivedData);
}
// Check if data is available from Serial Monitor
if (Serial.available()) {
String sendData = Serial.readString();
// Send the data to HC-12
Serial1.print(sendData);
}
}
Merci. Waouh !... Si ChatGPT s'en mêle, où va-t-on ?
Voici ce que j'obtiens avec le code de l'"intelligence artificielle"
---- Ouverture du port série COM4 ----
HC-12 Ready
Received from HC-12: 1
Received from HC-12: 0
Received from HC-12: .
Received from HC-12: 00
Received from HC-12: 1
Received from HC-12: 0
Received from HC-12: .
Received from HC-12: 00
Received from HC-12: 1
Received from HC-12: 0
Received from HC-12: .
Received from HC-12: 00
Je connais ce type de récupération par chaîne, mais comment faire alors pour transformer ces "10Hz" reçus en valeur numérique seule ?
On va y arriver !
Merci.
Ca décoiffe
Voici la réponse complète.
La partie if (Serial.available()) peut être supprimée.
J'ai fait ainsi parce que je n'ai pas ce type d'interface pour faire des test "en vrai", et puis, ChatGPT est tellement pratique, pourquoi s'en passer, c'est un outil d'actualité?
Pour trabsformer la réception: float valeurRecue = receivedData.toFloat();
Désolé d'abuser de ton temps. Je ne suis pas loin du but.
Pour l'affichage de la valeur, j'ai ajouté "String" (en gras dans le code ci-dessous)
Cela m'affiche bien le "receivedData", (mais toutes les 20 loop).
J'essaie de vérifier si la conversion du String en numérique fonctionne en ajoutant 10. Apparemment non.
Sacrebleu !
Bien cordialement.
Encore merci.
void loop() {
// Check if data is available from HC-12
String receivedData = "";
// Read the data from HC-12
while (Serial1.available())
{
char c = Serial1.read();
**receivedData += String(c);**
delay(10);
}
// Print the received data to the Serial Monitor
Serial.println("Received from HC-12: " + receivedData);
valeurRecue = receivedData.toFloat();
Serial.println(valeurRecue);
// Vérification de la conversion en nombre
**valeurRecue = valeurRecue +10;**
** Serial.println(valeurRecue);**
Apparemment non !
---- Ouverture du port série COM4 ----
HC-12 Ready
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12: 151.00
151.00
161.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Pardon, je suis collant.
En fait cela marche, mais j'ai une vingtaine de loops entre deux affichages.
**Received from HC-12: 100.00**
**100.00**
**110.00**
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
**Received from HC-12: 100.00**
**100.00**
**110.00**
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
10.00
Received from HC-12:
0.00
En fait, je pense que l'affichage de la valeur (ici 150Hz) n'apparaît qu'à la fin de la réception des données Série1. La conversion n'est faite qu'à ce moment là et elle est active.
Je vais injecter tout cela dans mon programme initial de l'anémomètre.
Je ne te dérange plus.
Encore merci pour ta disponibilité et tes conseils ; et merci à ChatGPT, Vindiou !
A++
Bien cordialement
#include <Arduino.h>
// Pins for Serial1 on Arduino Mega
#define HC12_RX 19 // RX1 pin on Mega
#define HC12_TX 18 // TX1 pin on Mega
float valeurRecue= 0;
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
// Initialize Serial1 for HC-12 communication
Serial1.begin(9600);
Serial.println("HC-12 Ready");
}
void loop() {
// Check if data is available from HC-12
String receivedData = "";
// Read the data from HC-12
while (Serial1.available())
{
char c = Serial1.read();
receivedData += String(c);
delay(10);
}
// Print the received data to the Serial Monitor
Serial.println("Received from HC-12: " + receivedData);
valeurRecue = receivedData.toFloat();
Serial.println(valeurRecue);
// Vérification de la conversion en nombre
valeurRecue = valeurRecue +10;
Serial.println(valeurRecue);
}