Récupérer et afficher les 10 dernières prise de température

Bonjour oasixm

Est-ce-que tu vois ta RTC avec un scan i2C?
Si non sur quelle pin sont connectés les signaux SDA et SCL?
Sur mon ESP32 TTGO, c'est SDA 21 et SCL 22
Essaies d'initialiser wire ainsi

Wire.begin(sdaPin, sclPin);

Ensuite essaies un nouveau scan i2C en initialisant wire de la même façon.

Cordialement
jpbbricole

Si tu as un Wi-Fi accessible il est possible de prendre l'heure via NTP

Après, c'est vrai que lorsque je t'ai proposé le code au départ, j'ai sous estimé le problème des huit heures. Il est plus simple de faire 3 tableaux : un pour la mesure, un pour l'heure et un pour la date.

1 Like

Bnjour oasixm

Pour le sport, je me suis prêté à l’exercice de lister les 10 dernières mesures.
Voilà le résultat de ma gamberge :

/*
    Name:       ARDFR_mormic10derniers.ino
    Created:	02.07.2021
    Author:     jpbbricole
*/
#include "RTClib.h"
RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//------------------------------------- Journal des mesures
const int mesuresNombre = 10;

struct mesuresJournalDef
{String dateHeure; float pression;};
mesuresJournalDef mesuresJournal[mesuresNombre];

//------------------------------------- Tempo pour affichage
unsigned long displayTemps = millis();
unsigned long displayTempo = 2000;

#define btnJournal 12         // Bouton pour déclencher l'affichage du journal
	
void setup()
{
   Serial.begin(115200);
   pinMode(btnJournal, INPUT_PULLUP);
   
   if (! rtc.begin()) {
	   Serial.println("Couldn't find RTC");
	   Serial.flush();
	   abort();
   }

   if (! rtc.isrunning()) {
	   Serial.println("RTC is NOT running, let's set the time!");
	   // When time needs to be set on a new device, or after a power loss, the
	   // following line sets the RTC to the date & time this sketch was compiled
	   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	   // This line sets the RTC with an explicit date & time, for example to set
	   // January 21, 2014 at 3am you would call:
	   // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
   }
}

void loop()
{
    if (millis()-displayTemps >= displayTempo)
    {
		mesureDansJournal();

		Serial.print(mesuresJournal[0].dateHeure);
		Serial.print("\tp: ");
		Serial.println(mesuresJournal[0].pression);
		
		displayTemps = millis();		
    }
	
	if (digitalRead(btnJournal) == LOW)
	{
		journalListe();
		
		while(digitalRead(btnJournal) == LOW){}
		Serial.println("");
	}
}

void mesureDansJournal()
{
	//--------------------------------- Décalage du journal vers "le bas"
	for (int j = mesuresNombre-1; j > 0; j --)
	{
		mesuresJournal[j] = mesuresJournal[j-1];
		
	}
	
	mesuresJournal[0].dateHeure = dateHeure();
	mesuresJournal[0].pression = pressionMesure();
}

/*-------------------------------------------------------------------
	Affichage du journal des mesures
	Le journal est décalé de telle façon que la dernière mesure 
	se trouve en tete
'*-------------------------------------------------------------------
*/
void journalListe()
{
	Serial.println("\n\tJournal des mesures");

	for (int j = 0; j < mesuresNombre; j ++)
	{
		Serial.print(mesuresJournal[j].dateHeure);
		Serial.print("\tp: ");
		Serial.println(mesuresJournal[j].pression);
	}
		
}

String dateHeure()
{
	String retVal = "";
	
	DateTime now = rtc.now();
	
	retVal = (String)daysOfTheWeek[now.dayOfTheWeek()] + ", "; 
	retVal += now.timestamp(2) +"/";     // Date
	retVal += now.timestamp(1);     // Heure
	
	return retVal;
}

float pressionMesure()
{
	static float pression = 12.124;
	pression += 0.13;
	
	if (pression > 22.0)
	{
		pression = 12.1;
	}
	return pression;
}

Les données, date et mesures se trouvent dans un tableau sous forme de structure mesuresJournal[mesuresNombre].
Les mesures de pression se font dans float pressionMesure(). Elles sont bidon, je n’ai pas ce capteur.
Tout les tant de temps la date et la pression sont mis dans le journal et ceci de telle façon que la dernière mesure se trouve en tête de la liste (indice [0]).
Pour déclencher les mesuresNombre dernières mesures, j’ai attribué un bouton (btnJournal), quand il y a LOW sur l’entrée la liste des mesures s’affiche dans le moniteur.

A ta disposition pour touts renseignements.

Cordialement
jpbbricole

Salut @jpbbricole

L'avantage de décaler les éléments a chaque lecture c'est que le tableau reste ordonné et il suffit donc d'enregistrer la nouvelle lecture à la position 0. L'autre avantage, c''est que c'est simple à lire.

Un inconvénient c'est le coût du décalage en terme de temps CPU et impact mémoire (ici vous recopiez par duplication les chaînes qui représentent l'heure par exemple). Avec 10 mesures, ça doit rester gérable mais quand on commence à vouloir conserver 500 mesures c'est plus problématique.

L'idée si on est contraint en mémoire ou performance est donc de garder dans une variable le "zéro relatif" du tableau et en faire ce que l'on appelle un tableau circulaire. Imaginons que l'on garde 5 valeurs et que le tableau ait été rempli case après case (depuis la case 0).

  • les 5 dernières valeurs sont donc aux indices 4, 3, 2, 1 et 0 et la prochaine case à remplir est à l'indice 0
  • au coup suivant, les 5 dernières valeurs sont aux indices 0, 4, 3, 2 et 1et la prochaine case à remplir est à l'indice 1
  • au coup suivant, les 5 dernières valeurs sont aux indices 1, 0, 4, 3 et 2 et la prochaine case à remplir est à l'indice 2
  • au coup suivant, les 5 dernières valeurs sont aux indices 2, 1, 0, 4 et 3 et la prochaine case à remplir est à l'indice 3
  • ...
    --> en mémorisant donc uniquement cette position de "la prochaine case à remplir" et en la faisant tourner (et revenir à 0 une fois arrivé au bout du tableau) on n'a plus à décaler les éléments ➜ c'est l'idée des autres codes proposés et la fonction modulo (%) permet de gérer le retour à 0 de cet indice.

Cela dit, pour un petit besoin de mémorisation et si le code ne tourne pas trop longtemps (risques possibles liés à la classe String et toutes les concaténations que vous effectuez) ça va fonctionner très bien.

PS/ pour rendre plus efficace votre code tant au niveau mémoire nécessaire que performance lors du décalage, vous pourriez stocker uniquement un uint32_t pour l'heure de mesure (la fonction dateHeure() retournerait simplement now. unixtime(); et c'est la fonction journalListe() qui se chargerait de convertir la date en texte, uniquement pour l'écriture sur écran.

Bonjour J-M-L

Je m'y était "attelé" mais mes vieux neurones n'avaient rien sorti de bon donc, solution de facilité... Mais je vais quand appliquer cette solution.

Excellente idée.
Dès que j'ai un moment, je vais appliquer ces 2 modifications.

Cordialement
jpbbricole

Bonjour

Voilà la version corrigée, que dis-je améliorée.
La structure du journal a légèrement changé.
de

struct mesuresJournalDef
{String dateHeure; float pression;};
mesuresJournalDef mesuresJournal[mesuresNombre];

à

struct mesuresJournalDef
{DateTime now;  float pression;};
mesuresJournalDef mesuresJournal[mesuresNombre];

Le programme (l'explication de post #48 est toujours valable)

/*
    Name:       ARDFR_mormic10derniers.ino
    Created:	02.07.2021
    Author:     jpbbricole
*/
#include "RTClib.h"
RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//------------------------------------- Journal des mesures
const int mesuresNombre = 10;

struct mesuresJournalDef
{DateTime now;  float pression;};
mesuresJournalDef mesuresJournal[mesuresNombre];

int journalIndex = 0;     
int journalIndexListe[mesuresNombre];

//------------------------------------- Tempo pour affichage
unsigned long displayTemps = millis();
unsigned long displayTempo = 2000;

#define btnJournal 12         // Bouton pour déclencher l'affichage du journal
	
void setup()
{
	Serial.begin(115200);
	pinMode(btnJournal, INPUT_PULLUP);
   
	if (! rtc.begin()) {
		Serial.println("Couldn't find RTC");
		Serial.flush();
		abort();
	}

	if (! rtc.isrunning()) {
		Serial.println("RTC is NOT running, let's set the time!");
		rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	}

	for (int i = 0; i < mesuresNombre; i ++)
	{
		journalIndexListe[i] = -1;     // Index inutilisé
	}

	journalIndex = -1;
	mesureDansJournal();
}

void loop()
{
    if (millis()-displayTemps >= displayTempo)
    {
		mesureDansJournal();
		journalListeOne(journalIndexListe[journalIndex]);
		
		displayTemps = millis();		
    }
	
	if (digitalRead(btnJournal) == LOW)
	{
		journalListe();
		
		while(digitalRead(btnJournal) == LOW){}
		Serial.println("");
	}
}

void mesureDansJournal()
{
	journalIndex += 1;
	journalIndex = journalIndex >= mesuresNombre ? 0 : journalIndex;

	mesuresJournal[journalIndex].now = rtc.now();
	mesuresJournal[journalIndex].pression = pressionMesure();
	
	//--------------------------------- Décalage de l'index du journal vers "le bas"
	for (int i = mesuresNombre-2; i >= 0; i --)
	{
		journalIndexListe[i+1] =journalIndexListe[i];
	}
	journalIndexListe[0] = journalIndex;
}

/*-------------------------------------------------------------------
	Affichage du journal des mesures
	Le journal est décalé de telle façon que la dernière mesure 
	se trouve en tete
'*-------------------------------------------------------------------
*/
void journalListe()
{
	Serial.println("\n\tJournal des mesures");

	for (int i = 0; i < mesuresNombre; i ++)
	{
		if (journalIndexListe[i] != -1)     // Si index utilisé
		{
			journalListeOne(i);
		}
	}
		
}

void journalListeOne(int journalIndex)
{
	Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(2) +"/");
	Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(1) +"\t p:");
	Serial.println(mesuresJournal[journalIndexListe[journalIndex]].pression);
}

String dateHeure()
{
	String retVal = "";
	
	DateTime now = rtc.now();
	
	retVal = (String)daysOfTheWeek[now.dayOfTheWeek()] + ", "; 
	retVal += now.timestamp(2) +"/";     // Date
	retVal += now.timestamp(1);     // Heure
	
	return retVal;
}

float pressionMesure()
{
	static float pression = 12.124;
	pression += 0.13;
	
	if (pression > 22.0)
	{
		pression = 12.1;
	}
	return pression;
}

Cordialement
jpbbricole

1 Like

Bravo, je suis fasciné par les programmes que vous faites si rapidement pendant que moi je galère :slight_smile:
J'ai donc essayé ton programme j'ai ce message d'erreur qui ressort .
pour le mettre avec mon capteur de température je dois changer le float pressionMesure () c'est ça ?

C:\Users\Commercial\Documents\Arduino\test_temp-histo3\test_temp-histo3.ino: In function 'String dateHeure()':
test_temp-histo3:107:28: error: invalid conversion from 'int' to 'DateTime::timestampOpt' [-fpermissive]
   retVal += now.timestamp(2) +"/";     // Date
                            ^
In file included from C:\Users\Commercial\Documents\Arduino\test_temp-histo3\test_temp-histo3.ino:6:0:
C:\Users\Commercial\Documents\Arduino\libraries\RTClib/RTClib.h:148:10: note:   initializing argument 1 of 'String DateTime::timestamp(DateTime::timestampOpt)'
   String timestamp(timestampOpt opt = TIMESTAMP_FULL);
          ^
test_temp-histo3:108:28: error: invalid conversion from 'int' to 'DateTime::timestampOpt' [-fpermissive]
   retVal += now.timestamp(1);     // Heure
                            ^
In file included from C:\Users\Commercial\Documents\Arduino\test_temp-histo3\test_temp-histo3.ino:6:0:
C:\Users\Commercial\Documents\Arduino\libraries\RTClib/RTClib.h:148:10: note:   initializing argument 1 of 'String DateTime::timestamp(DateTime::timestampOpt)'
   String timestamp(timestampOpt opt = TIMESTAMP_FULL);
          ^
exit status 1
invalid conversion from 'int' to 'DateTime::timestampOpt' [-fpermissive]

remplacez dans le code de @jpbbricole

au début la définition de daysOfTheWeek

const char* daysOfTheWeek[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

et ensuite les 2 fonctions par

void journalListeOne(int journalIndex)
{
  Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(DateTime::TIMESTAMP_DATE));
  Serial.write('/');
  Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(DateTime::TIMESTAMP_TIME));
  Serial.print(F("\t p:"));
  Serial.println(mesuresJournal[journalIndexListe[journalIndex]].pression);
}

String dateHeure()
{
  String retVal = "";

  DateTime now = rtc.now();

  retVal = (String) daysOfTheWeek[now.dayOfTheWeek()] ;
  retVal += ", ";
  retVal += now.timestamp(DateTime::TIMESTAMP_DATE);    // Date
  retVal += "/";
  retVal += now.timestamp(DateTime::TIMESTAMP_TIME);    // Heure

  return retVal;
}

niquel ça fonctionne mais voici le résultat
image
ça lit les valeurs et ne les sauvegardes pas il me semble

Bonjour J-M-L

Pour le const char* ça m'a échappé, mais pour le reste, ça change quoi?

Cordialement
jpèbbricole

Bonjour oasixm

Tu voudrais les sauvegarder où?

Cordialement
jpbbricole

Bonjour,
L'objectif final est que ça sauvegarde mes valeurs de température toute les 30 minutes, puis je fais un bouton et quand j'appuie sur ce bouton ça les envoies par Bluetooth .
Ducoup pour le moment je voulais un programme qui me sauvegardais mes valeurs toute les 30 minutes pendant 8 heures soit 16 valeurs .
Mais il faudrait que ça sauvegarde les 8h et 8h30 pas 8h23 sinon ça s'actualise trop.
Tu as compris ? :slight_smile: j'explique mal

le const char * c'est juste de l'optimisation mémoire

pour le reste la méthode timestamp() attend un paramètre de type timestampOpt
c'est un type énuméré

bien que les valeurs associées aux éléments soient 0,1 et 2 le compilateur C++ est en droit de refuser une conversion d'un entier vers ce type et c'est le message d'erreur qui a été donné.

invalid conversion from 'int' to 'DateTime::timestampOpt'

En utilisant DateTime::TIMESTAMP_DATE et DateTime::TIMESTAMP_TIME on fournit bien un paramètre du type attendu et le compilateur est content.

la séparation des print() en plusieurs lignes au lieu de faire '+' c'est pour éviter de créer des sous string temporaires qui n'apportent rien de bon (morcellement mémoire possible, allocation de gros buffers pour stocker la chaîne intermédiaire, ralentissement du code)

Bonjour J-M-L

J'avais essayé de mettre TIMESTAMP_FULL, TIMESTAMP_TIME et TIMESTAMP_DATE et j'avais eu des erreurs, c'est pourquoi j'avais mis 1 et 2 et ça a passé, d'où provient ce 2 interprétation du compilateur?

Cordialement
jpbbricole

Oui, comme l'enum est embarqué au sein de la classe, sa visibilité est locale et donc les mots clés ne sont pas connus en dehors.
Pour que le compilateur sache de quoi on parle, Il faut donc rajouter la classe devant, donc écrire DateTime::TIMESTAMP_DATE et pas juste TIMESTAMP_DATE.

ça peut passer suivant la version de l'IDE ou le type de carte utilisée (ie la version du compilateur). La norme C++ dit que ce n'est pas OK mais certains compilateurs sont flexibles (car en C ça se faisait souvent - je crois qu'il faut aussi fixer le type de l'énumération sans doute et faire un static cast sinon)

Boonsoir J-M-L

J'utilises Atmel Studio avec le plug Visual Micro qui "compile avec l'IDE Arduino" (je ne sait pas expliquer cette mécanique, c'est en dehors de mes cordes) donc j'ai le même compilateur que @oasixm ?

Mystère, mystère!

Cordialement
jpbbricole

mon compilateur sur AVR met un warning mais n'arrête pas la compilation

warning: invalid conversion from 'int' to 'DateTime::timestampOpt' [-fpermissive]
retVal += now.timestamp(1); // Heure

c'est l'option -fpermissive du compilateur qui fait cela: il oblige le compilateur à signaler certaines choses qui sont en fait des erreurs (mais sont autorisées par certains compilateurs) en tant qu'avertissements

faudrait voir si ce drapeau est passé dans votre chaîne de compilation

Sur un ESP32 (la plateforme utilisée) là il n'est pas content, j'ai bien

exit status 1
invalid conversion from 'int' to 'DateTime::timestampOpt' [-fpermissive]

avez vous testé sur ESP32 ?

Bonsoir oasixm

Oui, je crois que j'ai compris.
Le programme actuel est une version "accélérée", toutes les displayTempo millisecondes (2000) et n'enregistre que mesuresNombre (10) mesures. et ne tient pas compte de l'heure.
Je vais voire comment faire pour enregistrer tout les nnh00 et nnh30 (c'est juste?).
Question, si tu presses le bouton après les 8 heures, la mémoire aura fait un tour complet, ce qui veut dire que tu perdra des données?

Dernier point, si je te fais une nouvelle version, comme je n'ai pas ta sonde, tu devra réactualiser la partie float pressionMesure()

Si tu as déjà intégré ta sonde dans le programme, mets le programme en ligne afin que je puisse voire comment ta sonde se traite.

L'ESP32 se prête très bien à ça, sur quoi envoies-tu ces données, un smartphone, si oui dans quel programme ? As-tu déjà un interface Bluetooth pour ton Arduino comme le HC-06.

Bonne soirée
Cordialement
jpbbricole

bonjour @jpbbricole et merci
Voici le programme exemple de mon capteur (bme280)

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
  See the LICENSE file for details.
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup() {
    Serial.begin(9600);
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));

    unsigned status;
    
    // default settings
    status = bme.begin();  
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    Serial.println("-- Default Test --");
    delayTime = 1000;

    Serial.println();
}


void loop() { 
    printValues();
    delay(delayTime);
}


void printValues() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" °C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();
}

Le bouton, c'est une clic sur mon écran
nnh00 et nnh30 c'est juste.
oui je perdrai mes données à chaque tour complet
Pour le bluetooth j'utilise mon esp32 , quand j'ai test le bluetooth j'utilisais serial bluetooth manager

Bonjour oasixm
J’ai intégré la possibilité de faire des tâches périodiques, pour le moment, uniquement basé sur les minutes. Ainsi tu pourras avoir un enregistrement des mesures tous les xx :00 :xx et xx :30 ;xx.
Par manque d’imagination, j’ai appelé ça des alarmes.
Les minutes des alarmes se mettent dans ce tableau :

alarmesDef alarmes[]=
{
{0, 00, 0}, //Toutes les xx:00:xx
{0, 30, 0}, //Toutes les xx:30:xx
};

Si tu veux toutes les 15 minutes :

alarmesDef alarmes[]=
{
{0, 00, 0}, //Toutes les xx:00:xx
{0, 15, 0}, //Toutes les xx:15:xx
{0, 30, 0}, //Toutes les xx:30:xx
{0, 45, 0}, //Toutes les xx:45:xx
};

Ou n’importe quand :

alarmesDef alarmes[]=
{
{0, 07, 0},
{0, 23, 0},
{0, 12, 0},
{0, 55, 0},
};

Les alarmes sont traitées dans l’ordre chronologique des minutes et non pas dans l’ordre de leur place dans le tableau.

Comme je n’ai pas de sonde BME280 (c’est en commande), je ne l’ai pas intégrée dans cette version, je te laisse le faire.
Pour ajouter ces alarmes, je suis parti de la version corrigée du post #51.
La nouvelle version (cherches alarme dans le programme pour voire les ajouts)

/*
    Name:       ARDFR_oasixm10derniers.ino
    Created:	08.07.2021
    Author:     jpbbricole
*/
#include "RTClib.h"
RTC_DS1307 rtc;

const char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

//------------------------------------- Alarmes
struct alarmesDef
{int heure; int minute; boolean executed;};
alarmesDef alarmes[]= 
{
	{0,  0, 0},     //Toutes les xx:00:xx
	{0, 30, 0},     //Toutes les xx:30:xx
};
const int almNombre = sizeof(alarmes)/sizeof(alarmes[0]);     // Nombre d'alarmes

//------------------------------------- Journal des mesures
const int mesuresNombre = 10;

struct mesuresJournalDef
{DateTime now;  float pression;};
mesuresJournalDef mesuresJournal[mesuresNombre];

int journalIndex = 0;     
int journalIndexListe[mesuresNombre];

#define btnJournal 12         // Bouton pour déclencher l'affichage du journal
	
void setup()
{
	Serial.begin(115200);
	pinMode(btnJournal, INPUT_PULLUP);

	if (! rtc.begin()) {
		Serial.println("Couldn't find RTC");
		Serial.flush();
		abort();
	}

	if (! rtc.isrunning()) {
		Serial.println("RTC is NOT running, let's set the time!");
		rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	}

	for (int a = 0; a < almNombre; a ++)
	{
		alarmes[a].executed = false;     // Pour débloquer l'alarme
	}
		
	for (int i = 0; i < mesuresNombre; i ++)
	{
		journalIndexListe[i] = -1;     // Index inutilisé
	}

	journalIndex = -1;
	
	Serial.print(F("Demarrage a ")); Serial.println(dateHeure());
	
	if (almNombre > 0)
	{
		Serial.print(F("\nAlarmes(s) ")); Serial.println(almNombre);
		for (int a = 0; a < almNombre; a ++)
		{
			Serial.print(alarmes[a].heure); Serial.print(":");
			Serial.print(alarmes[a].minute); Serial.print(":");
			Serial.println("00");
		}
	}
}

void loop()
{
	//--------------------------------- Alarmes
	for (int a = 0; a < almNombre; a ++)
	{
		if (alarmeCheck(a))     // S'il y a alarme
		{
			mesureDansJournal();
			journalListeOne(journalIndexListe[journalIndex]);
		}
		
	}
	
	if (digitalRead(btnJournal) == LOW)
	{
		journalListe();
		
		while(digitalRead(btnJournal) == LOW){}
		Serial.println("");
	}
}

void mesureDansJournal()
{
	journalIndex += 1;
	journalIndex = journalIndex >= mesuresNombre ? 0 : journalIndex;

	mesuresJournal[journalIndex].now = rtc.now();
	mesuresJournal[journalIndex].pression = pressionMesure();
	
	//--------------------------------- Décalage de l'index du journal vers "le bas"
	for (int i = mesuresNombre-2; i >= 0; i --)
	{
		journalIndexListe[i+1] =journalIndexListe[i];
	}
	journalIndexListe[0] = journalIndex;
}

/*-------------------------------------------------------------------
	Affichage du journal des mesures
	Le journal est décalé de telle façon que la dernière mesure 
	se trouve en tete
'*-------------------------------------------------------------------
*/
void journalListe()
{
	Serial.println("\n\tJournal des mesures");

	for (int i = 0; i < mesuresNombre; i ++)
	{
		if (journalIndexListe[i] != -1)     // Si index utilisé
		{
			journalListeOne(i);
		}
	}
		
}

void journalListeOne(int journalIndex)
{
	Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(DateTime::TIMESTAMP_DATE) +"/");
	Serial.print(mesuresJournal[journalIndexListe[journalIndex]].now.timestamp(DateTime::TIMESTAMP_TIME) +"\t p:");
	Serial.println(mesuresJournal[journalIndexListe[journalIndex]].pression);
}

String dateHeure()
{
	String retVal = "";
	
	DateTime now = rtc.now();
	
	retVal = (String)daysOfTheWeek[now.dayOfTheWeek()]; 
	retVal += ", ";
	retVal += now.timestamp(DateTime::TIMESTAMP_DATE);     // Date
	retVal += "/";
	retVal += now.timestamp(DateTime::TIMESTAMP_TIME);     // Heure
	
	return retVal;
}

float pressionMesure()
{
	static float pression = 12.124;
	pression += 0.13;
	
	if (pression > 22.0)
	{
		pression = 12.1;
	}
	return pression;
}

//--------------------------------- Alarmes
boolean alarmeCheck(int almIndex)
{
	boolean almOk = false;

	DateTime almTime = rtc.now();
	if (alarmes[almIndex].minute == almTime.minute() )     // Si alarme libre
	{
		if (alarmes[almIndex].executed == false)     // Si l'alarme n'est pas en exécution
		{
			alarmes[almIndex].executed = true;
			almOk = true;
		}
	}
	else
	{
		alarmes[almIndex].executed = false;     // Libérer l'alarme
	}

	return almOk;
}

A ta disposition
Cordialement

Jpbbricole