besoin d'aide pour programme arduino gestion de température avec log

Bonjour,
Premier post sur le forum
je vais essayer d’etre comprit
Je possede
-le ds18b20 (sonde température) 1-wire
-arduino uno
-shield ethernet +sd

et je voudrait :
-affiche la temp sur une page web
-enregistré la temp tous les jours sur carte sd
-comparer la valeur afin d’activer le chaufage ou non !

voici mes bout de programme

COMPARAISON DE TEMP POUR RELAIS

// Déclaration des pins
const int temp = A0;    // pin d'entrée capteur
const int relay = 13;       // pin sortie relais
// variables
// Valeurs à déterminer en faonction du capteur (tension délivrée par le capteur)
int tmin = 0;            // t° min
int tmax = 1024;            // T° max
int t = 0;

void setup() {
  digitalWrite(relay, LOW);
}
void loop() {
  // Lecture t°:
  t = analogRead(temp);
 
  //Comparaison :
 
  if (t < tmin) {
   
    while (t < tmax){
          digitalWrite(relay, HIGH);
    };
         
  };
}

ENREGISTREMENT SUR SD

// --- Programme Arduino --- 
// Trame de code générée par le générateur de code Arduino
// du site www.mon-club-elec.fr 

// Auteur du Programme : X. HINAULT - Tous droits réservés 
// Programme écrit le : 18/02/1012

// ------- Licence du code de ce programme ----- 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

// ////////////////////  PRESENTATION DU PROGRAMME //////////////////// 

// -------- Que fait ce programme ? ---------
 /* Ce programme teste le stockage de valeurs issues
de mesures analogiques dans un fichier 
sur carte mémoire micro-SD
Données au format CSV pour utilisation directe
dans un tableur OpenOffice.  */ 

// --- Fonctionnalités utilisées --- 

// Utilise la connexion série vers le PC 
// Utilise la conversion analogique numérique 10 bits 
// Utilise une carte mémoire micro-SD avec le module Ethernet Arduino 
// Utilise une fonction permettant de connaitre la RAM restant disponible

// -------- Circuit à réaliser --------- 

// La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB) 

// Le module Ethernet est à enficher broche à broche sur la carte Arduino 
// Connecter broche SCLK du module Ethernet sur la broche 13
// Connecter broche MISO du module Ethernet sur la broche 12
// Connecter broche MOSI du module Ethernet sur la broche 11
// Connecter broche Select Ethernet du module Ethernet sur la broche 10
// Connecter broche Select SD Card du module Ethernet sur la broche 4
// Le module Ethernet est compatible avec la carte Mega via le connecteur ICSP

// Broche 14 : Une résistance variable de 10 KOhms

// /////////////////////////////// 1. Entête déclarative /////////////////////// 
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables, les objets utiles...

// --- Déclaration des constantes ---

// --- Inclusion des librairies ---

#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD

// --- Déclaration des constantes utiles ---

// --- Déclaration des constantes des broches E/S numériques ---

const int brocheSDCardSelect=4; // broche utilisée pour sélectionner la SD card 

// --- Déclaration des constantes des broches analogiques ---

const int analog0= A0; // Constante pour la broche analogique 0

// --- Déclaration des variables globales ---

int mesure_brute=0;// Variable pour acquisition résultat brut de conversion analogique numérique
float mesuref=0.0;// Variable pour calcul résultat décimal de conversion analogique numérique

int test; // Variable utilisée pour tester valeur renvoyée par fonctions SD Card


// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---

/*
Sd2Card card; // création d'un objet Sd2Card
SdVolume volume; // création d'un objet SdVolume
SdFile root; // création d'un objet SdFile pour le répertoire racine
SdFile file; // création d'un objet SdFile pour le fichier utilisé
*/

File file; // objet file 
File root; // objet root pour le répertoire racine


// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation ////////////////////////// 
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

// --- ici instructions à exécuter 1 seule fois au démarrage du programme --- 

// ------- Initialisation fonctionnalités utilisées -------  

Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission 

//---- initialise l'utilisation de la carte mémoire SD en mode SPI  
pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet!

  //----- initialisation de la carte SD ----- 
  Serial.println("Initialisation de la SD card...");

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  test=SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

  if (test!=true) { // si initialisation n'est pas réussie
    Serial.println("Echec initialisation!"); // message port Série
  }
  else { // si nitialisation réussie
    Serial.println("Initialisation reussie !"); // message port Série

  //----- affiche le contenu du répertoire 

  root = SD.open("/"); // ouvre la SD Card à la racine

  Serial.println("Repertoire racine ouvert !");

  } // fin si initialisation réussie

// ------- Broches en sorties numériques -------  

// ------- Broches en entrées numériques -------  

// ------- Activation si besoin du rappel au + (pullup) des broches en entrées numériques -------  

// ------- Initialisation des variables utilisées -------  

} // fin de la fonction setup()
// ********************************************************************************

////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

  //---- efface fichier au préalable ---
  test=SD.remove("data.txt"); // efface fichier et mémorise résultat opération  
  if (test) Serial.println("Fichier efface"); // affiche message si fichier bien effacé

  //---- crée fichier en écriture --- 
  file = SD.open("data.txt", FILE_WRITE); // ouvre le fichier en écriture
  // NB : le fichier est créé si il n'existe pas !

  //---- test si fichier dispo en écriture 
  if (!file) { // si fichier pas dispo 

    Serial.println ("Erreur ouverture fichier !");

  } // fin if

  else { // si le fichier existe et est ouvert 

    Serial.println ("Fichier pret pour ecriture !");

    //----- Ecriture dans le fichier au format CSV ----- 

    // premiere ligne du fichier CSV - entete avec liste des champs
    file.println("NumeroMesure;ValeurBrute;ValeurFloat;Millis");

    Serial.println ("Enregistrement en cours :");

    for (int i=0; i<1000; i++) { // n mesures CAN 

      // acquisition conversion analogique numérique (100µs env.) sur broche analogique indiquée
      mesure_brute= analogRead(A0) ; 

      // calcul tension en Volts
      mesuref=mesure_brute*5.0;
      mesuref=mesuref/1023.0; 

      // valeur premier champ
      file.print(i), file.print(';'); 

      // valeur deuxieme champ
      file.print(mesure_brute), file.print(';'); 

      // valeur troisieme champ
      file.print(mesuref), file.print(';'); 

      // valeur quatrieme champ
      file.print(millis());

      // le dernier champ doit se terminer par un saut de ligne +++
      file.println();

      delay(10); // entre chaque mesure
      if ((i+1)%50) Serial.print("."); else  Serial.println(".");// affiche ligne de 50 points

    } // fin boucle for

    file.close(); // ferme le fichier
    Serial.println("Fin enregistrement !");  
    Serial.println("Fermeture fichier !");  

    Serial.println("Retirez SD-Card et la lire sur le PC !");  


  } // fin else

  while(1); // stoppe loop

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

AFFICHAGE WEB me pose des problemme

question?
comment faire pour intégré une variable dans une page web et comment intégré la variable de temp la partie comparaison .

thanks

Réglement et charte du forum... à lire impérativement avant de poster http://arduino.cc/forum/index.php/topic,102175.0.html

Pensez à l'utilisation des balises [code][/code] pour nous exposer votre code.

Bouton

Bonjour,

Pour la partie web regarde du coté de "webduino" sur google ;)

Au passage, copier des morceaux de code par ci par là n'apportera rien de bon à la fin. Il faut comprendre les morceaux, puis faire son propre code. Ce sera plus propre et il y a aura pas d'erreurs du a des conflit entre plusieurs morceaux.

désolé

merci pour cet indice

C'est beaucoup mieux. :grin: ;) Sinon en ce qui concerne ta question, il suffit d'intégrer ta mesure dans la chaine de caractère de ton code html en réponse à la requête. Maintenant comme Skywodd te le conseil, il faut évité de copier du code par ci par là mais plutôt le comprendre, faire des testes (même si ça ne correspond pas au but final) , modifier, etc ...

Une chose me perturbe quand même :

  while(1); // stoppe loop

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

Attention à ce "stoppe loop" qui bloque tout simplement ton programme ... donc contrairement au commentaire suivant loop ne recommencera pas au début ... au temps tout mettre dans le setup alors :~ (ou alors reset entre chaque insertion ??? j'ai pas de sd donc ...)

Bonsoir,

j’avance doucement merci pour vos conseils !

voici une nouvelle version mais je n’arrive pas a afficher la page web !!!

une idée ?

les fonction sont mal séparé ?
est il possible d’afficher l’heure sur un uno sans shield supplémentaire ?

cdt

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
	//Déclaration des Pins
	const int relay = 13;       // pin sortie relais

	#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
	#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds

// Fonction récupérant la température depuis le DS18B20
	// Retourne true si tout va bien, ou false en cas d'erreur
	boolean getTemperature(float *temp){
	  byte data[9], addr[8];
	  // data : Données lues depuis le scratchpad
	  // addr : adresse du module 1-Wire détecté
	 
	  if (!ds.search(addr)) { // Recherche un module 1-Wire
	    ds.reset_search();    // Réinitialise la recherche de module
	    return false;         // Retourne une erreur
	  }
	   
	  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
	    return false;                        // Si le message est corrompu on retourne une erreur
	 
	  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
	    return false;         // Si ce n'est pas le cas on retourne une erreur
	 
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	   
	  ds.write(0x44, 1);      // On lance une prise de mesure de température
	  delay(800);             // Et on attend la fin de la mesure
	   
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad
	 
	  for (byte i = 0; i < 9; i++) // On lit le scratchpad
	    data[i] = ds.read();       // Et on stock les octets reçus
	   
	  // Calcul de la température en degré Celsius
	  *temp = ((data[1] << 8) | data[0]) * 0.0625;
	   
	  // Pas d'erreur
	  return true;
	}

// variables
// Valeurs à déterminer

    int tmin = 10;            // t° min // Valeur réelle en °C

    int tmax = 25;            // T° max // valeur réelle en °C

    int t = 0;


	
// Définir l'adresse MAC et l'IP de la carte
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3D, 0x0A };
byte ip[] = { 192,168,1,20 };

// Initialisation de la bibliothèque Ethernet server 
// avec l4IP définie et le port (80 par défaut en HTTP)
EthernetServer server(80);

void setup()
{
digitalWrite(relay, LOW);
Serial.begin(9600); // Initialisation du port série
// démarrage de la connection Ethernet connection et du serveur:
Ethernet.begin(mac, ip);
server.begin();
}

void loop()
{
// attente de clients (un navigateur web par exemple)
EthernetClient client = server.available();
float temp;
if (client) {

    // une demande HTTP se termine par une ligne vide
    boolean currentLineIsBlank = true;
    while (client.connected()) {

        if (client.available()) {

            char c = client.read();
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank) {
            // Header HTTP usuel
            //
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();

            // renvoie la valeur de la tension de la pin analogique 0
            // et fait la conversion en celsius
            // le tout dans une page HTML5 !
            client.print("<!doctype html><html><head><meta charset='utf-8'/><title>Serveur de température Arduino</title>");
            // script qui réactualise la page toutes les 1000 mSec
            client.print("<script type='text/javascript'>function reFresh() {  location.reload(true) } window.setInterval('reFresh()',1000); </script>");
            client.print("</head><body><html>");
            client.print("<h1 style='font-family:verdana;'>Serveur de Température - Arduino</h1>");
            client.print("<p style='font-family:arial;color:red;font-size:20px;'>La temperature relevée sur l'entrée ");
            client.print(" est de : ");
            client.print(temp);
            client.println(" °C.</p></body></html>");
            

        break;

    }

    if (c == '\n') {

    // you're starting a new line
    currentLineIsBlank = true;
    }
    else if (c != '\r') {

            // you've gotten a character on the current line
            currentLineIsBlank = false;

            }

        }

    }

    // on laisse du temps au navigateur web de recevoir les données
    delay(1);
    // close the connection:
    client.stop();

    }
	/* --- Affiche la temperature dans le moniteur serial ---*/
     
	  // Lit la température ambiante à ~1Hz
	  if(getTemperature(&temp)) {
	     
	    // Affiche la température
	    Serial.print("Temperature : ");
	    Serial.print(temp);
	    Serial.write(176); // caractère °
	    Serial.write('C');
	    Serial.println();
}
  /*-----------------------------------------------------*/
  /*--- Comparaison et enclenchement du relais ---*/
  // Lecture t°:
  t = temp;
  //Comparaison :
  if (t < tmin) {
    while (t < tmax){digitalWrite(relay, HIGH); };
                  }
   else {digitalWrite(relay, LOW);}
   
   /*-------------------------------------------*/

delay(600000); // 10min 


}[/quote][code]

][/code]

jhonnyy: Bonsoir,

j'avance doucement merci pour vos conseils !

voici une nouvelle version mais je n'arrive pas a afficher la page web !!!

une idée ?

les fonction sont mal séparé ? [u]est il possible d'afficher l'heure sur un uno sans shield supplémentaire ?[/u]

cdt

bonsoir

Il faut proceder par etapes et sans les bruler ton code ne compile déjà pas !

regarde ici , il y a un bout code, j'avais mis une verrue 1wire sur le code http://arduino.cc/forum/index.php/topic,82555.msg624025.html#msg624025

ça affiche la T° d'un DS18B20 sur une page web attention le code est prevu pour que le 1W soit sur le pin digital4 pour changer de 4 en 7 modifier la ligne const int broche_OneWire=pinD04; //declaration constante de broche par const int broche_OneWire=pinD07; //declaration constante de broche

le DS18B20 est bien cablé ? avec sa R de 4.7K ? voir photos sur le lien

et attention à l'adresse IP 192, 168, 1, 167

apres il faut adapter

il compile je me suis trompé en envoyant une ancienne version .

Je vois pas ou le programme bloque!!!!

jhonnyy: il compile je me suis trompé en envoyant une ancienne version .

Je vois pas ou le programme bloque!!!!

Un peu de rigueur prealable ça ne fait pas de mal :grin: post ton code "qui compile" et mets ton code entre les balises codes `` pas les balises

désolé

merci pour vos conseils .

le code est envoyé

Yop Yop, Tu as testé séparément la partie ethernet de la partie temp ds18b20 ? Bien procédé par étapes et non tout un en d'un coup, essaie déjà la partie ethernet avec une valeur fictive pour la temp. Attention delay est bloquant donc ton code bloquera purement et simplement pendant ses 10 minutes ... :~ (

delay(600000); // 10min

http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Tu as testé séparément la partie ethernet de la partie temp ds18b20 ? oui j'ai testé et cela fonctionne

essaie déjà la partie ethernet avec une valeur fictive pour la temp. comment faire

Attention delay est bloquant donc ton code bloquera purement et simplement pendant ses 10 minutes ... smiley-confuse ( ah bon comment lui dire un loop(600000);

non ?

merci cdt

osaka: Yop Yop, Tu as testé séparément la partie ethernet de la partie temp ds18b20 ? Bien procédé par étapes et non tout un en d'un coup, essaie déjà la partie ethernet avec une valeur fictive pour la temp. Attention delay est bloquant donc ton code bloquera purement et simplement pendant ses 10 minutes ... :~ (

delay(600000); // 10min

http://arduino.cc/en/Tutorial/BlinkWithoutDelay

bonsoir osaka c'est de la compil sous IDE 1.0

la partie ds18B20 est OK (valeur OK sous serial au reset)

et en supprimant le delai (60000) c'est ok chez moi :grin: http://cjoint.com/12mi/BEbwyodUgkR_capt4021.jpg

Ca veut dire quoi "lui faire un loop(60000)" ?

Si tu connais un minimum de C tu comprendra peut être mieux ce que fot setup() et loop() en apprenant que la lib "core" de l'Arduino contient une fonction main() écrite comme ceci :

void main()
{
    setup();  // Appellé 1 seule fois pour initialiser les modules

    while(1)
        loop();   // Appellé en boucle pour gérer les traitements
}

je connais très peux le langage c mais essai d'apprendre et je vous remercie de prendre le temps de m'expliquer :cold_sweat:

c'est de la compil sous IDE 1.0 cela veux dire quoi ? svp

et en supprimant le delai (60000) c'est ok chez moi smiley-mr-green si on supprime le dely (6000) cela vas ré effectue une recherche de temp quand ? une seule fois non ?

thanks

Balise [quote][/quote] pour citer quelqu’un. :grin:

jhonnyy:
si on supprime le delay (6000) cela vas ré effectue une recherche de temp quand ? une seule fois non ?

Pourquoi une seule fois ?
Comme barbu l’a dit la fonction loop peux être considéré comme une boucle infinie donc chaque instruction ce trouvant dans celle-ci est évalué constamment … en boucle . (la boucle tu ne la vois pas c’est l’ide qui ce charge “d’adapter” ton code avant compil).

Voici le vrai visage du code final, ton code sera “incrusté” dedans, regarde bien où ce situe setup() et loop().

#include <Arduino.h>

int main(void)
{
	init();

#if defined(USBCON)
	USB.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

Maintenant si tu si tu regardes le lien BlinkWithoutDelay tu verras comment il est possible d’effectuer un traitement dans un délai choisis lors d’un passage dans cette boucle infinie sans bloquer le reste du code comme le fait la fonction delay().

yes merci pour cette précision.

Bonjour a tous que pensez vous de mon code?

logiquement il lit la température et active le chaffage si la température est tro basse il réeffectue cette tache toutes les 10 Min!!!
cela est Ok?
le programme peux etre plus réduit ?

 #include <OneWire.h> // Inclusion de la librairie OneWire
	 
	#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
	#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
	 
	OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
	 
	// Fonction récupérant la température depuis le DS18B20
	// Retourne true si tout va bien, ou false en cas d'erreur
	boolean getTemperature(float *temp){
	  byte data[9], addr[8];
	  // data : Données lues depuis le scratchpad
	  // addr : adresse du module 1-Wire détecté
	 
	  if (!ds.search(addr)) { // Recherche un module 1-Wire
	    ds.reset_search();    // Réinitialise la recherche de module
	    return false;         // Retourne une erreur
	  }
	   
	  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
	    return false;                        // Si le message est corrompu on retourne une erreur
	 
	  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
	    return false;         // Si ce n'est pas le cas on retourne une erreur
	 
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	   
	  ds.write(0x44, 1);      // On lance une prise de mesure de température
	  delay(800);             // Et on attend la fin de la mesure
	   
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad
	 
	  for (byte i = 0; i < 9; i++) // On lit le scratchpad
	    data[i] = ds.read();       // Et on stock les octets reçus
	   
	  // Calcul de la température en degré Celsius
	  *temp = ((data[1] << 8) | data[0]) * 0.0625;
	   
	  // Pas d'erreur
	  return true;
	}
	 
// Déclaration des pins
    const int relay = 13;       // pin sortie relais

// variables
// Valeurs à déterminer
  unsigned long currentMillis = millis();
//Intervale de 10Min
long intervalchauffage = 600000; 
long previousMillis = 0;

    int tmin = 10;            // t° min // Valeur réelle en °C

    int tmax = 25;            // T° max // valeur réelle en °C

    int t = 0;


void setup() {

  digitalWrite(relay, LOW);
  Serial.begin(9600); // Initialisation du port série


}
void loop() {
//boucle avec fonction de temps pour la lecture de la température et action du relay chauffage
if(currentMillis - previousMillis > intervalchauffage) {
    previousMillis = currentMillis;
  /* --- Affiche la temperature dans le moniteur serial ---*/
  
    float temp; // je n'aime pas trop les variables flotantes mais bon passons ...
	   
	  // Lit la température ambiante à ~1Hz
	  if(getTemperature(&temp)) {
	     
	    // Affiche la température
	    Serial.print("Temperature : ");
	    Serial.print(temp);
	    Serial.write(176); // caractère °
	    Serial.write('C');
	    Serial.println();
}
  /*-----------------------------------------------------*/
  /*--- Comparaison et enclenchement du relais ---*/
  // Lecture t°:
  t = temp;
  //Comparaison :
  if (t < tmin) {
    while (t < tmax){digitalWrite(relay, HIGH); };
                  }
   else {digitalWrite(relay, LOW);}
   
   /*-------------------------------------------*/
}
}

Thanks

Bonsoir

Je ne vais pas commenter sur la partie de lecture du DS18B20 mais uniquement sur le coeur du code.
Il y a de très bonnes choses d’autres un plus … étranges :wink:

unsigned long currentMillis = millis();

Il est très étonnant que ce code compile, mais c’est pourtant le cas (j’ai essayé).
Tu déclares une variable et tu l’initialises avec la valeur de la date au moment de cette initialisation.
Ce veut dire que tu met dans currentMillis la valeur retournée par millis() une fois et une seule.
Voir plus bas l’impact sur le reste de ton code.

void loop() {
//boucle avec fonction de temps pour la lecture de la température et action du relay chauffage
	if(currentMillis - previousMillis > intervalchauffage) {

Tu compares uniquement des variables qui ont été initialisées une fois et une seul.
Donc des constantes.
Donc le résultat est constant.
Vue la valeur de intervalchauffage, tu ne passera jamais dans le code ci-après.

		previousMillis = currentMillis;

Ne sert à rien. Voir la solution après mes commentaires.

		/* --- Affiche la temperature dans le moniteur serial ---*/

		float temp; // je n'aime pas trop les variables flotantes mais bon passons ...

Moi non plus sur un micro 8 bit qui n’a pas d’unité de calcul flottant… :wink:

		// Lit la température ambiante à ~1Hz

je comprend pas ce commentaire : tu ne viens lire la température que toutes les 60000 millisecondes donc toute les minutes, pas toute les secondes.

		if(getTemperature(&temp)) {

Très bonne idée d’avoir prévu une valeur de retour booléenne pour getTemperature() au cas où ca se passe mal mais …

			// Affiche la température
			Serial.print("Temperature : ");
			Serial.print(temp);
			Serial.write(176); // caractère °
			Serial.write('C');
			Serial.println();
		}
		/*-----------------------------------------------------*/
		/*--- Comparaison et enclenchement du relais ---*/
		// Lecture t°:

… ici tu continues comme si la lecture était toujours correcte. Seul l’affichage dépend de la bonne exécution de getTempérature(). C’est une bonne idée qui tourne court.
Donc cette partie devrait aussi être dans le if() au cas ou getTemperature() retourne false.

		t = temp;
		//Comparaison :
		if (t < tmin) {
			while (t < tmax) {digitalWrite(relay, HIGH); };
		}
		else {digitalWrite(relay, LOW); }

Un peu compliqué.
Tu n’as pas besoin de refaire le digitalWrite() pendant la durée du test.
En plus tu rentres ici dans une boucle locale dont la durée n’est pas maitrisée.
Tu risque d’y bloquer ton code ce qui va poser problème quand tu voudras y rajouter ta page web.

		/*-------------------------------------------*/
	}
}

Voici comment j’aurais écrit la boucle :
Tout d’abord j’ai fait l’hypothèse vu ton code que :

  • Tu ne veut tester que 1 fois par minute si la température est descendue trop bas pour allumer le chauffage.
  • Mais que une fois que le chauffage est allumé, tu veux vérifier plus souvent et couper le chauffage très vite si la température max est atteinte.
  • En cas d’erreur de lecture de la température, on réessaye tout de suite, sinon il faudrait attente 1 minute de nouveau
#define PERIODE_LENTE       60000
#define PERIODE_RAPIDE        1000

// unsigned long currentMillis = millis(); // PLUS BESOIN
unsigned long intervalchauffage = PERIODE_LENTE;  // ATTENTION AU TYPE : On traite les millis() en unsigned long
unsigned long previousMillis = 0;  // ATTENTION AU TYPE : On traite les millis() en unsigned long

int tmin = 10;                // t° min // Valeur réelle en °C
int tmax = 25;                // T° max // valeur réelle en °C
int t = 0;

bool chauffageOn = false;


void setup() {

	digitalWrite(relay, LOW);
	Serial.begin(9600); // Initialisation du port série

// initialiser previousMillis pour être sur de réclencher le test la 1ère fois
  previousMillis = millis() - intervalchauffage;
}

void loop() 
{
//boucle avec fonction de temps pour la lecture de la température et action du relay chauffage
// voilà comment on gère correctement le timing
// il faut à chaque fois comparer avec "maintenant" donc avec la valeur retournée par millis() à cet instant présent
	if( (millis() - previousMillis) > intervalchauffage) {
		previousMillis = millis();  // on mémorise la valeur de maintenant
		/* --- Affiche la temperature dans le moniteur serial ---*/

		float temp; // je n'aime pas trop les variables flotantes mais bon passons ...

		// Lit la température ambiante à ~1Hz
		if(getTemperature(&temp)) {

			// Affiche la température
			Serial.print("Temperature : ");
			Serial.print(temp);
			Serial.write(176); // caractère °
			Serial.write('C');
			Serial.println();
			/*-----------------------------------------------------*/
			/*--- Comparaison et enclenchement du relais ---*/
			// Lecture t°:
			t = temp;
			//Comparaison :
                        if ( chauffageOn )
                        {
                               if ( t > tmax )
                                {
                                      digitalWrite(relay, LOW);
                                      chauffageOn = false;
                                      intervalchauffage = PERIODE_LENTE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                        }
                        else  // if ( chauffageOn )
                        {
			        if (t < tmin) 
                                {
                                      digitalWrite(relay, HIGH);
                                      chauffageOn = true;
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_LENTE;
                                }
                        }   // if ( chauffageOn ) else
                }
                else  // If ( getTemperature() )
                {
                        // en cas d'erreur de lecture on passe en période rapide pour venir retester rapidemment
                        intervalchauffage = PERIODE_RAPIDE;
 		} // If ( getTemperature() ) else

		/*-------------------------------------------*/
	}
}

Amélioration encore possible : compter les erreurs de lectures successives et sonner une alarme si trop d’erreurs.

merci barbudor

très intéressant tu m’apprend bcp et je t’en remercie

En cas d’erreur de lecture de la température, on réessaye tout de suite, sinon il faudrait attente 1 minute de nouveau

il est possible que la lecture est des problème ? ex:parasite sur le ds18b20?

Amélioration encore possible : compter les erreurs de lectures successives et sonner une alarme si trop d’erreurs.

Est il possible de loguer les erreur sur le serial ou la carte sd

maintenant je m’attaque au service web !!!

Il y a une partie qui est encore flou
j’ai un shield sd et network il bloque combien de ports ?

thanks
De plus comment afficher sur le web ou le port série si le relais est allumé ou non ?
une variable à crée sur la parti de comparaison ?
et l’affiché sur la partie web mais je suis vraiment pas sur!!!

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h> // Inclusion de la librairie OneWire

#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
	 
	OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
	 
	// Fonction récupérant la température depuis le DS18B20
	// Retourne true si tout va bien, ou false en cas d'erreur
	boolean getTemperature(float *temp){
	  byte data[9], addr[8];
	  // data : Données lues depuis le scratchpad
	  // addr : adresse du module 1-Wire détecté
	 
	  if (!ds.search(addr)) { // Recherche un module 1-Wire
	    ds.reset_search();    // Réinitialise la recherche de module
	    return false;         // Retourne une erreur
	  }
	   
	  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
	    return false;                        // Si le message est corrompu on retourne une erreur
	 
	  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
	    return false;         // Si ce n'est pas le cas on retourne une erreur
	 
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	   
	  ds.write(0x44, 1);      // On lance une prise de mesure de température
	  delay(800);             // Et on attend la fin de la mesure
	   
	  ds.reset();             // On reset le bus 1-Wire
	  ds.select(addr);        // On sélectionne le DS18B20
	  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad
	 
	  for (byte i = 0; i < 9; i++) // On lit le scratchpad
	    data[i] = ds.read();       // Et on stock les octets reçus
	   
	  // Calcul de la température en degré Celsius
	  *temp = ((data[1] << 8) | data[0]) * 0.0625;
	   
	  // Pas d'erreur
	  return true;
	}
	 
// Déclaration des pins
    const int relay = 13;       // pin sortie relais

// variables
// Valeurs à déterminer
#define PERIODE_LENTE        60000
#define PERIODE_RAPIDE        1000

unsigned long intervalchauffage = PERIODE_LENTE;  // ATTENTION AU TYPE : On traite les millis() en unsigned long
unsigned long previousMillis = 0;  // ATTENTION AU TYPE : On traite les millis() en unsigned long

int tmin = 10;                // t° min // Valeur réelle en °C
int tmax = 25;                // T° max // valeur réelle en °C
int t = 0;

bool chauffageOn = false;

// Définir l'adresse MAC et l'IP de la carte
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x3D, 0x0A };
byte ip[] = { 192,168,1,20 };

// Initialisation de la bibliothèque Ethernet server 
// avec l4IP définie et le port (80 par défaut en HTTP)
EthernetServer server(80);


void setup() {

	digitalWrite(relay, LOW);
	Serial.begin(9600); // Initialisation du port série
//Initialisation de la partie web
	Ethernet.begin(mac, ip);
	server.begin();
// initialiser previousMillis pour être sur de réclencher le test la 1ère fois
  previousMillis = millis() - intervalchauffage;
}

void loop() 
{

//boucle avec fonction de temps pour la lecture de la température et action du relay chauffage
// voilà comment on gère correctement le timing
// il faut à chaque fois comparer avec "maintenant" donc avec la valeur retournée par millis() à cet instant présent
	if( (millis() - previousMillis) > intervalchauffage) {
		previousMillis = millis();  // on mémorise la valeur de maintenant
		/* --- Affiche la temperature dans le moniteur serial ---*/

		float temp; // je n'aime pas trop les variables flotantes mais bon passons ...

		// Lit la température ambiante à ~1Hz
		if(getTemperature(&temp)) {

			// Affiche la température
			Serial.print("Temperature : ");
			Serial.print(temp);
			Serial.write(176); // caractère °
			Serial.write('C');
			Serial.println();
			/*-----------------------------------------------------*/
			[u]/*--- Comparaison et enclenchement du relais ---*/
			// Lecture t°:
			t = temp;
			//Comparaison :
                        if ( chauffageOn )
                        {
                               if ( t > tmax )
                                {
                                      digitalWrite(relay, LOW);
                                      chauffageOn = false;
                                      intervalchauffage = PERIODE_LENTE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                        }
                        else  // if ( chauffageOn )
                        {
			        if (t < tmin) 
                                {
                                      digitalWrite(relay, HIGH);
                                      chauffageOn = true;
                                      intervalchauffage = PERIODE_RAPIDE;
									  
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_LENTE;
                                }[/u]
                        }   // if ( chauffageOn ) else
                }
                else  // If ( getTemperature() )
                {
                        // en cas d'erreur de lecture on passe en période rapide pour venir retester rapidemment
                        intervalchauffage = PERIODE_RAPIDE;
 		} // If ( getTemperature() ) else

		/*-------------------------------------------*/
	}
// attente de clients (un navigateur web par exemple)
EthernetClient client = server.available();
if (client) {

    // une demande HTTP se termine par une ligne vide
    boolean currentLineIsBlank = true;
    while (client.connected()) {

        if (client.available()) {

            char c = client.read();
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank) {
            // Header HTTP usuel
            //
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();

            client.print("<!doctype html><html><head><meta charset='utf-8'/><title>Serveur de température Arduino</title>");
            // script qui réactualise la page toutes les 1000 mSec
            client.print("<script type='text/javascript'>function reFresh() {  location.reload(true) } window.setInterval('reFresh()',1000); </script>");
            client.print("</head><body><html>");
            client.print("<h1 style='font-family:verdana;'>Serveur de Température - Arduino</h1>");
            client.print("<p style='font-family:arial;color:red;font-size:20px;'>La temperature relevée est de ");
            client.print(t);
            client.println(" °C.</p></body></html>");
            

        break;

    }

    if (c == '\n') {

    // you're starting a new line
    currentLineIsBlank = true;
    }
    else if (c != '\r') {

            // you've gotten a character on the current line
            currentLineIsBlank = false;

            }

        }

    }

    // on laisse du temps au navigateur web de recevoir les données
    delay(1);
    // close the connection:
    client.stop();
    }
}