ATtiny 85 et DHT11

Bonjour,
Je voulais construire un projet tout bête qui allume une led RVB suivant la température en respectant les consignes de climatisation/chauffage émises par le gouvernement espagnol..
Équipement autonome avec pile bouton 3v.
Mais j'ai beau utiliser les exemples fournis dans le github ou les dépôts, chaque collecte de données me retourne un code erreur alors qu'avec un Arduino nano et le même montage, ça fonctionne très bien. Et ce quelle que soit la bibliothèque utilisée (SimpleDHT, DHT11, DHT, TinyDHT...). Rien n'y fait. J'ai même testé un résistance entre le + et la broche data du DHT11, rien n'y fait.
Tout cela n'est pas logique mais j'ai lu que le DHT11 et l'ATtiny ne faisaient pas toujours bon ménage. Je vous livre le code de test (qui ne fait que tester):
Si vous avez une piste je suis preneur.

#include "SimpleDHT.h"
#include <SoftwareSerial.h>

#define DHTPIN 0  // DHT connected to Arduino Uno Digital Pin 2
#define DHTTYPE DHT11   // DHT 11 

SoftwareSerial Serial(7, 4);
SimpleDHT11 dht11;

void setup() {
  Serial.begin(9600); // Output status on Uno serial monitor
  Serial.println("DHT11 test!");
}

void loop() {
  byte temperature = 0, humidity = 0;
  int err = SimpleDHTErrSuccess;
  for (byte i = 0; i < 10; i++) {
    if ((err = dht11.read(DHTPIN, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
      Serial.print("Read failed! Error Code: ");
      Serial.println (err);
      delay(1000);
      return;
    }
    else {

    }
    Serial.print("Temp: ");
    Serial.print((int)temperature);
    Serial.print("Humidity: ");
    Serial.println((int)humidity);
    delay(1000);
  }
}

Et si tu donnais le code d'erreur ?

Excuses et merci. Mais comme le code est différent suivant la bibliothèque utilisée ...
Avec SimpleDHT, c'est -237.
Voilà.

Bonjour @vangeles

Quelle horloge est utilisée pour faire tourner ton micro-controlleur ATtiny85 ?

Bonjour,
Je l'ai laissé à 1 Mhz.
Si je le mets à 8Mhz (sortie série toujours à 9600), j'obtiens des valeurs aléatoires mais très souvent 4113±1 ou 6161±1
Cdlt

Code 237
Désolé mais je ne connais pas cette bibliothèque, j'espérai que tu donnes la nature de l'erreur et pas un simple numéro.

Le DHT11 est un circuit rapide. L'erreur est probablement une erreur "checksum" -> somme de contrôle.

A 1 MHz d'horloge il n'y avait aucune chance que cela fonctionne.
A 8 MHz peut-être que cela fonctionne, mais seulement avec une bibliothèque qui n'utilise pas la fonction digitalWrite() qui est trop lente.
La nano fonctionne avec une horloge de 16 MHz.
Même à 16 MHz la fonction digitalRead était trop lente.

Il faut que tu trouve une bibliothèque comme celle de Rob Tillaart qui fait appel aux macros de l'IDE qui font la conversion "Numérotation Microchip" vers "numérotation Arduino" et qui évite toutes les actions inutiles de la fonction digitalWrite()

Peut-être que la bibliothèque de Rob Tillaart est compatible AT85.

Principe du DHT11 / DHT22
Un bit 0 est constitué d'une élément binaire 0 suivi d'un élément binaire 1 qui est plus court que le 0.
Un bit 1 est constitué d'une élément binaire 0 suivi d'un élément binaire 1 qui est plus long que le 0..
Pour savoir si on reçoit un 0 ou un 1 il suffit de comparer le temps passé dans la boucle de détection du 0 avec celui passé dans la détection du 1.

Avec le temps d'exécution de digitalWrite on ne fait pas assez de tour dans chaque boucle et le résultat est incertain ce qui donne des erreurs de somme de contrôle.

Déjà merci pour ces détails.
Je commençais à soupçonner un problème de vitesse d'horloge.
Je vais étudier ta réponse et analyser les bibliothèques pour essayer d'en trouver une qui contourne ce problème de lenteur du digitalRead.
Malheureusement je ne peux pas m'y remettre avant le début de la semaine prochaine et en mettant la fréquence à 16Mhz je perds les traces Serial.print qui deviennent illisibles, même en laissant le port série à 9600 bauds.
Donc le sujet reste entier mais j'ai des pistes à explorer.
Merci encore.

Je précise que je n’ai jamais utilisé l’ATtiny85.

Quand tu dis que tu étais à 1 MHz puis à 8 MHz, faut-il comprendre qu’il n’y a ni quartz ni résonateur et que tu tournes sur l’oscillateur interne ?

As tu installé un bootloader ?

Bonjour il semblerait quelle le soit

la charger et essayer un des exemples...

Je n'avais pas trop d'inquiétude si c'est la version pour Atmel avr.

La version que je connais a quand même un défaut, a mon idée bien sur, c'est qu'elle utilise millis() pour mesurer le temps passé dans la boucle du 0 et dans celle du 1du "0" et du "1".
Une bibliothèque n'est pas prévue pour faire de la métrologie, elle est prévue pour être fonctionnelle et dans le cas présent ou la rapidité est importante pour ne pas faire d'actions inutiles.

Quand je me suis intéressé au DHT22, je suis parti des bibliothèques existantes, pas question de réinventer la roue.
Je n'ai pas utilisé millis(), j'ai utilisé la variable qui sert au TIMEOUT et qui est incrémenté à chaque tour de boucle while.

Cette variable était commune à la boucle "0" et à la boucle "1.
elle n'avait qu'un but ne pas bloquer le programme en cas de câblage défecctueux.
J'en ai créé une par type de boucle : timeout_0 et timeout_1.
Au lieu de comparer les résultats de millis(), il suffit de comparer si timeout_1 est plus petit ou plus grand que timeout_0.

C'est plus rapide et très probablement intéressant avec un micro de 8 MHz d'horloge.
J'avais échangé avec l'auteur, a l'époque il n'a pas retenu ma proposition.

Bonsoir

Je m'y suis donc remis.
J'ai bien utilisé la bibliothèque de Rob Tillaart .
J'ai utilisé le job de test à du Github à cette adresse. DHTlib/examples/dht11_test/dht11_test.ino at master · RobTillaart/DHTlib · GitHub

J'ai testé sur un nano et un ATtiny 85 (même schéma).
Voilà la réponse sur ATtiny

DHT11, Checksum error, 43.0, 87.0
DHT11, Checksum error, 43.0, 31.0
DHT11, Checksum error, 41.0, 23.0
DHT11, Checksum error, 42.0, 31.0
DHT11, Checksum error, 62.0, 110.0
DHT11, OK, 42.0, 23.0
DHT11, OK, 42.0, 23.0
DHT11, Checksum error, 14.0, 87.0
DHT11, Checksum error, 42.0, 31.0
DHT11, Checksum error, 58.0, 86.0
DHT11, Checksum error, 63.0, 55.0
DHT11, Checksum error, 42.0, 87.0

On voit que j'ai des réponses souvent en erreur (quand elles sont OK ça me semble cohérent). Sur Nano j'ai à peu près le même taux d'erreur mais les valeurs sont bien meilleures.

Type, status, Humidity (%), Temperature (C)
DHT11, Checksum error, 51.0, 23.0
DHT11, OK, 51.0, 24.0
DHT11, Checksum error, 50.0, 24.0
DHT11, Checksum error, 49.0, 24.0
DHT11, Checksum error, 49.0, 24.0
DHT11, Checksum error, 48.0, 24.0
DHT11, Checksum error, 47.0, 24.0
DHT11, Checksum error, 47.0, 24.0
DHT11, Checksum error, 46.0, 24.0
DHT11, Checksum error, 45.0, 24.0
DHT11, Checksum error, 45.0, 24.0
DHT11, Checksum error, 44.0, 24.0
DHT11, Checksum error, 44.0, 24.0

Je pourrais éventuellement ne retenir que les valeurs à OK mais ça m'oblige à tester très souvent alors que je ne voulais faire une mise à jour que toutes les 1 à 5 minutes (pile CR2016 ou 2032).
Je pense que je vais abandonner le sujet. Je laisse encore ouvert quelques temps au cas où...

Merci

PS: et au bout d'un moment, sur le nano, les valeurs OK se stabilisent.

DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0
DHT11, OK, 44.0, 22.0

Cela confirme que c’etait des erreurs de somme de controle, ainsi que mon affirmation comme quoi l’usage de millis() est une erreur de conception.

Essayes dans les fichiers de la bibliothèque de :
1 commenter tous les appels a milli()

Par couple zero + un :
2 utilises deux variables pour le TimeOut, une pour la boucle de detection du 0 et une pour la boucle de detection du 1.
3 pour définir si le couple recu (zéro suivi d’un un) est un bit 0 ou un bit 1 compares les deux valeurs des variables TimeOut.

  • si timeout1 a une valeur plus grande que timeout0 c’est que le temps passé dans la boucle while du 1 est plus long que celui passé dans la boucle du 0.
    Le bit reçu est donc un bit 1.
  • vice versa si timeout1 est plus petis que timeout0, c’est un bit 0.

Ce traitement est plus rapide que l’usage de millis qui est totalement inapproprié dans ce cas.
C’est ma vue des choses en temps qu’électronicien qui a une vision "matériel ”.

Note :
Sans faire la vérification cela ne garanti pas que cela fonctionnera avec un avr 8 bit a 8 MHz, cela mettra toutes les chances de tn côté.

Sur un attiny sans quartz un réglage OSCCAL pourrait améliorer ???

Le mauvais fonctionnement que j'ai identifié, dans la bibliothèque officielle de l'époque, est que la boucle en cours fait trop de choses lentes et que l'usage de millis() bouffe du temps d'exécution à la boucle suivante.

Cela se traduit par un pas de mesure trop long et une perte de sensibilité.

On peut arriver à ne pas être capable de distinguer le temps d'un 1 de celui d'un 0, ce qui est impossible.
D'où le grand nombre d'erreurs "checksum".

Il n'est pas interdit de penser que si Aosong a ajouté une somme de contrôle aux informations de lecture, c'est qu'Aosong avait bien identifié un potentiel problème de lecture.

Il y a une dizaine d'années le DHT11 avait mauvaise presse et nombreux étaient ceux le classaient comme mauvais : les bibliothèques de l'époque (usage de digitalRead + milli) donnaient 80 % d'erreur de somme de contrôle.

Déjà je vous remercie vous deux (@68tjs et @jfs59) pour vos réponses.
Je ne suis pas électronicien mais informaticien à la retraite. Pour autant je comprends un peu vos remarques.
Décoder le programme source de la bibliothèque va me prendre du temps mais j'en ai un peu. Je comprends la différence entre milli() et un boucle; dans le premier cas le milli lui-même prend des ressources alors que la boucle moins. Donc dans le principe on compare la même chose mais par deux méthodes différentes.
Je ne sais pas si la source est bien documentée mais je vais l'extraire du .zip de Github dans un premier temps.
Même si j'avais plus ou moins abandonné l'idée du projet, le curiosité peut me pousser à creuser. Je vous tiens informé.
Cdlt

Cà y est, je viens de terminer mes fouilles archéologiques dans mon PC.

Précision importante : je n'ai pas utilisé de DHT11 mais un DHT22.
Si mes souvenirs sont bons il y a des petites différences du coté de l'hygrométrie.

Dans le fichier zip tu trouveras un programme ino , un fichier *.h et un fichier *.cpp
Je n'ai pas géré en mode bibliothèque, mais en mode programmation en fichiers séparés.

Les 2 fichiers h et cpp sont à mettre dans le répertoire du fichier ino.
C'est pour cela que la ligne include n'est pas
#include <am2302.h>
mais :
#include "am2302.h"

En principe cela fonctionne (j'espère) mais comme la dernière modif date de 2016 et que je ne suis jamais revenu dessus......

Point important :
Je n'ai pas la maîtrise de Rob Tillaart pour les macros Arduino.
Pour être rapide en lecture, j'ai attaqué la lecture des niveaux reçus avec ce que je savais faire, c'est-à-dire en utilisant directement les registres du microcontrôleur.
C'est beaucoup moins portable que ce qu'à fait Rob, mais cela a le mérite d'exister et de fonctionner.

Rappel : j'ai utilisé un DHT22 (am3202) et non un DHT11

Il faudra te plonger dans la datasheet de l'ATtiny85 pour connaitre les noms des ports de ce micro.

En pj :

  • le fichier zip
  • la doc
    -- AM2301 = DHT11
    -- AM2302 = DHT22 (pour comprendre les différences avec un DH11)

DHT11.pdf (466,5 Ko)
AM2302.pdf (570,5 Ko)
test_am2302.zip (4,5 Ko)

Bon courage.

Bonsoir,
Je réponds simplement pour vous dire que mon sujet est toujours vivant.
Mais mon niveau technique m'oblige à regarder ça en détail, et pas avant la semaine du 24 mars (je pense être comme vous, retraité, donc trop occupé...).
Voilà et merci encore; je partage d'ailleurs vos recherches avec un ami intéressé.
Cdlt