Utilisation emetteur/récepteur 433mhz

Bonjour
j'utilise un arduino uno
j'ai créé un programme qui récupère la temperature avec ds18b20 et la transmet avec un rh433mhz avec une antenne 17.3 cm torsadé (fabrication maison)
les modules sont sur une breadboard
j'ai positionné une led pour vérifier l’émission
j'ai téléversé le programme sur un atmega328p pour utilisation sans connexion à l'arduino
je récupère les infos sur mon raspberry avec un récepteur 433mhz avec une antenne 17.3 cm torsadé (fabrication maison) pour les mettre dans une bd phpmyadmin
tout fonctionne correctement lorsque le récepteur et l’émetteur se trouve à proximité (environ 50cm)
si je les éloigne, environ 5m, je ne reçois plus rien ou seulement de façon aléatoire
comment améliorer cette liaison ?
pouvez vous m'aider ?
cordialement
Pierre

essayez une antenne de 12cm. il y a souvent des bobines sur la carte qui vont ajouter 5cm à votre antenne mais je pense que vous aurez de meilleurs résultats avec une antenne d'environ 30cm

vous utilisez une libraire? virtualWire? quelle vitesse de transmission?

merci pour la réponse
avec l’émetteur j’utilise la librairie RadioHead

    #include <OneWire.h> // Inclusion de la librairie OneWire
    #include <RH_ASK.h>
    #include <SPI.h> // Not actually used but needed to compile
     
    #define DS18B20 0x28     // Adresse 1-Wire du DS18B20
    #define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire

    OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds

    // default settings automatically  Speed is 2000bps; RX pin = 11; TX pin = 12; Ptt pin =  10; PTT inverted = false.
    // RH_ASK driver(1000,4)//change speed and RX pin
    
    RH_ASK driver(2000,11,12);

    String message;
    
    String lieu = String("Limoges_Bureau");
    String code = String("1001");
    
    char adr_module[25];

// setup()
    void setup() {
      
      Serial.begin(9600); // Initialisation du port série

      if (!driver.init())
         Serial.println("init failed");
         
    }
     
// loop()
    void loop() {
      float temp;
      float celsius;

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

        Serial.print("Temperature : ");
        Serial.print(celsius);
        Serial.write(176); // caractère °
        Serial.write('C');
        Serial.println();

        message = "";
        message += " TEMP";
        message += " ";  
        message += lieu;
        message += " ";   
        message += code;
        message += " "; 
        message += adr_module;
        message += " ";    
        message += celsius;
        
    Serial.print(message);
    Serial.println();

//        char charBuf[50] = { '\0' };
        char charBuf[50];
        message.toCharArray(charBuf, 50); 
        
//        Serial.print(charBuf);
//        Serial.println();

// ***********************************************************************
        Serial.print("TX ... "); // On signale le début de l'envoi 

        // On envoie le message
        driver.send((uint8_t *)charBuf, strlen(charBuf));
    
        // On attend la fin de l'envoi 
        driver.waitPacketSent();

        Serial.println("Done !"); // On signal la fin de l'envoi 
        Serial.println();
        
        delay(5000);

      }

    }

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

      // just big enough for 8 hex plus spacing plus nul character
      
      // copy address to buffer in human readable format
      for(int cnt=0;cnt<sizeof(addr);cnt++)
        {
           sprintf(&adr_module[cnt*2], "%02x ", addr[cnt]);
        }
      // remove last space
      adr_module[strlen(adr_module) - 1] = '\0';
      
       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;
    }

avec le récepteur j’utilise la librairie Virtualwire

    #include <OneWire.h> // Inclusion de la librairie OneWire
    #include <RH_ASK.h>
    #include <SPI.h> // Not actually used but needed to compile
     
    #define DS18B20 0x28     // Adresse 1-Wire du DS18B20
    #define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire

    OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds

    // default settings automatically  Speed is 2000bps; RX pin = 11; TX pin = 12; Ptt pin =  10; PTT inverted = false.
    // RH_ASK driver(1000,4)//change speed and RX pin
    
    RH_ASK driver(2000,11,12);

    String message;
    
    String lieu = String("Limoges_Bureau");
    String code = String("1001");
    
    char adr_module[25];

// setup()
    void setup() {
      
      Serial.begin(9600); // Initialisation du port série

      if (!driver.init())
         Serial.println("init failed");
         
    }
     
// loop()
    void loop() {
      float temp;
      float celsius;

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

        Serial.print("Temperature : ");
        Serial.print(celsius);
        Serial.write(176); // caractère °
        Serial.write('C');
        Serial.println();

        message = "";
        message += " TEMP";
        message += " ";  
        message += lieu;
        message += " ";   
        message += code;
        message += " "; 
        message += adr_module;
        message += " ";    
        message += celsius;
        
    Serial.print(message);
    Serial.println();

//        char charBuf[50] = { '\0' };
        char charBuf[50];
        message.toCharArray(charBuf, 50); 
        
//        Serial.print(charBuf);
//        Serial.println();

// ***********************************************************************
        Serial.print("TX ... "); // On signale le début de l'envoi 

        // On envoie le message
        driver.send((uint8_t *)charBuf, strlen(charBuf));
    
        // On attend la fin de l'envoi 
        driver.waitPacketSent();

        Serial.println("Done !"); // On signal la fin de l'envoi 
        Serial.println();
        
        delay(5000);

      }

    }

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

      // just big enough for 8 hex plus spacing plus nul character
      
      // copy address to buffer in human readable format
      for(int cnt=0;cnt<sizeof(addr);cnt++)
        {
           sprintf(&adr_module[cnt*2], "%02x ", addr[cnt]);
        }
      // remove last space
      adr_module[strlen(adr_module) - 1] = '\0';
      
       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;
    }

que puis je faire pour améliorer ?
cordialement
Pierre

pour la stabilité je dirais testez avec une plus petite et plus grande antenne et vous pouvez aussi tester à une vitesse de transmission plus faible

c'est alimenté en 12V? la puissance émise dépend de l'alimentation sur de nombreux modules

et comme le spectre de 433mhz est super encombré - plus vous êtes loin de votre émetteur plus le récepteur peut avoir des interférence provenant du reste du monde...

En France la Puissance Apparente Rayonnée admises diffèrent suivant les bandes et sous-bandes et pour la bande 433 MHz elle est limitée à 10 mW

Sinon votre code ne devrait pas utiliser la classe String, je crois que cela vous a été mentionné avant.

bonjour
les modules couples E/R 433 "cheap" sont généralement des "plaies"
pour ameliorer "le rendement" il faut déjà :

  • ne pas travailler avec la même breadbord/alim (aucun couplage)
  • mettre et adapter les antennes sur E/R
  • utiliser une alim serieuse pour l’émetteur
  • ajuster le noyau sur le rrecepteur en s’éloignant de l'emetteur

Merci pour les conseils
l’émetteur et le récepteur sont sur des breadboard différents car j’utilise en autonome l’emetteur avec un atmega328p
sur l’emetteur en effet j’utilise une alimentation faite de 3 piles de 1.5v
comment mettre une alimentation plus élevé, quel type
pour le récepteur le breadboard est connecté directement sur le raspberry en 5v
comment mettre en place une alimentation différente
je ne comprend pas votre phrase (Sinon votre code ne devrait pas utiliser la classe String, je crois que cela vous a été mentionné avant.)
cordialement
pierre

j'ai oublié
vous dites (les modules couples E/R 433 "cheap" sont généralement des "plaies" )
quelle solution de remplacement
cordialement
pierre

les bobines embarquées sur les E/R 433 sont dimensionnées pour des communication courte distance

j'ai eu de meilleurs résultats sur de bonnes distances avec des RF24L01 2.4GHz Radio/Wireless Transceivers

bonsoir
merci pour les réponses
j'ai une idée le wifi avec esp8266
peut on faire un réseau ad hoc entre le raspberry et les différent breadboard sur lesquelq se trouvent les atmega328p et le rf433mhz remplacé par le esp8266
cordialement
pierre

oui bien sûr c'est une option - l'idéal alors est que votre esp8266 soit connecté à votre réseau wifi. sinon sa capacité à créer un réseau étendu est assez faible du fait de sa faible puissance.

sultan87:
bonsoir
merci pour les réponses
j'ai une idée le wifi avec esp8266
peut on faire un réseau ad hoc entre le raspberry et les différent breadboard sur lesquelq se trouvent les atmega328p et le rf433mhz remplacé par le esp8266
cordialement
pierre

bonjour
Tu peux utiliser les esp8266 en mode AP sans problemes et/ou regarder du coté des esp8266 en mode mesh
quelle distance max et quel environnement ?

Dans mon jardin/maison j'ai automatisé un certain nombres de fonctions avec des ESP8266 connectés à mon réseau wifi de la maison et exportant vers internet des données sur un site web externe qui me permet de commander des fonctions depuis n'importe où. c'est alimenté par batteries LiPo qui sont rechargées par du solaire.

Les ESP (série 7 pour certains avec une antenne quand ils sont vraiment au fond du jardin, sinon des 01 ou des 12E suivant le nombres GPIO dont j'ai besoin) sont pratiques car directement utilisables maintenant sans arduino du tout.

donc du moment que le réseau de la maison arrive jusqu'à l'ESP tout fonctionne bien.

par contre mettre des ESP pour créer un réseau wifi et connecter d'autres ESP dessus c'est assez limité au niveau de la portée et sensible aux interférences. des 07 avec antenne dans ce cas là c'est mieux.

merci pour les réponses
le problème est que la où je veux mettre en place le raspberry et les atmega je n'ai pas internet d'où la question de mettre en place un réseau ad hoc
est ce possible, si oui comment
cordialement
pierre

sultan87:
merci pour les réponses
le problème est que la où je veux mettre en place le raspberry et les atmega je n'ai pas internet d'où la question de mettre en place un réseau ad hoc
est ce possible, si oui comment
cordialement
pierre

bonjour

Il y a 2 solutions :

  • Tout en esp en en configurant un en mode AP (diffusion SSID)
  • installer sur ton RPI un reseau wifi en mettant un routeur wifi

j'utilise la 1ere solution sans probleme sur une distance de 50m+ entre esp (ouverture de barrières automatiques)

bonjour
merci pour vos réponses
je vais commander des esp et faire les tests
je vous tiens au courant
cordialement
pierre

Vous pouvez aussi prendre du NRF (pour la portée et simplicité) et mettre un arduino en central avec un Shield GPRS qui enverra les data via le réseau télécom - des Sims sans engagement avec un certain volume de données ça ne coûte pas un bras