Avec un Atmega, créer un capteur de température sans fil

Pour continuer le projet de domotique avec le Raspberry, la première étape importante pour moi est d’avoir un capteur capable d’envoyer sans fil des données. Ici je vous présente un exemple de sonde mesurant température et humidité.

Pi Home Connect - temperature humidity sensor atmega 328

Dans cet article (très très long), je préviens que vous n’allez peut être pas créer la meilleure sonde du monde. De nombreux sites proposent des méthodes poussées pour arriver à une solution optimale. Ici je vous présente le résultat de mes tests et vous propose de le réaliser chez vous. Je compte sur les experts pour proposer des améliorations via les commentaires 🙂

Pour rappel ma sonde fonctionne sur deux piles AA, avec un Atmega328, une LED pour indiquer le fonctionnement et un émetteur 433Mhz. La LED est optionnelle car source de consommation d’énergie mais pratique pour confirmer que tout fonctionne.

Après 16 17 18 19 20 jours de fonctionnement (la rédaction de l’article a pris du temps), ma sonde émet toujours les données avec une distance de 5m entre la sonde et la Gateway (un arduino connecté à un Raspberry Pi), sans murs mais avec un meuble en bois. Voici l’évolution du niveau des piles sur deux semaines :

Pi Home Connect - temperature humidity sensor atmega 328 - interface

La sonde a le fonctionnement suivant : toutes les 5 secondes (oui c’est pour les tests), la sonde DHT11 est activée, la température et l’humidité sont lues ainsi que le niveau des piles. Ces données constituent le message à envoyer. Le message est envoyé 4 fois à 160ms d’interval. Chaque envoi fait s’allumer puis éteindre la LED.

Vous pouvez donc imaginer qu’en diminuant le nombre d’envois, en supprimant la LED et en augmentant le temps entre chaque mesure, vos piles pourront durer facilement un an (je ferais bientôt un article sur le sujet).

Pré requis

Avant de pouvoir vous lancer dans l’aventure, il faut avoir un peu de matériel et un environnement de travail prêt à l’emploi.

Matériel

Vous aurez besoin :

  • D’un atmega328 (juste la puce) avec ou sans bootloader, peu importe car nous allons y installer le notre. Vous en trouverez facilement sur ebay ou des sites chinois dans les 1.5€/pièce ou encore Amazon. En en commandant plusieurs vous pouvez encore diminuer un peu le prix.
    Pi Home Connect - Atmega328P
  • D’un Arduino UNO où vous pouvez enlever l’atmega. Il sera utilisé pour envoyer le bootloader et le programme de gestion de la sonde. Vous pourrez utiliser cet Arduino (ou un autre) comme récepteur. Comptez dans les 10€ (version non officielle mais légale), un peu plus sur Amazon (plus rapide). La carte pourra servir pour fabriquer d’autres sondes.
    Pi Home Connect - Arduino Uno with Atmega328p
  • Une sonde de température. J’ai utilisé une DHT11 que j’avais à la maison. Ce n’est vraiment pas ce qu’il y a de mieux, la DHT22 étant bien meilleure, mais je n’avais que ça sous la main à l’époque. Comptez 1.40€ la DHT11 ou 4.5€ la DHT22 (mais ca vaut le cout)
    Pi Home Connect - DHT11
  • Une résistance 4.7KΩ nécessaire pour la sonde DHT11
    Pi Home Connect - resitor 4k7
  • Un émetteur et un récepteur 433Mhz. L’émetteur sera pour la sonde, le récepteur pour l’Arduino connecté au Raspberry. Un peu moins de 1€ la paire. Mais attention tous n’ont pas la même qualité … Par la suite je testerai d’autres modules de communication.
    Pi Home Connect - 433Mhz rf kit
  • Des piles AA. J’en utilise 2 que j’ai mis dans un boitier récupéré sur une guirlande LED de Noël. Les boitiers coutent environ 3.5€ les dix pièces (ou ici pour une livraison plus rapide).Pi Home Connect - 2x AA battery holder
  • Des filsPi Home Connect - wires
  • Une breadboard. Par le suite vous pourrez utiliser des plaques de prototypage, moins encombrantes et réutiliser la breadboard pour d’autres montages.Pi Home Connect - Breadboard
  • (Optionnel mais très conseillé !) Des condensateurs de 22µF. Il en faudra 2 si vos Atmega328 sont configurés par défaut pour utiliser un oscillateur externe (et je ne crois pas que vous puissiez le savoir à l’avance)
    Pi Home Connect - 22uF capacitor
  • (Optionnel mais très conseillé !) Un résonateur 8Mhz ou 16Mhz si vos Atmega328 sont configurés par défaut pour utiliser un oscillateur externe
    Pi Home Connect - 16mhz resonator

Vous voilà maintenant équipés et prêt à assembler votre sonde.

Environnement de travail

Quand je parle d’environnement de travail c’est essentiellement l’outil Arduino IDE. Prenez bien la version 1.5.8+, même si c’est une beta, pour pouvoir travailler !

Il s’agit maintenant de pouvoir configurer votre Atmega pour fonctionner avec son oscillateur interne (8Mhz) pour diminuer sa consommation générale. Pour cela je vous conseille de charger le fichier ZIP ici. L’archive doit être décompressée dans le sous répertoire hardware situé avec les différents programmes de votre Arduino. Voici ce que vous devez avoir :

Arduino IDE boards.txt folder mac os

Au démarrage de l’IDE Arduino vous devriez voir les nouvelles cartes installées :

Pi Home Connect - boards atmega328 8Mhz low power

Installation d’un bootloader optimisé

Voici le câblage pour charger le bootloader :

PiHomeConnect-Node bootloader atmega328

Une fois réalisé :

  • Connecter l’arduino UNO à votre ordinateur via son câble USB
  • Démarrer Arduino IDE puis confirmer la configuration
  • Upload du programme pour que le UNO puisse envoyer le bootloader. Le programme est disponible dans le menu « Fichier > Exemples > ArduinoISP ». Puis cliquer sur « Téléverser »
    LPi Home Connect - IDE arduino ISP‘Arduino UNO est maintenant prêt à envoyer un bootloader à votre montage !
  • Sélectionner le type de carte pour votre sonde. Nous choisissons donc un atmega328 sur un arduino en 3.3V et à la fréquence de 8Mhz
    Pi Home Connect - IDE bootloader 8Mhz 3.3V
  • Maintenant sélectionner la carte qui va programmer le bootloader. Il s’agit de notre Arduino
    Pi Home Connect - IDE bootloader Arduino as ISP
  • Reste à graver le bootloader avec la commande « Graver le bootloader »

Vous avez maintenant configuré votre node pour fonctionner en 3.3V en utilisant l’oscillateur interne qui fonctionne à 8Mhz. C’est la première étape pour optimiser l’utilisation de l’énergie !

Vous pouvez maintenant ajouter votre sonde et l’émetteur. Si vous avez mis un résonateur, vous pouvez l’enlever (ainsi que les condensateurs) :

PiHomeConnect - Arduino node temperature humidity sensor

La carte Arduino UNO vous sera utile pour envoyer le programme dans votre nouvel Atmega. Vous pouvez la connecter comme sur le dessin ci dessus où bien prendre l’Atmega du node, le mettre sur la carte UNO, charger le programme grâce à l’IDE puis replacer l’Atmega du node sur la breadboard. A vous de voir, personnellement je déplace l’atmega 😉

La photo du montage final :

PiHomeConnect - Arduino node temperature humidity sensor

Installation du programme du capteur

Dans l’Arduino IDE vous devrez installer les librairies suivantes :

  • La librairie DHT pour récupérer les données de votre sonde. Disponible ici.
  • La librairie Narcoleptic pour mettre en sommeil « profond » votre node et ainsi économiser les piles. Disponible ici.
  • La librairie Manchester pour envoyer les données via votre émetteur 433Mhz. Disponible ici.

L’installation des librairies se fait de la manière suivante :

  • Récupérer le .zip de la librairie
  • L’importer grâce à l’outil d’importation dans Arduino IDE (Sketches > Import librairies)

Voici le programme à envoyer vers votre node grâce à l’Arduino IDE :

#include <Narcoleptic.h>
#include <dht.h>
#include <Manchester.h>

#define BLINK_MODE true

#define NODE_ID 1 // On 8bits so 0..255

#define MESSAGE_SIZE 6 // Number of bytes to send
#define SEND_MESSAGE_DELAY 5000 // Delay in ms between each value's extraction
#define SEND_433_COUNT 4 // How many times the message has to be send
#define SEND_433_PAUSE 160 // 16 multiple

// Define connectors used for the node
#define TX_PIN 7
#define LED_PIN 13
#define DHT11_PIN 2

dht DHT;
// Array of bytes to will make the message
// In this node : 2 bytes for voltage, 2 bytes for
uint8_t msgData[MESSAGE_SIZE] = {0, 0, 0, 0, 0, 0};

//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------
 long readVcc() {
   bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
   long result;
   // Read 1.1V reference against Vcc
   #if defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
   #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    ADMUX = _BV(MUX3) | _BV(MUX2);
   #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  // For ATmega328
   #endif
   delay(2); // Wait for Vref to settle
   ADCSRA |= _BV(ADSC); // Convert
   while (bit_is_set(ADCSRA,ADSC));
   result = ADCL;
   result |= ADCH<<8;
   result = 1126400L / result; // Back-calculate Vcc in mV
   ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
   return result; // Vcc in millivolts
} 

void setup() {
  pinMode(LED_PIN, OUTPUT);
  if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
  man.setupTransmit(TX_PIN, MAN_1200);
  msgData[0] = NODE_ID;
  // Wait 1s to allow DHT11 to initialize
  Narcoleptic.delay(1000);
}

void loop() {
  // Read Vcc value
  long currentVcc = readVcc();
  uint16_t uint16_currentVcc = (uint16_t)currentVcc;
  // Save millivolts in two bytes to keep high precision. Will be decoded by the gateway
  uint8_t byteData[2] = {uint16_currentVcc >> 8, uint16_currentVcc & 0xFF};
  msgData[2] = byteData[0];
  msgData[3] = byteData[1];

  // Read data from DHT11 sensor
  int chk = DHT.read11(DHT11_PIN);
  // DHT11 values can be put in a byte value due to the low precision
  msgData[4] = (uint8_t)DHT.humidity;
  msgData[5] = (uint8_t)DHT.temperature;

  // Send message SEND_433_COUNT times with a delay of SEND_433_PAUSE ms for each
  for (int i=0; i<SEND_433_COUNT; i++) {
    msgData[1] = i;
    if (BLINK_MODE) digitalWrite(LED_PIN, HIGH);
    man.transmitArray(MESSAGE_SIZE, msgData);
    if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
    // Wait between each send
    Narcoleptic.delay(SEND_433_PAUSE);
  }
  // Wait before getting new sensor value
  Narcoleptic.delay(SEND_MESSAGE_DELAY);
}

Et après ?

Le prochain article montrera comment recevoir les données et les envoyer vers le Raspberry Pi qui saura (en principe) quoi en faire !

Il reste quand même à améliorer l’ensemble ! Comme par exemple :

  • Optimisation du code. L’idée est de faire une bibliothèque générale, disponible sous GitHub, qui regroupera toutes les fonctions de récupération, conversion, etc. en fonction des capteurs connectés : DHT11, DHT22, LM36, etc.
  • D’autres modules d’émission : NRF24L01+, ESP8266, etc.
    Les modules 433Mz sont capricieux, pas toujours de bonne qualité, j’ai pas l’impression que ce soit le meilleur choix. Je vais donc continuer l’investigation

La suite du projet Pi Home Connect bientôt !

Vous aimerez aussi...

  • Zescientist

    Hello,
    Ces couples Em/Rec ne sont pas d’excellente qualité.
    Une astuce pour tout de même minimiser le coût : Maintenir ces Em/Rec sur tes modules distants (capteurs et actionneurs) mais investir dans un unique « bon » couple pour ta station maître reliée au RPi. Cela va grandement améliorer ta portée.

    Sinon les ESP8266 semble « la solution » pour de la domotique low-cost, plus besoin d’atmega pour gérer les capteurs, plus besoin d’arduino pour transmettre les informations au RPi et une portée liée à la qualité du Wifi.

    • Effectivement je me dis que le Wifi est capté partout dans la maison donc autant en profiter et le prix est vraiment raisonnable. Je suis pressé de tester en remplaçant mes modules 433Mz 😉

      • mrclem.nw

        oui mais la consommation des ESP8266 est vraiment médiocre. ça tire un max.
        merci pour ton tuto, je voulais refaire mon capteur RF avec juste un ATMega au lieu du microview actuel. mais surtout le faire dormir du coup changer le bootloader. tout ça pour dialoguer avec un module RFXCOM et domoticz

        • Je vais regarder ce que ca donne sachant que le but est de faire dormir l’émetteur car le node ne doit pas recevoir d’instruction. Mais est-ce que la connexion au SSID ne va pas prendre trop de temps … Je vais tester

          • MrClem

            donc effectivement ce n’est pas trop grave si on coupe le transmetteur à chaque fois. Les tests que j’ai vu sont assez lent lorsque c’est un serveur LUA qui tourne dessus mais bon ça évolue à une vitesse…
            merci encore la partie customisation bootloader m’intéresse bcp. Je vais essayer tout ça.

          • MrClem

            arf du coup j’ai des questions 😉 :

            quelles sont les optimisations de ton bootloader ?

            as -ton besoin de ce bootloader optimisé pour utiliser Narcoleptic ? (il semblerait que non)

            par contre je viens de me rendre compte que ça n’ira pas pour mon utilisation. Je fais très peu d’attente dans ma loop(), tout est géré par interval de temps : en gros, je regarde si l’interval est passé pour executer une acquisition et envoyer en RF. Il me faudra une fonction d’endormissement et de réveil plutot mais avec le milli() toujours actif.. Je vais chercher ça, ça doit bien exister.

          • Le bootloader est l’optiboot 5.0a pour atmega328 en 3.3v et 8mhz.

            Narcoleptic permet l’utilisation du watchdog donc ca n’est pas lié au bootloader

            Pour ton soucis je crois savoir que tu peux réveiller ton atmega sur base d’une interruption (y en a 2, la 0 et la 1). Tu as aussi JeeLib qui permet de suivre le temps écoulé : http://jeelabs.net/pub/docs/jeelib/

  • sandu

    finally a tutorial for exactly what I am looking for. Looks similar to the LoFi (Hackaday) project. why don’t you consider lower power MCU like the ATiny84,85 etc.? anyway, the arduino approach is way better then ESP8266 in terms of real wireless sensors without the need to replace batteries.

    • I don’t know what’s the difference between atiny85 and a atmega328P (-PU version of course). Do you think that the battery life will be much more longer ?

      • Sandu

        well, you can run a wireless sensor based on attiny for a year using a coin cell (CR2032) or even for year (10 years on 3 x AA) depending on how often do you transmit,etc.
        did you considered any encryption on the payload that you are transmitting? would be a nice future if you consider extending this project in the future to have bi-directional transmission: receive and send commands to other remote sensors.

        I am also waiting for some RFM12B and RFM69HW transceivers to test them with attiny in a similar project. they have better range and wall penetration than the NRF24L01.

        good luck! waiting for your next part of the tutorial 🙂

  • Galen

    Bravo pour ce tuto 🙂 encore un qui va rejoindre ma collection sur le sujet jusqu’a ce que je me lance
    j’ai aussi celui ci http://labalec.fr/erwan/?p=1534 sous le coude ça peut aider dans la recherche de l’emetteur et recepteur le plus fiable

  • Guillaume

    Bonjour,
    il existe aussi une autre façon de programmer un atmega sans enlever la puce c’est de procéder par le spi et d’incorporer le programme isp sur l’arduino. Mais une autre facon plus agréable est de prendre un arduino pro mini qui revient presque moins cher qu’un atmega ainsi que des composants à mettre à coté.

    • L’arduino mini est en plus très compact donc idéal pour des sondes (c’est la prochaine étape après les différents transmetteurs ;-))

  • David

    Bonjour,

    Merci pour l’article ! Très intéressant ! Surtout que j’ai la même démarche actuellement alors je vais suivre la série avec une grande attention.

    Je viens de passer quelques temps à essayer de coir comment installer un bootloader mais j’ai un peu souffert …

    En regardant les fichiers que tu proposes je vois que contrairement à d’autres liens que j’ai trouvé tu n’utilises pas un bootloader directement fourni avec l’IDE. Y’a t’il une raison ?

    http://hardware-libre.fr/2014/02/fr-arduino-atmega-programmation-isp/
    http://arduino.cc/en/Tutorial/ArduinoToBreadboard

    Pas encore essayé le tien en fait, j’ai d’abord essayé les autres mais même si j’arrive à installer le bootloader (après une petite correction dans board.txt) je n’arrive pas à téléverser le sketch ensuite.

    J’ai vu qu’il fallait utilisé « Téléverser avec un programmeur » au lieu de « Téléverser », est-ce la même chose avec ton bootloader ? (pas encore essayé car j’avais dépassé mon quota de bricolage pour la journée 😉

    David.

    • Le mien est un peu un melange. Le bootloader est celui d’optiboot qui est maintenant dans arduino ide si je me trompe pas. Celui de l’archive est l’atmega 168 pour 328 dans le repertoire bootloader de l’IDE
      Pour le bootloader il faut effectivement passer par un programmeur. Mon article essaye de resumer tout ca car j’ai aussi galeré 😉

      • David

        Hello,

        Bon j’ai essayé avec ton bootloader aujourd’hui et ça fonctionne très bien. J’ai vu que tu avais aussi modifié le fichier platform.txt ? Ca doit expliqué pourquoi juste en modifiant le fichier Board.txt d’origine pour ajouter ta configuration et en utilisant ton bootloader ça ne fonctionne pas …

        Si je fais comme tu le dis dans ton article ça marche nickel alors je vais pas chercher plus loin pour le moment. J’y reviendrai quand j’aurais avancé plus sur le projet.
        Je serai néanmoins très intéressé de comprendre ce que tu as fait comme modification. Une idée pour un autre article ?? 😉 Mais pour le moment j’attends avec impatience l’article sur la liaison entre l’arduino de réception et le RPI. Via une liaison série ? SPI ?

        Bonne continuation !

        • L’article est en ligne 😉 il manque le code pour la réception mais il suffit d’ajouter un récepteur 433 sur l’arduino et envoyer les données vers le raspberry

          Pour le boot loader c’est cool si ça fonctionne. Mais changements sont surtout là pour avoir un package autonome qui s’installe facilement.

          • David

            Salut,

            Suis bien content d’avoir réussi à mettre ton bootloader et d’être passé à 8MHz interne et 3,3V.

            Du coup il n’est plus possible d’utiliser la liaison série via l’arduino UNO après ? J’ai déjà remarqué qu’il fallait débrancher le reset de la carte sinon l’atmega redémarre tout le temps (probablement la différence de potentiel) mais même avec ça je ne vois plus rien via la liaison série de l’IDE ….

            Tu as pareil ?
            Merci.

          • Je vais pas le garantir à 100% mais il me semble que ça fonctionnait.

  • Pascal

    C’est vrai que les émetteur/récepteur 433Mhz low cost sont pas terrible !! mais il existe le projet Mysensors qui utilise des NRF24L01 (émetteur/récepteur 2.4Ghz) qui fonctionnent bien et géré par le projet domotique Jeedom, c’est vraiment bien!

    • Je termine ma bibliothèque Arduino pour les modules Wifi ESP8266 et après je teste les NRF24L01. Je pourrais alors en faire un comparatif pour aider à choisir en fonction de ses besoins.

  • David

    Hello,

    J’ai bien avancé grace à ton article !
    J’ai testé 3 librairies de réduction de consommation de courant … Narcoleptic, Jeelib et Lowpower.

    Je n’arrivais pas à m’en sortir au départ et j’avais une conso de 1mA même en mode POWER_DOWN …
    C’était lié au switchs que j’utilise pour régler le numéro du senseur (tu n’as pas suivi le même principe vu que tu le mets directement dans le code …). Problème réglé en utilisant une sortie de l’arduino pour alimenter les switchs à l’init seulement.

    Bref ! Je voulais partager les consommations que j’obtiens avec les trois librairies.
    8MHz sous 3v. 4mA environ en activité (lecture température, lumière et batterie).

    Au repos :
    – LowPower : 0.030mA (soit 3648 days en gros mais sans l’auto-décharge)
    – Narcoleptic : 0.190mA (soit 623 days environ toujours sans l’auto-décharge)
    – JeeLib : 0.014mA (soit 6689 days pareil sans l’auto-décharge)

    Ca fait quand même une sacrée différence … Je ne sais pas si tu as essayé de regarder la consommation …

    David.

    • Merci pour l’information. J’avais vu JeeLib mais pas LowPower. Je vais faire la bascule 😉
      J’ai fini mes tests avec des ESP8266, j’attaque bientôt les NRF24L01 😉

    • Attention aussi avec les chiffres. La mise en sommeil avec le WatchDog est de 8s max donc toutes les 8s l’Arduino va se réveiller faire une boucle avec un test et se rendormir.

      • David

        Jeelib accepte une valeur jusqu’à 65535 ms … J’ai mis 10 secondes pour le moment et je n’ai pas l’impression qu’il se réveille … Je ne sais pas comment ils font. Je prévois de faire une mesure toutes les 5 minutes donc je vais mettre la commande dans une boucle. L’arduino se réveillera un peu mais il n’y aura pas de mesure donc ça ne devrait pas trop consommer …
        On verra avec le temps.

        Si t’as un retour on pourra comparer.

        David.

  • Arduina

    Bonjour Chris!! Merci beaucoup pour ce tutoriel. Nous avons testé le code sur l'émetteur et fonctionne parfaitement, mais nous ne parvenons pas à générer un code pour le récepteur, Nous avons eu l'intention, mais il ne fonctionne pas nous.
    Notre idée est d'avoir deux émetteurs utilisant les nœuds dans le code que vous avez fait.
    Nous espérons impatient le prochain tutoriel!

    • Hello,

      Here is an example how to receive data on an arduino and send them to the serial port (where i plugged a raspberry pi) :

      #include

      #define RX_PIN 4
      #define LED_PIN 13

      uint8_t moo = 1;
      #define BUFFER_SIZE 6
      uint8_t buffer[BUFFER_SIZE];

      void setup() {
      Serial.begin(115200);
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, moo);
      man.setupReceive(RX_PIN, MAN_1200);
      man.beginReceiveArray(BUFFER_SIZE, buffer);
      }

      void loop() {
      if (man.receiveComplete()) {
      uint8_t receivedSize = 0;
      Serial.print(buffer[0]);Serial.print(";");
      Serial.print(buffer[1]);Serial.print(";");
      float voltage = (buffer[2] < < 8 ) | (buffer[3] & 0xff); Serial.print(voltage/1000);Serial.print(";"); Serial.print(buffer[4]);Serial.print(";"); Serial.print(buffer[5]); Serial.println(";");man.beginReceiveArray(BUFFER_SIZE, buffer); moo = ++moo % 2; digitalWrite(LED_PIN, moo); } }

      • Arduina

        Merci beaucoup! Nous allons passer la journée à travailler avec ce. Notre objectif est d'avoir deux émetteurs Node1, Node2 envoie des données à un récepteur qui peut identifier le message de chaque nœud de l'émetteur (1 & 2). Avec l'exemple que j'ai fournis, Je pense que nous pouvons voir comment les données nous obtenir à partir d'un nœud et de décider comment gérer la trasnmisiones du récepteur. Je pense que nous seramuy utile. Je vais commencer à tester avec un Arduino pour l'accès au port série; mais ensuite, il faudra essayer d'autres Attiny85, C'est ce que nous utilisons pour notre projet.
        Si nous mettons en œuvre les deux nœuds émetteurs seront partageront le code pour un récepteur.
        Merci encore!

        • With the ultra basic protocol i tried to implement you can manage multiple nodes (it’s the first or second field i don’t remember well) so sure you should be able to do that.
          About the Attiny85, the program is the same so should be easy too
          Good luck !

          • Arduina

            Désolé pour le mess!! Le code de TX que j'ai fourni n'est pas correcte. Ma réponse aurait dû être:

            Salut à nouveau,

            Malheureusement, I haven´t been as successful as I hoped 🙁

            Nous avons créé le Code TX et chargé dans le Attiny85 et le code de RX chargé sur UNO. La bibliothèque de Manchester utilisé est indiqué dans ce tutoriel https://github.com/mchr3k/arduino-libs-manchester.

            La doesn´t de code de TX semblent fonctionner comme il n'y a aucun clignotement sur le LED en Pin 1. Aussi, Je peux voir que le code de RX ne reçoit pas n'importe quoi comme l'ony Serial.print j'obtiens sur le port série est le premier « Inicio Loop ».

            Je vais coller les deux morceaux de code juste au cas où quelqu'un est intéressé à jeter un coup d'oeil et peut-être suggérer des idées alors que nous la recherche de notre part.

            Nous avons réussi à l'aide de la bibliothèque de Manchester pour avoir 1 émetteur envoie des données à 2 récepteurs tous runing sur Attiny. C'était aussi un défi pour nous, et nous sommes fiers d'avoir travailler à la maison avec intérieur et extérieur lumières qui s'allume lorsqu'un mouvement est détecté. Dès que nous aurons cette prochaine étape terminée, je vais partager tous les codes finales!

            Il s'agit de Code de l'émetteur TX chargé sur Attiny85:

            /*Este sketch usa la librería Manchester del siguiente enlace 
             https://github.com/mchr3k/arduino-libs-manchester
             
             Gestionar distintos nodos del transmisor que envían datos a un solo receptor
             
            */
            #include <Manchester.h>
            
            #include <Narcoleptic.h>
            
            
            #define BLINK_MODE true
             
            #define NODE_ID 1 // On 8bits so 0..255
             
            #define MESSAGE_SIZE 6 // Number of bytes to send
            #define SEND_MESSAGE_DELAY 5000 // Delay in ms between each value's extraction
            #define SEND_433_COUNT 4 // How many times the message has to be send
            #define SEND_433_PAUSE 160 // 16 multiple
             
            // Define connectors used for the node
            #define TX_PIN 0
            #define LED_PIN 1
            #define SENSOR_T A2
            
            float dato;
            float datoTotal;
            int   bucle;
            
            float y;            //señal de planta sensor dinamo
            float Temp;        //variable de temperatura desde "sensor"
            
             
            // Array of bytes to will make the message
            // In this node : 2 bytes for voltage, 2 bytes for
            uint8_t msgData[MESSAGE_SIZE] = {0, 0, 0, 0, 0, 0};
             
            //--------------------------------------------------------------------------------------------------
            // Read current supply voltage
            //--------------------------------------------------------------------------------------------------
             long readVcc() {
               bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
               long result;
               // Read 1.1V reference against Vcc
               #if defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
               #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                ADMUX = _BV(MUX3) | _BV(MUX2);
               #else
                ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  // For ATmega328
               #endif
               delay(2); // Wait for Vref to settle
               ADCSRA |= _BV(ADSC); // Convert
               while (bit_is_set(ADCSRA,ADSC));
               result = ADCL;
               result |= ADCH<<8;
               result = 1126400L / result; // Back-calculate Vcc in mV
               ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
               return result; // Vcc in millivolts
            } 
             
            void setup() {
              pinMode(LED_PIN, OUTPUT);
              if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
              man.setupTransmit(TX_PIN, MAN_1200);
              msgData[0] = NODE_ID;
              // Wait 1s to allow DHT11 to initialize
              Narcoleptic.delay(1000);
            }
             
            void loop() {
              // Read Vcc value
              long currentVcc = readVcc();
              uint16_t uint16_currentVcc = (uint16_t)currentVcc;
              // Save millivolts in two bytes to keep high precision. Will be decoded by the gateway
              uint8_t byteData[2] = {uint16_currentVcc >> 8, uint16_currentVcc & 0xFF};
              msgData[2] = byteData[0];
              msgData[3] = byteData[1];
             
              // Read data from sensor
                 
                    dato = 0;
               datoTotal = 0;
                   bucle = 0;
               while (bucle <=3000){
              
              dato = analogRead (SENSOR_T);
              datoTotal = dato + datoTotal;
            
              delayMicroseconds (10);
              bucle++;
            }
               
                y = (datoTotal / 3000); //sumamos caida de tension en el cable
              
             Temp = (5.12 * y * 100.0)/1024.0;
                 
             
              // Sensor values can be put in a byte value due to the low precision
              msgData[4] = (uint8_t)Temp;
              msgData[5] = (uint8_t)Temp; 
             
              // Send message SEND_433_COUNT times with a delay of SEND_433_PAUSE ms for each
              for (int i=0; i<SEND_433_COUNT; i++) {
                msgData[1] = i;
                if (BLINK_MODE) digitalWrite(LED_PIN, HIGH);
                man.transmitArray(MESSAGE_SIZE, msgData);
                if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
                // Wait between each send
                Narcoleptic.delay(SEND_433_PAUSE);
              }
              // Wait before getting new sensor value
              Narcoleptic.delay(SEND_MESSAGE_DELAY);
            }
            

            Et c'est le code de RX récepteur fonctionnant sur UNO (pour pouvoir accéder à port série):

            
            /*Este sketch usa la librería Manchester del siguiente enlace 
             https://github.com/mchr3k/arduino-libs-manchester
             
             Gestionar distintos nodos del transmisor que envían datos a un solo receptor
            */
            #include <Manchester.h>
            
            
            #define RX_PIN 4
            #define LED_PIN 13
            
            uint8_t moo = 1;
            #define BUFFER_SIZE 6
            uint8_t buffer[BUFFER_SIZE];
            
            void setup() {
            Serial.begin(115200);
            pinMode(LED_PIN, OUTPUT);
            digitalWrite(LED_PIN, moo);
            man.setupReceive(RX_PIN, MAN_1200);
            man.beginReceiveArray(BUFFER_SIZE, buffer);
            }
            
            void loop() {
            Serial.println ("Inicio loop");
            if (man.receiveComplete()) {
            uint8_t receivedSize = 0;
            Serial.print(buffer[0]);Serial.print(";");
            Serial.print(buffer[1]);Serial.print(";");
            float voltage = (buffer[2] << 8 ) | (buffer[3] & 0xff);
            Serial.print(voltage/1000);Serial.print(";");
            Serial.print(buffer[4]);Serial.print(";");
            Serial.print(buffer[5]);
            Serial.println(";");
            
            man.beginReceiveArray(BUFFER_SIZE, buffer);
            moo = ++moo % 2;
            digitalWrite(LED_PIN, moo);
            }
            }
            

            Merci!

          • You changed the value of the default values and i guess that you missed the connection. I see A2 as a value which is not a good value. Only integers are expected.
            Please look at this picture : http://fc04.deviantart.net/fs70/f/2013/038/3/7/attiny_web_by_pighixxx-d5u4aur.png
            I guess that Arduino Pin values are the one to use (10, 11, 12, 13). Not sure about that, do not have an attiny85 …
            Try to load a basic sketch that blinks a led to guess which values are correct

  • Marco

    bonsoir,

    je voudrais savoir si un article a été fait pour la partir réception sur un autre arduino? j’ai cherché mais je n’ai rien trouvé.

    J’espere que l’auteur de l’article pourra m’aider

    J’ai repris excatement sont croquis pour l’emission avec un dht22 et atmega 8Mhz interne

      • Marco

        J avais vu cet article. Par contre moi je cherche le code de réception qui va avec le code d émission de cette article pour un arduino.

        • Non désolé. Le principe est expliqué il manque le code de décomposition/réception que je dois avoir sur mon ordinateur et que je peux t’envoyer si je le trouve

          • Marco

            Bonjour, si ca vous dérange pas je suis bien intéressé par le code si vous arrivez à mettre la Ain desssus. Vous voulez mon mail?

            Merci encore

          • Peut être à adapter mais devrait fonctionner :

            #include

            #define RX_PIN 4

            #define LED_PIN 13

            uint8_t moo = 1;

            #define BUFFER_SIZE 6

            uint8_t buffer[BUFFER_SIZE];

            void setup() {

            Serial.begin(115200);

            pinMode(LED_PIN, OUTPUT);

            digitalWrite(LED_PIN, moo);

            man.setupReceive(RX_PIN, MAN_1200);

            man.beginReceiveArray(BUFFER_SIZE, buffer);

            }

            void loop() {

            if (man.receiveComplete()) {

            uint8_t receivedSize = 0;

            Serial.print(buffer[0]);Serial.print(« ; »);

            Serial.print(buffer[1]);Serial.print(« ; »);

            float voltage = (buffer[2] << 8 ) | (buffer[3] & 0xff);

            Serial.print(voltage/1000);Serial.print(";");

            Serial.print(buffer[4]);Serial.print(";");

            Serial.print(buffer[5]);

            Serial.println(";");

            man.beginReceiveArray(BUFFER_SIZE, buffer);

            moo = ++moo % 2;

            digitalWrite(LED_PIN, moo);

            }

            }

          • Marco

            Merci je test ça.

          • Marco

            bonsoir,

            je viens de tester le code de reception (j’ai pas pu avant lol)

            voila ce que je recois:

            1;1;4.77;2;1;

            1;2;4.77;2;1;

            1;3;4.77;2;1;

            1;0;4.77;2;1;

            1;1;4.77;2;1;

            1;2;4.77;2;1;

            1;3;4.77;2;1;

            1;0;4.79;2;1;

            1;2;4.79;2;1;

            Avez vous une idée d’ou ça peut venir

            merci

          • C’est dans les commentaires de l’émetteur 🙂
            – ID du node
            – n° de la trame de 0 à SEND_433_COUNT (4 par défaut). Je n’ai pas mis de gestion de ACK donc la trame est émise plusieurs fois pour que ca passe. A charge du Raspberry de faire le tri
            – Voltage d’alimentation de m’émetteur
            – Humidité du DHT11 (connecté sur le pin 2 par défaut)
            – Température du DHT11 (connecté sur le pin 2 par défaut)

            Vu tes dernières valeurs il va falloir revoir la connexion ou les paramètres

          • Marco

            c’est bon j’avais pas changé le dht11 en dht22

            la je recois:

            1.10v – 58% – 26*C

            est ce que c’est normal que je ne vois que 1.10v alors qu’il est branché en usb.

            autre question apres je vous laisse tranquille.
            lorsque je branche l’arduino avec juste l’alimenttion externe en 9v je n’ai aucune donnée sur le moniteur serie du recepteur. Mais si je le branche en usb ça fonctionne.

            Un parametre a modifier?

            bonne soirée

          • Non c’est pas normal surtout que dans les teames précédantes tu avais bien 4.7v. Un autre paramètre a du etre changé

          • Marco

            normalement le voltage que je dois trouver c’est combien?
            là je l’alimente avec alim externe de 9v alors
            au moment de la premiere mesure j’etais avec mon usb (donc bonne valeur mesurer)
            ensuite j’ai modifier le dht11 en dht22 et du coup j’etais a 1.10v

            le reste des parametre est identique a ton code

          • Utilise la meme alimentation via ton hub. Si tu mets du 9v direct sur l’arduino alors qu’il attend du 3.3v max normal que ca ne fonctinne pas 😉

          • Marco

            bonsoir,

            ca y est, tout fonctionne, par contre j’ai toujours les 1.10v.

            Dit moi sur cette partie la de ton prog, sachant que j’utilise juste la puce atmega, est ce que je dois modifier quelques choses? pour le moment elle tourne avec cette partie la entiere.

            Je vois qu’il y a une ligne en observation ou il y a ecrit; // Read 1.1V reference against Vcc
            est ce du a ca que j’ai mes 1.10v sur mon retour réception?

            en tout cas merci beaucoup, je debute vraiment avec le arduino, j’essaye de comprendre le prog en C, mais c’est pas évident mais cela étant dit c’est super intéressant

            //————————————————————————————————–

            // Read current supply voltage

            //————————————————————————————————–

            long readVcc() {

            bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC

            long result;

            // Read 1.1V reference against Vcc

            #if defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)

            ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84

            #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)

            ADMUX = _BV(MUX3) | _BV(MUX2);

            #else

            ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328

            #endif

            delay(2); // Wait for Vref to settle

            ADCSRA |= _BV(ADSC); // Convert

            while (bit_is_set(ADCSRA,ADSC));

            result = ADCL;

            result |= ADCH<<8;

            result = 1126400L / result; // Back-calculate Vcc in mV

            ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power

            return result; // Vcc in millivolts

            }

          • Le 1.1 est un valeur de reference permettant de calculer ensuite la valeur reelle de l’alimentation. Tu alimentes de combien ?

          • Marco

            Bonjour,

            J alimente mon arduino en USB et je suis branché sur le ground et le 5v comme sur ton dernier shema du dessus (sauf que je n ai pas de fil sur sur le tx et rx) et au niveau du programme j ai juste modifier pour qu’ il m affiche les valeurs comme au dessus c est dire:
            Voltage – humidité – température

          • Marco

            c’est bon j’avais pas changé le dht11 en dht22

            la je recois:

            1.10v – 58% – 26*C

            est ce que c’est normal que je ne vois que 1.10v alors qu’il est branché en usb

  • Alexandre SEROT

    Bonjour,

    J’ai tester avec un Arduino UNO, j’ai été obliger de commenter les lignes 28 et 44

    bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
    ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power

    Car PRR n’était pas reconnu.

    Avec ces modifs ça fonctionne nikel.

    Je possède des pro micro (copie chinoise acheter chez Aliexpress possédant un ATmega32u4), j’ai voulu tester et la c’est le drame… après le téléversement, l’Arduino n’est plus reconnu par Windows et m’indique que le périphérique a été arrêté car il comporte des problèmes (code 43).

    La solution trouver (dans le cas ou ca arriverait à d’autres):

    – Faire un reset sur l’arduino (rst + gnd)
    – Il va de nouveau être detecter par windows pendant un cour instant, ceci permet voir le port COM sur lequel il est detecter.
    – Il va de nouveau passer en erreur
    – Lancer le téléversement d’un sketch basique (blink par exemple)
    – Refaire un reset
    – Le téléversement abouti, c’est gagner il est de nouveau opérationnel.

    Le truc (que je ne sais expliquer), c’est que lors du reset, il est détecter correctement par Windows pendant un court temps (10secondes a peine), c’est pour cela qu’il faut lancer le téléversement un peu en avance du 2eme reset, le téléversement commençant par vérifier le code.

    Ma question est pourquoi mon pro micro passe dans cette état?

    J’ai beau relire le code, je ne comprend pas ce qui le met dans cette état, je ne trouve rien de spécifique a l’Atmega328

    Merci d’avance,

    Alex

    • Salut
      Est-ce que ca ne vient pas de la librairie Narcoleptic ? En étant désactivé et en utilisant le « sleep » classique ca ne fonctionne pas mieux ? Je ne vois que ca qui pourrait faire une manipulation de registre et faire « planter » le uc

  • Jean-Michel SORET

    Bonjour,
    Bravo pour la précision de ton tuto qui m’a donné envie de me lancer.
    C’est mes premiers pas avec un Arduino.

    Je n’ai pas encore reçu les condensateurs donc j’ai testé sans oscillateur externe.
    Dans l’IDE Arduino, j’ai les messages d’erreurs joints.
    Est-ce lié au manque d’oscillateur externe???

    Merci de bien vouloir répondre.

    • Bonjour
      Pas de pièces jointes
      Mais oui c’est possible que le sketch ne se charge pas à cause du manque d’oscillateur pour faire tourner l’horloge correctement. Mais il est possible de s’en passer mais dans ce cas il faut adapter la vitesse d’upload

  • Jean-Michel SORET

    Bonjour,

    J’ai rajouté l’oscillateur et les condensateurs (20 nF et pas 20 µF) mais j’ai l’erreur ci-dessous au moment de graver le bootloader:

    Arduino : 1.6.7 (Windows 10), Carte : « (PiHomeConnect) ATmega328 – 3.3V – 8 MHz internal clock »

    java.io.IOException: Cannot run program « {path}/bin/avrdude »: CreateProcess error=2, Le fichier spécifié est introuvable

    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)

    at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:26)

    at cc.arduino.packages.Uploader.executeUploadCommand(Uploader.java:123)

    at cc.arduino.packages.uploaders.SerialUploader.burnBootloader(SerialUploader.java:359)

    at processing.app.Editor.lambda$handleBurnBootloader$42(Editor.java:2754)

    at java.lang.Thread.run(Thread.java:745)

    Caused by: java.io.IOException: CreateProcess error=2, Le fichier spécifié est introuvable

    at java.lang.ProcessImpl.create(Native Method)

    at java.lang.ProcessImpl.(ProcessImpl.java:386)

    at java.lang.ProcessImpl.start(ProcessImpl.java:137)

    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)

    … 5 more

    Si tu as une piste…

    Merci d’avance

    • Comme le dit la log le programme avrdude n’est pas dans le path. Si tu l’as bien installé il faut régler la variable path

      • Danston Sac

        bonjour, je suis sous mac osx et je n’arrive pas à grave le bootloader j’ai Cannot run program « {path}/bin/avrdude »: error=2, No such file or directory.

        j’ai donc le même probleme, mais ne comprend pas comment régler la variable path merci

        • Ca se regle dans l’interface de l’ide de memoire

          • Danston Sac

            alors j’ai fait les modifs du path mais maintenant j’ai une autre erreur,
            avrdude: stk500_recv(): programmer is not responding
            avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

            est-ce une erreur dans mon cablage ? j’ai pourtant fait attention. J’ai un doute sur le sens de polarité des 2 condensateurs il sont dans le même sens !!.

          • Je pense oui une erreur dans le branchement. J’ai aussi souvenir de devoir maintenir le reset actif pour que l’atmega soit détecter. Ca dépendait des puces

  • Jean-Michel SORET

    Bonjour,

    Je suis sous Windows 10. J’ai modifié le path et redémarré mon PC mais j’ai toujours la même erreur de path.
    Je ne comprends pas ce qui se passe.
    J’ai la dernière version de l’IDE Arduino (1.7).

    Si tu as une idée…

    Merci

  • Julien Geneste

    Yop,

    J’ai vu sur la photo qu’une fois le projet fini tu n’as pas de quartz sur ton Atmega. L’horloge est interne ou sa dépend de la version du microcontroleur ?

    Merci !

    • Salut,
      Comme je l’explique j’utilise l’oscillateur interne à 8Mhz. Moins « rapide » mais surtout consomme moins

  • sidwin9

    Bonjour,

    Il me manque des précisions sur ton montage, surtout en ce qui concerne les alimentations. Apparemment, tu alimentes le tous avec 2 piles de 1.5volts pour un fonctionnement du Atmega à 3,3Volts mais que fais tu pour l’alimentation du TX 433 Mhz qui fonctionne en 5Volts.

    Merci de m’éclaircir un peu tous cela.

    • Bonsoir. Je l’ai connecté directement. Le module fonctionne dans un range 3.3v-12v. Par contre en 3.3v la.portée est limitée

      • sidwin9

        Merci pour ta réponse rapide.
        Les 2 piles de 1.5 volts suffisent donc pour l’ensemble du montage. Tu tiens combien de temps sans changer les piles ?

        • J’en parle en début d’article avec un graphique qui montre l’évolution de la charge des 2 piles. Dans ce tutoriel j’ai un peu abusé sur la fréquence pour illustrer le fonctionnement. Par contre je n’ai pas mesuré la décharge « naturelle » de la pile

  • Ken Addams

    Hello,
    C’est super tous ces montages, mais dans une vraie installation domestique, vous installez vos breadboards avec captuers de températures et résistances dans votre salon ? En fait j’adhère complètement au principe, mais je n’ai pas encore trouvé d’implémentation « non geek » c’est à dire embarquant un boitier discret pour intégration dans un intérieur harmonieux. Des idées svp ?

    • Bonjour. Pour du non geek sur ce site il y a un projet expliqué avec des boîtiers qui cachent tout ça
      Sinon pour cet article ça explique comment fabriquer soi même. L’étape suivante c’est le boîtier imprimé en 3d. A chacun de voir pour l’esthétique