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

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

le code de getTemperatuer() le prévoit.
Si ce n'est pas toi qui l'a codé ainsi, quelqu'un d'autre a été prévoyant.
En programmation, tant desktop que embarqué, IL FAUT TOUJOURS PREVOIR LE PIRE

Dans ton cas tu va commander un chauffage.
Imagine que tu lises une fois une température inférieure à 10°. Tu vas donc allumer le chauffage. Et puis pendant la chauffe, un problème arrive sur la liaison avec leDS. S'il n'est pas sur la carte mais déporté par exemple, on peut imaginer que le fil se débranche ou ait été rongé par une souris (véridique). Ton code actuel va continuer à raisonner sur la dernière lecture de temp qui confirme qu'il faut continuer à chauffer.
Je ne sais ce que tu chauffe mais si c'est pour une couveuse à canard comme Infobarquee, il est presque sûr de récupérer en fin de journée les margrets cuits à point (or ca se mange plutôt rosé le canard ;)).
Donc il faut considérer les erreurs possibles vis à vis des risques possible et agir en conséquence.
pose toi la question : si je n'ai plus la température quel est le mode de fonctionnement dégrader que je dois appliquer :

  • couper le chauffage
  • le laisser en route en permanence
  • appliquer un "PWM" de sécurité genre 1 minute en marche poru 2 minutes arrêté,
  • sonner une corne de brume pour appeler les gardes côtes ....

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

Bien sur.
A ajouter dans la boucle. Tu peux logguer les lecture valides ainsi que les erreurs.

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

Comme je le dit dans ma signature la dessous : READ THAT FUCKING SCHEMATIC (cloné de la phrase de Linus Torvald : Read That Fucking Code qui incite les gens à lire le code Open Source pour être sur de savoir ce qu'il fait).
Si ton shield c'est le shield officiel Arduino tu trouveras le schéma sur la page consacré ici.
On voit que les broches suivantes sont utilisées :

  • D4 : chip-select de la carte SD
  • D10 : chip-select du chip Ethernet W5100
  • D11, D12, D23 : interface SPI (respectivement MISO, MOSI et SCLK). Celles-ci sont difficile à voir sur le schéma car pour une raison incompréhensible, le shield Ethernet ne va pas les prendre sur le connecteur shield J1 mais sur le connecteur ISP. Ceci rend le shield Ethernet incompatible avec toute carte compatible qui ne respecte pas exactement l'emplacement du connecteur ICSP !

Donc ca te laisse pas mal d'IO pour ta sonde de température, ta commande de relai (a bouger de la broche D13 maintenant car celle-ci est utilisé par le bus SPI)

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!!!

Dans le code que je t'ai renvoyé, j'ai déjà créé une variable chauffageOn qui trace cette information. Je m'en sert pour savoir si je doit comparer la température "< tmin" ou "> tmax". Tu peux l'utiliser aussi à l'extérieur.
Pour le port série, un Serial.print() bien placé fera l'affaire.
Pour la page web, il faut que le contenu de ta page contienne une partie dynamique qui dépend de la valeur de certaines variables.

Attention, par défaut, pour que l'affichage dans le navigateur web soit mis à jour il faut que le navigateur redemande la page.
Si tu veux que cela soit affiché automatiquement, il faut donc que le navigateur fasse la demande automatiquement d'un rafraîchissement de la page sans que l'utilisateur presse F5.
Pour un rafraichissement de toute la page, il suffit d'ajouter dans l'entête de ta page :

<header>
<meta http-equiv="refresh" content="30" />
</header>

La valeur donne la période de rafraîchissement en seconde.
Comme tu ne mesures la température que toute les minutes, ça ne sert à rien de rafraîchir plus vite.

Après pour avoir un rafraîchissement plus léger, tu peux faire du JavaScript et du HTML Dynamique pour éviter l'effet de remise à zéro de la page.

Sinon, ton dernier code commence a devenir lourd.
Ne laisse plus tout dans la fonction loop() mais découpe en sous fonctions qui deviennent maintenable et lisibles.
Une fonction qui dépasse 50 lignes de code (y compris les lignes blanches et les commentaires) devient illisibles.
On se perd dans les indentations, quand on lit la fin on ne sais plus ce que fait le début , ....

Découpe ton code par exemple :

void loop()
{
  tache_lecture _temperature();
  tache_gestion chauffage();
  tache_ethernet();
}

Tu t'y retrouveras mieux, tu pourras plus facilement debugguer chaque partie individuellement.
Définis clairement les interfaces entre les taches c'est à dire les variables globales qui vont transporter l'information d'une tâche à l'autre.
J'ai donné à plusieurs personnes sur le forum déjà des exemples sur comment découper des tâches en machines d'état non bloquantes.
En attendant que j'écrive un Tuto sur le sujet, regarde mes réponses par exemple ici : http://arduino.cc/forum/index.php/topic,102491.0.html

En plus quand tu auras des problèmes et que tu feras appel à communauté,; tu auras plus facilement des réponses sur un code simple, localisé à un problème, que si tu nous balance 500 lignes de code en disant "çà marche pas".

A+

bonjour,
Désolé je n'arrive pas a comprendre la partie

void loop()
{
tache_lecture _temperature();
tache_gestion chauffage();
tache_ethernet();
}

je me suis aidé de ce code

taskLoop(redLED)  
{  
  digitalWrite(ledPinRed,HIGH);  
  delay(200);  
  digitalWrite(ledPinRed,LOW);  
  delay(200);  
}  
  
taskLoop(greenLED)  
{  
  digitalWrite(ledPinGreen, HIGH);  
  delay(500);  
  digitalWrite(ledPinGreen, LOW);  // set the LED off  
  delay(500);  
}  
  
// Fonctions habituelles  
  
void setup()     
{                  
  // Initialisation des deux sorties pour les leds  
  pinMode(ledPinRed, OUTPUT);  
  pinMode(ledPinGreen, OUTPUT);  
    
  // Création des deux tâches  
  createTaskLoop(redLED, NORMAL_PRIORITY);  
  createTaskLoop(greenLED, NORMAL_PRIORITY);  
}  
  
void loop()                       
{  
  // Deux tâches en parallèle pendant 2 secondes  
  resumeTask(greenLED);  
  resumeTask(redLED);  
  delay(2000);  
  // Puis seulement la verte pendant 2 secondes   
  suspendTask(redLED);  
  delay(2000);  
  // Puis seulement la rouge  
  resumeTask(redLED);  
  suspendTask(greenLED);  
  delay(2000);  
  // et on recommence (loop)  
}

je vous pas comment appelé la tache_lecture _temperature();
il faut la renseigner avant un peux comme mon

l.13 boolean getTemperature(float *temp){

non ?
et oui Read That Fucking Code
Je pensait avoir une remarque comme celle ci :slight_smile:

c Bon j'ai comprit Merci dite moi si mon code est comme voulou mais logiquement c bon

séparé les taches c'est mieux pour l'arduino ?

pour nous humain je comprend mais aussi pour "lui"!!!

#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
// 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	 
	OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
	
	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éclaration des pins
    const int relay = 13;       // pin sortie relais

	 
	// 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é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 temperature(){

//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

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

	}
void reseau(){
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();
    }
}

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() 
{
 temperature();
reseau();
}

Ca me semble bon à première lecture.

Le premier exemple que tu était aller chercher concerne l'utilisation de DuinOS un noyau multi-tâche qui est une extension à l'environnement Arduino. Pas besoin d'aller chercher cela pour ce genre d'opérations simples.

Encore 2 remarques :

  • Tu utilise toujours la broche 13 pour le relai ce qui est incompatible avec l'usage du shield Ethernet car la broche 13 fait partie de l'interface SPI utilisée par le shield Ethernet et la carte SD.

  • Attention à la mémoire. Tu utilise de nombreuses chaines de caractères pour définir ta page HTML. Les mécanismes du processeur ATmega font que les chaînes de caractères, bien qu'étant des constantes, sont des données et sont recopiées avant setup() de la mémoire FLASH dans la RAM.
    Or si la FLASH est assez confortable (32KO), la RAM est beaucoup plus petite (2KO).
    Il existe heureusement des techniques qui permettent de laisser les chaînes de caractères.

Le principe est :

  1. De rajouter #include "pgmspace.h"
  2. D'encapsuler toutes les chaines de caractères que tu va utiliser avec xxx.print par PSTR("ma chaîne") comme par exemple :
client.println(PSTR("HTTP/1.1 200 OK"));
client.println(PSTR("Content-Type: text/html"));

Normalement toutes les classes dérivées de Print (ou Stream) savent aller chercher les chaînes de caractères en FLASH.

Tu peux aussi gagner un peu en place et en temps d'exécution en groupant un peu plus tes chaines par exemple :

				client.print(PSTR( \
"HTTP/1.1 200 OK\n"\
"Content-Type: text/html\n"\
"\n"\
"<!doctype html><html><head><meta charset='utf-8'/><title>Serveur de temp�rature Arduino</title>\n"\
"<script type='text/javascript'>function reFresh() {  location.reload(true) } window.setInterval('reFresh()',1000); </script>\n"\
"</head><body><html>\n"\
"<h1 style='font-family:verdana;'>Serveur de Temp�rature - Arduino</h1>\n"\
"<p style='font-family:arial;color:red;font-size:20px;'>La temperature relev�e est de " ) );
					client.print(t);
					client.println( PSTR(" �C.</p></body></html>") );

Tu remarquera l'usage du caractère \ en fin de ligne qui signifie que la ligne au sens C ne s'arrete pas à la ligne du code source.
le compilateur va donc voir l'ensemble de toutes ces lignes comme une seule ligne "logique" ce qui est indispensable pour que les chaînes de caractères se concatène.
Tu remarquera aussi que :

  • le premier print() est un print() et non plus un println()
  • j'ai "manuellement" ajouter les retours à la ligne par des \n en fin de chaque chaîne de caractères.

Comme cela, il peut envoyer d'un seul trait toute le début jusqu'à la température.

pour afficher si le chauffage est activer c bon ?

		if(getTemperature(&temp)) {

			// Affiche la température
			Serial.print("Temperature : ");
			Serial.print(temp);
			Serial.write(176); // caractère °
			Serial.write('C');
			Serial.print("Chauffage :");
			Serial.write(chauffageOn);
			Serial.println();
			/*-----------------------------------------------------*/
			/*--- Comparaison et enclenchement du relais ---*/
			// Lecture t°:
			t = temp;
			//Comparaison :
                        if ( chauffageOn )
                        {
                               if ( t > tmax )
                                {
                                      digitalWrite(relay_chauffage, LOW);
                                      chauffageOn = false;
                                      intervalchauffage = PERIODE_LENTE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                        }
                        else  // if ( chauffageOn )
                        {
			        if (t < tmin) 
                                {
                                      digitalWrite(relay_chauffage, 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

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

	}

Les lignes sont bonnes mais je dirais qu'elles sont mal placées.
Tu affiches chauffageOn juste après avoir lut la température mais avant de faire le test sur la température et d'avoir pris ta décision.

J'afficherais chauffageOn après la fin du if, derrnière la ligne
et dans le else de getTemperature mets une alarme :

                        }   // if ( chauffageOn ) else
			Serial.print("Chauffage :");
			Serial.println( chauffageOn ? "marche" : "arrêt" );
                }
                else  // If ( getTemperature() )
                {
                        // en cas d'erreur de lecture on passe en période rapide pour venir retester rapidemment
                        intervalchauffage = PERIODE_RAPIDE;
                        Serial.println( "ALARME: Erreur de lecture de la température" );
 		} // If ( getTemperature() ) else

Bonjour,

comment le programe comprend les ligne ci dessous
je voit pas comment il peux faire ?
pas de true ou false ???

Serial.print("Chauffage :");
Serial.println( chauffageOn ? "marche" : "arrêt" );

Merci

actuellement je m’attaque a la parti ntp pour loguer la date et l'heure.

Serial.println( chauffageOn ? "marche" : "arrêt" );

est une écriture compacte en C pour :

char *str;
if (ChauffageOn)
  str = "marche";
else
  str = "arrêt";
Serial.println( str );

yes okay
c'est bien plus logique

merci

je viens de "terminer" l'enregistrement sur sd

/*
* Info
*Broche utilisé par les fonctions
- D4 : chip-select de la carte SD
- D10 : chip-select du chip Ethernet W5100
- D11, D12, D13
*Broche à relier
- D1 : 
- D2 : 
- D3 :
- D5 : relai vmc
- D6 : Relai chauffage
- D7 : sonde de temp >> ds18b20
- D8 :
- D9 :
*/


//librairie
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h> // Inclusion de la librairie OneWire
//broche et variables
#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
#define PERIODE_LENTE        60000
#define PERIODE_RAPIDE        1000
const int relay_chauffage = 6;       // pin sortie relais
const int relay_vmc = 6;
const int chipSelectsd = 4;
//Valeur a déterminé-----------------------------------------------------------------------------------------------
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 };
	byte gw[] = { 192, 168, 1, 1 };
EthernetServer server(80);
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	 
	unsigned long enregistrementcarte = PERIODE_LENTE;
	OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
	
bool chauffageOn = false;
	// 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;
	}

void temperature(){

//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_chauffage, LOW);
                                      chauffageOn = false;
                                      intervalchauffage = PERIODE_LENTE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                        }
                        else  // if ( chauffageOn )
                        {
			        if (t < tmin) 
                                {
                                      digitalWrite(relay_chauffage, HIGH);
                                      chauffageOn = true;
                                      intervalchauffage = PERIODE_RAPIDE;
									  
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_LENTE;
                                }
                        }   // if ( chauffageOn ) else
						Serial.print("Chauffage :");
						Serial.println( chauffageOn ? "marche" : "arrêt" );
                }
                else  // If ( getTemperature() )
                {
                        // en cas d'erreur de lecture on passe en période rapide pour venir retester rapidemment
                        intervalchauffage = PERIODE_RAPIDE;
 		                Serial.println( "ALARME: Erreur de lecture de la température" );
		}		// If ( getTemperature() ) else

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

	}
void reseau(){
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();
    }
}
void enregistrementsd() {
if( (millis() - previousMillis) > enregistrementcarte) {
previousMillis = millis();
String dataString = "";

File dataFile = SD.open("logtemp.txt", FILE_WRITE);

// if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}
}

void setup() {

	digitalWrite(relay_chauffage, 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;
 // parti sd  
  Serial.print("Initializing SD card...");
   pinMode(10, OUTPUT);
     if (!SD.begin(chipSelectsd)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop() 
{
 temperature();
reseau();
enregistrementsd();
}

cela fonctionne mais je voudrait qu'il m'affiche l'heure par le biais d'un serveur ntp cela est possible ?

de plus mon code commence à être gros et j'ai vraiment pas fini !!!!
des astuces ?

cordialement

NTP, y'a un exemple sur le site Arduino : http://arduino.cc/en/Tutorial/UdpNtpClient
Je ne sais pas ce qu'il vaut.

Pour l'instant tes fonctions sont courtes et bien ciblées, donc rien a redire sur l'organisation.
Fait attention à l'indentation pour que cela reste lisible (c'est peut être bon dans l'IDE mais sur le forum ca passe pas terrible).

Après tu peux chercher à découper dans plusieurs fichiers sources (des .cpp pas des .ino) pour chaque tâches.
Ce qui permet aussi d'organiser chaque module de manière bien indépendante avec son setup_Xxxx() et son loop_Xxxx() et dans le INO il ne reste finalement que une fonction setup qui appele les setup_Xxxx() et une fonction loop qui appele les loop_Xxxx().

okay merci

mais j'ai l'impression que tu es le seul sur le post pourquoi ?
étrange.

Parce que j'ai beaucoup de temps ces temps ci.

Mais çà va pas durer après mi-mai :wink:

merci d'avoir du temps à me consacrer

je ne comprend pas je test un code ntp client qui me parait vraiment bien

/*
* Info
*Broche utilisé par les fonctions
- D4 : chip-select de la carte SD
- D10 : chip-select du chip Ethernet W5100
- D11, D12, D13
*Broche à relier
- D1 : 
- D2 : 
- D3 :
- D5 : relai vmc
- D6 : Relai chauffage
- D7 : sonde de temp >> ds18b20
- D8 :
- D9 :
*/


//librairie
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h> // Inclusion de la librairie OneWire
#inculde <NTP.h>
//broche et variables
#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
#define PERIODE_LENTE        60000
#define PERIODE_RAPIDE        1000
#define temp_enregistrement_sd		600000
const int relay_chauffage = 6;       // pin sortie relais
const int relay_vmc = 6;
const int chipSelectsd = 4;
//Valeur a déterminé-----------------------------------------------------------------------------------------------
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,0,20 };
	byte gw[] = { 192, 168,0,254 };

byte time_dot_nist_dot_gov[] = { 192, 43, 244, 18}; // time.nist.gov	
	EthernetServer server(80);
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	 
unsigned long enregistrementcarte = temp_enregistrement_sd;
	OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
	
bool chauffageOn = false;
	// 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;
	}
void Temp_ntp() {
	
	NTP ntp(time_dot_nist_dot_gov);
    unsigned long time = ntp.get_gmt();
    Serial.println(time);}
void temperature(){

//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_chauffage, LOW);
                                      chauffageOn = false;
                                      intervalchauffage = PERIODE_LENTE;
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_RAPIDE;
                                }
                        }
                        else  // if ( chauffageOn )
                        {
			        if (t < tmin) 
                                {
                                      digitalWrite(relay_chauffage, HIGH);
                                      chauffageOn = true;
                                      intervalchauffage = PERIODE_RAPIDE;
									  
                                }
                                else
                                {
                                      intervalchauffage = PERIODE_LENTE;
                                }
                        }   // if ( chauffageOn ) else
						Serial.print("Chauffage :");
						Serial.println( chauffageOn ? "marche" : "arrêt" );
                }
                else  // If ( getTemperature() )
                {
                        // en cas d'erreur de lecture on passe en période rapide pour venir retester rapidemment
                        intervalchauffage = PERIODE_RAPIDE;
 		                Serial.println( "ALARME: Erreur de lecture de la température" );
		}		// If ( getTemperature() ) else

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

	}
void reseau(){
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();
    }
}
void enregistrementsd() {
if( (millis() - previousMillis) > enregistrementcarte) {
previousMillis = millis();
String dataString = "";

File dataFile = SD.open("logtemp.txt", FILE_WRITE);

// if the file is available, write to it:
  if (dataFile) {
    dataFile.println(t);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}
}

void setup() {

	digitalWrite(relay_chauffage, LOW);
	Serial.begin(9600); // Initialisation du port série
//Initialisation de la partie web
	Ethernet.begin(mac,ip,gw);
	server.begin();
// initialiser previousMillis pour être sur de réclencher le test la 1ère fois
  previousMillis = millis() - intervalchauffage;
 // parti sd  
  Serial.print("Initializing SD card...");
   pinMode(10, OUTPUT);
     if (!SD.begin(chipSelectsd)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop() 
{
 temperature();
reseau();
enregistrementsd();
}

dsl deux posts car trop de caractères
et j'ai un gro message d'erreur
J'ai vérifié la lib cela me parait ok

sketch_may08a.cpp:24:2: error: invalid preprocessing directive #inculde
sketch_may08a.cpp: In function 'void Temp_ntp()':
sketch_may08a:90: error: 'NTP' was not declared in this scope
sketch_may08a:90: error: expected `;' before 'ntp'
sketch_may08a:91: error: 'ntp' was not declared in this scope

UNE solution?

Avec une loupe tu devrais mieux voir :wink:

#include <OneWire.h> // Inclusion de la librairie OneWire
#inculde <NTP.h>

Le reste doit découler de la 1ere erreur :smiley:

MERCI j'ai passé pas mal de temps pour ceci !!!!!!!!!!!!!!!!!!!!!!!!!