Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser ;)

En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.

Topic "Utiliser un capteur de température et d'humidité DHT11 / DHT22 avec une carte Arduino / Genuino"

Flux RSS des posts récents dans ce topic ( Flux Atom)


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#204 | Signaler ce message


Dans ce tutoriel, nous allons apprendre ensemble à communiquer avec un capteur de température et d'humidité, le DHT22 et son petit frère, le DHT11. Nous verrons les caractéristiques de ses capteurs, leurs fonctionnements et comment les utiliser. En bonus, nous verrons comment calculer le point de rosée, pour les amateurs de météo.

Lire la suite de l'article sur le site

Derniére modification le par skywodd


Photo de profil de flo

flo

Membre

#369 | Signaler ce message


Salut Fabien(ou plutot maitre !!),

Super ton topic!! Claire, précis, TOP! Vraiment! Bon moi je suis ce que l'on pourrait appeler un Noob en la matière.. En fait, j'ai un projet perso qui me tiens à coeur depuis un moment et j'ai décidé de passer à l'acte, il y a un petit mois à peine. J'ai quelques notions en programmation mais plus automate orienté machine. Donc je débute dans la programmation "ordinateur" ? Je sais pas si c'est comme ca que l'on dit… Enfin bref !

J'utilise ce genre de capteur pour mon projet, donc ton code met bien utile !! :) Par contre, j'ai un soucis du coup, quand je le transfert sur ma carte.

J'ai tout d'abord eu un problème d'affichage sur le moniteur série. Ça me m'était des caractères bizarres au lieu de valeurs de temp et humidity. Je me suis donc dit, que c'était la bibliothèque DHT qui n'était pas à jour, et effectivement il y avait un 1.3.0 de dispo. Et la, en voulant re-Transfer le code il ne passe plus! J'ai eu ce message d'erreur "Erreur de compilation pour la carte Arduino/Genuino Mega or Mega 2560" Est ce que tu connaîtrais la cause de ce problème ?

Si tu trouves 5 minutes pour m'aider la dessus je t'en serrais très reconnaissant !! ;)

Merci par avance

A+

Florian


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#380 | Signaler ce message


Salut Fabien(ou plutot maitre !!),

par flo

Du calme jeune padawan ;)

J'ai tout d'abord eu un problème d'affichage sur le moniteur série. Ça me m'était des caractères bizarres au lieu de valeurs de temp et humidity.

(…)

Est ce que tu connaîtrais la cause de ce problème ?

par flo

Les deux problèmes sont distincts.

  • L'affichage de caractéres bizarres, c'est un probléme de vitesse de communication. La valeur dans Serial.begin(XXXX) doit correspondre à la valeur choisie dans le moniteur série (via liste déroulante en bas de la fenêtre).

  • Pour l'erreur de compilation, il me faudrait le détail de l'erreur pour en dire plus (dans la zone noir en bas de l'éditeur de code).


Photo de profil de Jean-Eudes

Jean-Eudes

Membre

#461 | Signaler ce message


Bonjour Skywood,

Votre article est vraiment sympa, utile, et pédagogue. Serait-il possible d'avoir l'article au format pdf ?

Merci d'avance, Jean-Eudes :)

PS : Je partage

Derniére modification le par Jean-Eudes


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#470 | Signaler ce message


Serait-il possible d'avoir l'article au format pdf ?

par Jean-Eudes

Je n'ai pas de version PDF à proposer pour le moment. C'est dans ma (très longue) liste de chose à implémenter pour le site.

Si vous voulez une version PDF, le plus simple est "d'imprimer dans un fichier". L'option est disponible nativement sous Chrome.

Pour Firefox, il doit y avoir une solution équivalente ou un plugin (je n'utilise pas Firefox).

PS : Je partage

par Jean-Eudes

Merci de partager le lien mais pas directement le contenu de l'article ;)


Pas de photo de profil

Mgonin

Membre

#492 | Signaler ce message


Bonjour, Merci pour ce tuto. Je souhaiterais utiliser 2-3 capteurs DHT22 mais malheureusement je bloque sur ce point. Pouvez-vous m'aider svp ? Merci d'avance.


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#500 | Signaler ce message


Je souhaiterais utiliser 2-3 capteurs DHT22 mais malheureusement je bloque sur ce point. Pouvez-vous m'aider svp ?

par Mgonin

Voici un exemple d'utilisation avec deux sondes :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const byte BROCHE_CAPTEUR_1 = 5;
const byte BROCHE_CAPTEUR_2 = 6;

void loop() {
  float temperature[2], humidity[2];
 
  /* Lecture capteur 1 */
  if (readDHT22(BROCHE_CAPTEUR_1, &(temperature[0]), &(humidity[0])) != DHT_SUCCESS) {
    Serial.println(F("Erreur capteur 1")); 
  }

  /* Lecture capteur 2 */
  if (readDHT22(BROCHE_CAPTEUR_2, &(temperature[1]), &(humidity[1])) != DHT_SUCCESS) {
    Serial.println(F("Erreur capteur 2")); 
  }

  /* Affichage de la température et du taux d'humidité */
  Serial.print(F("Humidite (%): "));
  Serial.println(humidity[0], 2);
  Serial.print(F(", "));
  Serial.println(humidity[1], 2);
  Serial.print(F("Temperature (^C): "));
  Serial.print(temperature[0], 2);
  Serial.print(F(", "));
  Serial.println(temperature[1], 2);
}

Pas de photo de profil

celia

Membre

#505 | Signaler ce message


Bonjour, quand j'utilise ce programme, le moniteur série me donne une humidité de 37240.80 et une température de 307.20C et je n'arrive pas à trouver l'erreur. Nous avons pour but de réaliser une station météo avec Arduino pour notre projet ISN. Si vous avez un peu de temps, ca nous aiderais beaucoup. Merci d'avance Lisa et Célia


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#506 | Signaler ce message


Bonjour, quand j'utilise ce programme, le moniteur série me donne une humidité de 37240.80 et une température de 307.20C et je n'arrive pas à trouver l'erreur.

par celia

DHT11 ou DHT22 ? Chaque version nécessite d'utiliser la fonction adéquate.


Pas de photo de profil

celia

Membre

#507 | Signaler ce message


DHT 11 nous a dit notre professeur


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#509 | Signaler ce message


DHT 11 nous a dit notre professeur

par celia

Dans ce cas, il faut utiliser la fonction readDHT11().


Pas de photo de profil

Mgonin

Membre

#515 | Signaler ce message


Merci pour votre réponse. Cela fonctionne bien avec une board ARDUINO. Par contre j'ai essayé avec un CONTROLLINO en passant par la fonction LINX de LABVIEW pour faire un interfaçage + enregistrement des data dans un fichier et j'ai des bugs…pourtant j'arrive bien à le réaliser pour un capteur en passant par la librairie DHT. Auriez-vous en tête un moyen simple de faire la lecture des mes 3 capteurs DHT22,16 MAX31855 + 10 capteurs de vibration avec un interfaçage et un enregistrement des datas ? Je connais un peu l'univers Arduino et LabVIEW. Par contre, je suis moins adepte de Processing par exemple. Merci.


Pas de photo de profil

celia

Membre

#519 | Signaler ce message


Bonjour, notre professeur a acheté un nouveau capteur, sa référence est sen51035P, on ne sait pas si c est dht11 ou 22 Merci de votre aide


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#522 | Signaler ce message


Auriez-vous en tête un moyen simple de faire la lecture des mes 3 capteurs DHT22, 16 MAX31855 + 10 capteurs de vibration avec un interfaçage et un enregistrement des datas ?

par Mgonin

29 capteurs ça commence à faire du monde …

Question bête, une sortie texte sur le port série (via l'usb) au format CSV ne serait pas suffisant ?


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#523 | Signaler ce message


Bonjour, notre professeur a acheté un nouveau capteur, sa référence est sen51035P, on ne sait pas si c est dht11 ou 22

par celia

DHT22 d’après la doc.


Photo de profil de Jean-Eudes

Jean-Eudes

Membre

#560 | Signaler ce message


Serait-il possible d'avoir l'article au format pdf ?

par Jean-Eudes

Je n'ai pas de version PDF à proposer pour le moment. C'est dans ma (très longue) liste de chose à implémenter pour le site.

Si vous voulez une version PDF, le plus simple est "d'imprimer dans un fichier". L'option est disponible nativement sous Chrome.

Pour Firefox, il doit y avoir une solution équivalente ou un plugin (je n'utilise pas Firefox).

PS : Je partage

par Jean-Eudes

Merci de partager le lien mais pas directement le contenu de l'article ;)

par skywodd

Bonjour skywodd, désolé de répondre si tard mais je te remercie pleinement !! je ne connaissais pas cette méthode ;)

Je pensais bien entendu à publier l'article (et le site surtout) et non pas copier coller en m'appropriant l'article.

Encore merci et bonne continuation ;)


Pas de photo de profil

HERAUD

Membre

#569 | Signaler ce message


Bonjour et merci pour le tuto, c'est exactement ce que je cherchais. Et compte tenu de mon niveau, le fait que j'arrive à mettre en application vos conseils est un gage de qualité pédagogique ! Ma recherche portait sur la recherche de point de rosée, et ça tombe bien puisqu'en bonus, vous ajoutez au tuto le code qui permet le calcul approximatif du "dewpoint". Bêtement, j'ai ajouté cela à la suite du programme gérant la DHT22 en température et taux d'humidité relative, mais … ça marche po. Pour préciser la situation : l'achat de la carte Arduino date d'hier, j'ai fait clignoter une diode puis attaqué direct votre tuto (encore une fois, le plus étonnant est que ça marche ! 53% d'humidité et 23.5°C devant l'ordi en ce moment. Votre prochain flash météo dans 500ms ! c'est top). Help


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#573 | Signaler ce message


Bêtement, j'ai ajouté cela à la suite du programme gérant la DHT22 en température et taux d'humidité relative, mais … ça marche po.

par HERAUD

Va falloir être plus précis, qu'est ce qui marche pas ? La compilation ? L’exécution ? Le résultat du calcul ?

Je ne suis pas devin ;)


Pas de photo de profil

HERAUD

Membre

#576 | Signaler ce message


Bj, Je précise : j'ai essayé d'incorporer la partie bonus sur le dewpoint dans le programme "de base", et la vérification annonçait des erreurs diverses, suivant ce que je tentais de faire. Entrer dans le détail m'est difficile, vu que je n'y connais rien. Mais j'ai tenté, toute un journée … Ce rajout est-il suffisamment simple pour que vous me l'expliquiez succinctement ?


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#578 | Signaler ce message


Entrer dans le détail m'est difficile, vu que je n'y connais rien.

par HERAUD

Un minimum serait de donner une copie du message d'erreur …

Voici un exemple qui marche, mais ce n'est rien de plus qu'un copier-coller de l'article :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
 * Exemple de code pour la lecture d'un capteur DHT11 ou DHT22.
 */

/** Broche "DATA" du capteur */
const byte BROCHE_CAPTEUR = 5;

/* Code d'erreur de la fonction readDHT11() et readDHT22() */
const byte DHT_SUCCESS = 0;        // Pas d'erreur
const byte DHT_TIMEOUT_ERROR = 1;  // Temps d'attente dépassé
const byte DHT_CHECKSUM_ERROR = 2; // Données reçues erronées

/** Fonction setup() */
void setup() {
 
  /* Initialisation du port série */
  Serial.begin(115200);
  Serial.println(F("Demo DHT11 et DHT22"));
  
  /* Place la broche du capteur en entrée avec pull-up */
  pinMode(BROCHE_CAPTEUR, INPUT_PULLUP);
}

/** Fonction loop() */
void loop() {
  float temperature, humidity;
 
  /* Lecture de la température et de l'humidité, avec gestion des erreurs */
  // N.B. Remplacer readDHT11 par readDHT22 en fonction du capteur utilisé !
  switch (readDHT22(BROCHE_CAPTEUR, &temperature, &humidity)) {
  case DHT_SUCCESS: 
     
    /* Affichage de la température et du taux d'humidité */
    Serial.print(F("Humidite (%): "));
    Serial.println(humidity, 2);
    Serial.print(F("Temperature (^C): "));
    Serial.println(temperature, 2);
    
    Serial.print(F("Point de rosée (^C): "));
    Serial.println(dewPoint(temperature, humidity), 2);
    break;
 
  case DHT_TIMEOUT_ERROR: 
    Serial.println(F("Pas de reponse !")); 
    break;
 
  case DHT_CHECKSUM_ERROR: 
    Serial.println(F("Pb de communication !")); 
    break;
  }
  
  /* Pas plus d'une mesure par seconde */
  // N.B. Avec le DHT22 il est possible de réaliser deux mesures par seconde
  delay(1000);
}

/**
 * Lit la température et le taux d'humidité mesuré par un capteur DHT11.
 *
 * @param pin Broche sur laquelle est câblée le capteur.
 * @param temperature Pointeur vers la variable stockant la température.
 * @param humidity Pointeur vers la variable stockant le taux d'humidité.
 * @return DHT_SUCCESS si aucune erreur, DHT_TIMEOUT_ERROR en cas de timeout, ou DHT_CHECKSUM_ERROR en cas d'erreur de checksum.
 */
byte readDHT11(byte pin, float* temperature, float* humidity) {
  
  /* Lit le capteur */
  byte data[5];
  byte ret = readDHTxx(pin, data, 18, 1000);
  
  /* Détecte et retourne les erreurs de communication */
  if (ret != DHT_SUCCESS) 
    return ret;
    
  /* Calcul la vraie valeur de la température et de l'humidité */
  *humidity = data[0];
  *temperature = data[2];

  /* Ok */
  return DHT_SUCCESS;
}

/**
 * Lit la température et le taux d'humidité mesuré par un capteur DHT22.
 *
 * @param pin Broche sur laquelle est câblée le capteur.
 * @param temperature Pointeur vers la variable stockant la température.
 * @param humidity Pointeur vers la variable stockant le taux d'humidité.
 * @return DHT_SUCCESS si aucune erreur, DHT_TIMEOUT_ERROR en cas de timeout, ou DHT_CHECKSUM_ERROR en cas d'erreur de checksum.
 */
byte readDHT22(byte pin, float* temperature, float* humidity) {
  
  /* Lit le capteur */
  byte data[5];
  byte ret = readDHTxx(pin, data, 1, 1000);
  
  /* Détecte et retourne les erreurs de communication */
  if (ret != DHT_SUCCESS) 
    return ret;
    
  /* Calcul la vraie valeur de la température et de l'humidité */
  float fh = data[0];
  fh *= 256;
  fh += data[1];
  fh *= 0.1;
  *humidity = fh;
 
  float ft = data[2] & 0x7f;
  ft *= 256;
  ft += data[3];
  ft *= 0.1;
  if (data[2] & 0x80) {
    ft *= -1;
  }
  *temperature = ft;

  /* Ok */
  return DHT_SUCCESS;
}

/**
 * Fonction bas niveau permettant de lire la température et le taux d'humidité (en valeurs brutes) mesuré par un capteur DHTxx.
 */
byte readDHTxx(byte pin, byte* data, unsigned long start_time, unsigned long timeout) {
  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
  // start_time est en millisecondes
  // timeout est en microsecondes
 
  /* Conversion du numéro de broche Arduino en ports / masque binaire "bas niveau" */
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *ddr = portModeRegister(port);   // Registre MODE (INPUT / OUTPUT)
  volatile uint8_t *out = portOutputRegister(port); // Registre OUT (écriture)
  volatile uint8_t *in = portInputRegister(port);   // Registre IN (lecture)
  
  /* Conversion du temps de timeout en nombre de cycles processeur */
  unsigned long max_cycles = microsecondsToClockCycles(timeout);
 
  /* Evite les problèmes de pull-up */
  *out |= bit;  // PULLUP
  *ddr &= ~bit; // INPUT
  delay(100);   // Laisse le temps à la résistance de pullup de mettre la ligne de données à HIGH
 
  /* Réveil du capteur */
  *ddr |= bit;  // OUTPUT
  *out &= ~bit; // LOW
  delay(start_time); // Temps d'attente à LOW causant le réveil du capteur
  // N.B. Il est impossible d'utilise delayMicroseconds() ici car un délai
  // de plus de 16 millisecondes ne donne pas un timing assez précis.
  
  /* Portion de code critique - pas d'interruptions possibles */
  noInterrupts();
  
  /* Passage en écoute */
  *out |= bit;  // PULLUP
  delayMicroseconds(40);
  *ddr &= ~bit; // INPUT
 
  /* Attente de la réponse du capteur */
  timeout = 0;
  while(!(*in & bit)) { /* Attente d'un état LOW */
    if (++timeout == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
  }
    
  timeout = 0;
  while(*in & bit) { /* Attente d'un état HIGH */
    if (++timeout == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
  }

  /* Lecture des données du capteur (40 bits) */
  for (byte i = 0; i < 40; ++i) {
 
    /* Attente d'un état LOW */
    unsigned long cycles_low = 0;
    while(!(*in & bit)) {
      if (++cycles_low == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
    }

    /* Attente d'un état HIGH */
    unsigned long cycles_high = 0;
    while(*in & bit) {
      if (++cycles_high == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
    }
    
    /* Si le temps haut est supérieur au temps bas c'est un "1", sinon c'est un "0" */
    data[i / 8] <<= 1;
    if (cycles_high > cycles_low) {
      data[i / 8] |= 1;
    }
  }
  
  /* Fin de la portion de code critique */
  interrupts();
 
  /*
   * Format des données :
   * [1, 0] = humidité en %
   * [3, 2] = température en degrés Celsius
   * [4] = checksum (humidité + température)
   */
   
  /* Vérifie la checksum */
  byte checksum = (data[0] + data[1] + data[2] + data[3]) & 0xff;
  if (data[4] != checksum)
    return DHT_CHECKSUM_ERROR; /* Erreur de checksum */
  else
    return DHT_SUCCESS; /* Pas d'erreur */
}

/** Fonction de calcul rapide du point de rosée en fonction de la température et de l'humidité ambiante */
double dewPoint(double celsius, double humidity) {

  // Constantes d'approximation
  // Voir http://en.wikipedia.org/wiki/Dew_point pour plus de constantes
  const double a = 17.27;
  const double b = 237.7;

  // Calcul (approximation)
  double temp = (a * celsius) / (b + celsius) + log(humidity * 0.01);
  return (b * temp) / (a - temp);
}

Pas de photo de profil

HERAUD

Membre

#581 | Signaler ce message


Oui entièrement d'accord, sur le moment j'ai tenté plein d'options, mais sans rien enregistrer. Bon j'arrive à un résultat similaire avec ma version (cf. ci-dessous) et la votre : le programme marche, mais donne une température fausse (11° au lieu des 24° ambiants aujourd'hui). Cette erreur disparaît quand on neutralise la partie du code définissant le dewpoint. Et je ne me l'explique pas.

Ma dernière tentative en date :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/**
 * Exemple de code pour la lecture d'un capteur DHT11 ou DHT22.
 */

/** Broche "DATA" du capteur */
const byte BROCHE_CAPTEUR = 5;

/* Code d'erreur de la fonction readDHT11() et readDHT22() */
const byte DHT_SUCCESS = 0;        // Pas d'erreur
const byte DHT_TIMEOUT_ERROR = 1;  // Temps d'attente dépassé
const byte DHT_CHECKSUM_ERROR = 2; // Données reçues erronées

/*Declaration*/
const double a = 17.27;
const double b = 237.7;
float DewPoint;
float temp;

/** Fonction setup() */
void setup() {
 
  /* Initialisation du port série */
  Serial.begin(115200);
  Serial.println(F("Demo DHT11 et DHT22"));
  
  /* Place la broche du capteur en entrée avec pull-up */
  pinMode(BROCHE_CAPTEUR, INPUT_PULLUP);
}

/** Fonction loop() */
void loop() {
  float temperature;
  float humidity;
 
  /* Lecture de la température et de l'humidité, avec gestion des erreurs */
  // N.B. Remplacer readDHT11 par readDHT22 en fonction du capteur utilisé !
  switch (readDHT22(BROCHE_CAPTEUR, &temperature, &humidity)) {
  case DHT_SUCCESS: 

/*Partie dewPoint*/
     temp = (a * temperature) / (b + temperature) + log(humidity * 0.01);
     DewPoint = (b * temp) / (a - temp);
    
    /* Affichage de la température et du taux d'humidité et dewPoint */
    Serial.print("Humidite (%): ");
    Serial.println(humidity, 2);
    Serial.print("Temperature (^C): ");
    Serial.println(temperature, 2);
    Serial.print("DewPoint: ");
    Serial.println(DewPoint, 2);
    break;
 
  case DHT_TIMEOUT_ERROR: 
    Serial.println(F("Pas de reponse !")); 
    break;
 
  case DHT_CHECKSUM_ERROR: 
    Serial.println(F("Pb de communication !")); 
    break;
  }
  
  /* Pas plus d'une mesure par seconde */
  // N.B. Avec le DHT22 il est possible de réaliser deux mesures par seconde
  delay(1000);
 
}

/**
 * Lit la température et le taux d'humidité mesuré par un capteur DHT11.
 *
 * @param pin Broche sur laquelle est câblée le capteur.
 * @param temperature Pointeur vers la variable stockant la température.
 * @param humidity Pointeur vers la variable stockant le taux d'humidité.
 * @return DHT_SUCCESS si aucune erreur, DHT_TIMEOUT_ERROR en cas de timeout, ou DHT_CHECKSUM_ERROR en cas d'erreur de checksum.
 */
byte readDHT11(byte pin, float* temperature, float* humidity) {
  
  /* Lit le capteur */
  byte data[5];
  byte ret = readDHTxx(pin, data, 18, 1000);
  
  /* Détecte et retourne les erreurs de communication */
  if (ret != DHT_SUCCESS) 
    return ret;
    
  /* Calcul la vraie valeur de la température et de l'humidité */
  *humidity = data[0];
  *temperature = data[2];

  /* Ok */
  return DHT_SUCCESS;
}

/**
 * Lit la température et le taux d'humidité mesuré par un capteur DHT22.
 *
 * @param pin Broche sur laquelle est câblée le capteur.
 * @param temperature Pointeur vers la variable stockant la température.
 * @param humidity Pointeur vers la variable stockant le taux d'humidité.
 * @return DHT_SUCCESS si aucune erreur, DHT_TIMEOUT_ERROR en cas de timeout, ou DHT_CHECKSUM_ERROR en cas d'erreur de checksum.
 */
byte readDHT22(byte pin, float* temperature, float* humidity) {
  
  /* Lit le capteur */
  byte data[5];
  byte ret = readDHTxx(pin, data, 1, 1000);
  
  /* Détecte et retourne les erreurs de communication */
  if (ret != DHT_SUCCESS) 
    return ret;
    
  /* Calcul la vraie valeur de la température et de l'humidité */
  float fh = data[0];
  fh *= 256;
  fh += data[1];
  fh *= 0.1;
  *humidity = fh;
 
  float ft = data[2] & 0x7f;
  ft *= 256;
  ft += data[3];
  ft *= 0.1;
  if (data[2] & 0x80) {
    ft *= -1;
  }
  *temperature = ft;

  /* Ok */
  return DHT_SUCCESS;
}

/**
 * Fonction bas niveau permettant de lire la température et le taux d'humidité (en valeurs brutes) mesuré par un capteur DHTxx.
 */
byte readDHTxx(byte pin, byte* data, unsigned long start_time, unsigned long timeout) {
  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
  // start_time est en millisecondes
  // timeout est en microsecondes
 
  /* Conversion du numéro de broche Arduino en ports / masque binaire "bas niveau" */
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *ddr = portModeRegister(port);   // Registre MODE (INPUT / OUTPUT)
  volatile uint8_t *out = portOutputRegister(port); // Registre OUT (écriture)
  volatile uint8_t *in = portInputRegister(port);   // Registre IN (lecture)
  
  /* Conversion du temps de timeout en nombre de cycles processeur */
  unsigned long max_cycles = microsecondsToClockCycles(timeout);
 
  /* Evite les problèmes de pull-up */
  *out |= bit;  // PULLUP
  *ddr &= ~bit; // INPUT
  delay(100);   // Laisse le temps à la résistance de pullup de mettre la ligne de données à HIGH
 
  /* Réveil du capteur */
  *ddr |= bit;  // OUTPUT
  *out &= ~bit; // LOW
  delay(start_time); // Temps d'attente à LOW causant le réveil du capteur
  // N.B. Il est impossible d'utilise delayMicroseconds() ici car un délai
  // de plus de 16 millisecondes ne donne pas un timing assez précis.
  
  /* Portion de code critique - pas d'interruptions possibles */
  noInterrupts();
  
  /* Passage en écoute */
  *out |= bit;  // PULLUP
  delayMicroseconds(40);
  *ddr &= ~bit; // INPUT
 
  /* Attente de la réponse du capteur */
  timeout = 0;
  while(!(*in & bit)) { /* Attente d'un état LOW */
    if (++timeout == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
  }
    
  timeout = 0;
  while(*in & bit) { /* Attente d'un état HIGH */
    if (++timeout == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
  }

  /* Lecture des données du capteur (40 bits) */
  for (byte i = 0; i < 40; ++i) {
 
    /* Attente d'un état LOW */
    unsigned long cycles_low = 0;
    while(!(*in & bit)) {
      if (++cycles_low == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
    }

    /* Attente d'un état HIGH */
    unsigned long cycles_high = 0;
    while(*in & bit) {
      if (++cycles_high == max_cycles) {
        interrupts();
        return DHT_TIMEOUT_ERROR;
      }
    }
    
    /* Si le temps haut est supérieur au temps bas c'est un "1", sinon c'est un "0" */
    data[i / 8] <<= 1;
    if (cycles_high > cycles_low) {
      data[i / 8] |= 1;
    }
  }
  
  /* Fin de la portion de code critique */
  interrupts();
 
  /*
   * Format des données :
   * [1, 0] = humidité en %
   * [3, 2] = température en degrés Celsius
   * [4] = checksum (humidité + température)
   */
   
  /* Vérifie la checksum */
  byte checksum = (data[0] + data[1] + data[2] + data[3]) & 0xff;
  if (data[4] != checksum)
    return DHT_CHECKSUM_ERROR; /* Erreur de checksum */
  else
    return DHT_SUCCESS; /* Pas d'erreur */
}

Je présente votre travail à un informaticien cette aprèm (suis en formation). Peut-être trouvera-t-il l'astuce. Je vous tiens au jus. Merci pour le temps consacré à mon cas. Crdt, E.H.

Derniére modification le par skywodd


Pas de photo de profil

HERAUD

Membre

#582 | Signaler ce message


Bon le formateur sèche également.

Précision : lorsqu'on rajoute le bonus, c'est très curieux, les relevés de température et d'humidité ne sont plus bons. La température reste inférieur ou égal à 12°, et l'humidité passe de 50 à 30° env.

JE vais tenter sur un autre poste.


Pas de photo de profil

HERAUD

Membre

#583 | Signaler ce message


Autant pour moi !! Le problème venait de mon ordi. Tout marche impec Merci !


Pas de photo de profil

cgibaux

Membre

#587 | Signaler ce message


Bonjour,

Tout d'abord merci pour cet article super détaillé et très clair, on comprend bien comment le code marche. Cependant quand j'exécute le code, le capteur se met en timeout error et je ne comprends vraiment pas d'où cela peut venir. Une idée pour me débloquer ? :)

Merci


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#588 | Signaler ce message


Cependant quand j'exécute le code, le capteur se met en timeout error et je ne comprends vraiment pas d'où cela peut venir.

par cgibaux

Le câblage est bon ? La résistance est bien câblée au VCC ?

Quand le code part en timeout c'est que le capteur ne répond pas.