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

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

Salut @jpbbricole

A quoi servent les heures et le timer dans cette structure ?

Attention à la notation des chiffres en commençant par un 0. Si on ne fait pas gaffe on va écrire 09 pour 9 minutes et le compilateur ne va pas être content parce qu'un nombre qui commence par 0 est écrit en octal (base 8). Bien sûr pour 00 ça ne pose pas de souci.

Une suggestion pour que la structure soit un peu optimisée (et que le tableau soit défini conformément aux types)

struct alarmesDef {int8_t heure; int8_t minute; bool executed; unsigned long timer;};
alarmesDef alarmes[]= {
  {0,  0, false, 0},     //Toutes les xx:00:xx
  {0, 30, false, 0},     //Toutes les xx:30:xx
};

La fonction alarmeCheck() me semble bizarre . Si les minutes correspondent vous mettez executed = true et vous déclenchez un enregistrement mais comme c'est long une minute vous allez revenir tester cette alarme dans la même minute, la fois d'après la minute va donc toujours correspondre et comme executed == false sera faux, vous allez le re-basculer à vrai et donc au prochain appel (on sera toujours dans la même minute sans doute) vous allez à nouveau déclencher un log.

--> une fois l'enregistrement pour une certaine minute déclenché, il ne faut pas le remettre à faux tant que l'horloge n'a pas dépassé cette minute (ou simplement au prochain changement d'heure)

Salut J-M-L

Le timer est un oubli lors du nettoyage d'une ancienne option, sans aucune influence sur le déroulement du programme.

Les heures, c'est expliqué ici:

Je te rassure, ça fonctionne très bien, je pense que tu est passé un peu "rapidement" sur sa lecture.

Cordialement
jpbbricole

Oui j'ai lu en diagonal et mal vu l'indentation, la désactivation se fait chaque fois que la minute change donc c'est bon

Déplacé tout ce qui suivait et qui n'avait aucune valeur ajoutée pour ce post dans le bar.

Bonjour J-M-L

Constaté dans un programme:
int v = 033; // Donne 27 (base ?)
v = 0100; // Donne 64 (base 16)

Je trouve le compilateur un peu "vicieux" une explication?

Merci par avance.

Cordialement
jpbbricole

Non, pas vicieux, simple notation en OCTAL.

Bonjour hbachetti

Compris, j'avais pris l'affichage pour du décimal!
Ok, merci, une fois de plus j'ai compris à l'envers :upside_down_face:

Cordialement
jpbbricole

3*x+3=27
Trouver x... :wink:

Bonjour lesept

= 8
C'est facile quand on comprends les choses à l'endroit, ce qui n'est pas toujours mon cas.
Croyant que l'affichage dans la console était du décimal, j'avais de la peine à savoir d'où sortait ce 27, surtout que manque de bol, 64 hexa donnait bien 100. Donc j'ai tout fait à l'envers.
Merci pour l'exercice.

Cordialement
jpbbricole

Oui c’est historique - pour faciliter la tâche du compilateur un nombre commençant par 0 a été défini comme de l’octal - c’est resté en C++