transmeteur 433 Mhz avec code manchester

Bonjour,

Je suis sur un projet de station météo avec un capteur extérieur constitué d’un Arduino Nano avec montage émetteur 433 Mhz et DHT22.
Mon montage fonctionne très bien mais mon problème est la transmission des données en code manchester.
je transmet la température et l’humidité mais simplement sur 2 digits (Exemple : 20), je voudrais transmettre sur 3 ou 4 digits avec pour la température les valeurs négatives (Exemple : -10.50 ou -10.5).

Voici mon code :

#include <Narcoleptic.h>
#include <DHT.h>
#include <Manchester.h>
 
#define BLINK_MODE true
 
#define NODE_ID 1 // Sur 8bits donc 0..255
 
#define MESSAGE_SIZE 10// Nombre d'octets à envoyer
#define SEND_MESSAGE_DELAY 5000 // Retard en ms entre la lecture de chaque valeur
#define SEND_433_COUNT 4 // Combien de fois le message doit être envoyée
#define SEND_433_PAUSE 160 // 16 multiple
 
// Définir les connecteurs utilisés
#define TX_PIN 5
#define LED_PIN 13
#define DHTPIN 2       // Attribut le pin 8 au DHT
#define DHTTYPE DHT22  // Type de DTH
 
DHT dht(DHTPIN, DHTTYPE);

double humDHT_Ext;     // Variable Humidité Extérieure
double tempDHT_Ext;    // Variable Température Extérieure
// Tableau d'octets du message
// 2 octets pour la tension , 2 octets pour
uint8_t msgData[MESSAGE_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

void setup() {
  Serial.begin(9600); // Indique le taux de transfert au Moniteur Serial : 9600 Bauds
  pinMode(LED_PIN, OUTPUT);
  if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
  man.setupTransmit(TX_PIN, MAN_1200);
  msgData[0] = NODE_ID;
  // Attendre 1s pour initialiser DHT22
  Narcoleptic.delay(2000);
}
 
void loop() {
  // Lire les données de capteur DHT11
  //int chk = DHT.read11(DHT11_PIN);
  // Les valeurs DHT11 peuvent être mis dans une valeur d'octet en raison de la faible précision
  tempDHT_Ext = dht.readTemperature();
  humDHT_Ext = dht.readHumidity();
  msgData[2] = (uint8_t)humDHT_Ext;
  Serial.print("Hum : ");
  Serial.println(humDHT_Ext);
  msgData[3] = (uint8_t)tempDHT_Ext;
  Serial.print("Temp : ");
  Serial.println(tempDHT_Ext);
 
  // Envoyer un message SEND_433_COUNT fois avec un retard de ms SEND_433_PAUSE pour chacun
  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);
    // Attendre entre chaque envoi
    Narcoleptic.delay(SEND_433_PAUSE);
  }
  // Attendez avant d'obtenir une nouvelle valeur de capteur
  Narcoleptic.delay(SEND_MESSAGE_DELAY);
}

Si quelqu’un peu me venir en aide j’en serais ravi.
Merci.

Pas d'idée... ????

Bon apparemment on ne peux envoyer que des entiers avec le code manchester, du coup je multiplie par 100 avant l’émission et je divise par 100 à la réception. Mais comment faire pour transmettre les températures négatives ?

Bonjour,

Même pour une température négative, ça reste un valeur hexadécimale qu'il faudra décoder à la réception.

exemple sur 8 bit : 1°C = 0x01 -1°C=0x81 bit 7 pour le signe.

j'espère avoir bien expliqué.

Yan_duino

Bonjour,

Tu peux bien sur transmettre des valeurs flottantes ou autres valeurs binaires.
Le plus simple est de définir une structure message et de transmettre cette structure.

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

#define BLINK_MODE true

#define NODE_ID 1 // Sur 8bits donc 0..255
#define SEND_MESSAGE_DELAY 5000 // Retard en ms entre la lecture de chaque valeur
#define SEND_433_COUNT 4 // Combien de fois le message doit être envoyée
#define SEND_433_PAUSE 160 // 16 multiple

// Définir les connecteurs utilisés
#define TX_PIN 5
#define LED_PIN 13
#define DHTPIN 2       // Attribut le pin 8 au DHT
#define DHTTYPE DHT22  // Type de DTH

DHT dht(DHTPIN, DHTTYPE);

double humDHT_Ext;     // Variable Humidité Extérieure
double tempDHT_Ext;    // Variable Température Extérieure
// Tableau d'octets du message

// message à envoyer
struct SMessage
{
  int cpt;
  double hum;
  double temp;
} msgData;

void setup() {
  Serial.begin(9600); // Indique le taux de transfert au Moniteur Serial : 9600 Bauds
  pinMode(LED_PIN, OUTPUT);
  if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
  man.setupTransmit(TX_PIN, MAN_1200);
  // Attendre 1s pour initialiser DHT22
  Narcoleptic.delay(2000);
}

void loop() {
  // Lire les données de capteur DHT11
  //int chk = DHT.read11(DHT11_PIN);
  // Les valeurs DHT11 peuvent être mis dans une valeur d'octet en raison de la faible précision
  tempDHT_Ext = dht.readTemperature();
  humDHT_Ext = dht.readHumidity();
  Serial.print("Hum : ");
  Serial.println(humDHT_Ext);
  Serial.print("Temp : ");
  Serial.println(tempDHT_Ext);
  
  // range les mesures dans le buffer
  msgData.hum=humDHT_Ext;
  msgData.temp=tempDHT_Ext;

  // Envoyer un message SEND_433_COUNT fois avec un retard de ms SEND_433_PAUSE pour chacun
  for (int i = 0; i < SEND_433_COUNT; i++) {
    msgData.cpt = i;
    if (BLINK_MODE) digitalWrite(LED_PIN, HIGH);
    man.transmitArray(sizeof msgData, (uint8_t *)&msgData);
    if (BLINK_MODE) digitalWrite(LED_PIN, LOW);
    // Attendre entre chaque envoi
    Narcoleptic.delay(SEND_433_PAUSE);
  }
  // Attendez avant d'obtenir une nouvelle valeur de capteur
  Narcoleptic.delay(SEND_MESSAGE_DELAY);
}

Il faut faire la même modif en réception.

Ok merci beaucoup pour les infos.

Et pour le réception, j'effectue la séparation de la donnée temp et hum comment ?

Merci pour votre aide.

Tu déclare la même structure en réception et su en extrait la température et l’humidité Si tu n' arrives pas mets ton programme de reception

Je veux bien, merci.

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <DHT.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <DS3231.h>
#include <Manchester.h>

// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS     10
#define TFT_RST    9  // you can also connect this to the Arduino reset
                      // in which case, set this #define pin to 0!
#define TFT_DC     8

// Option 1 (recommended): must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

// Option 2: use any pins but a little slower!
#define TFT_SCLK 13   // set these to be whatever pins you like!
#define TFT_MOSI 11   // set these to be whatever pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

Adafruit_BMP085 bmp180;
DS3231 clock;
RTCDateTime dt;        // dt variable de temps

#define lum A1         // Définir l'entrée A1 à “lum”
#define DHTPIN 6       // Attribut le pin 6 au DHT
#define DHTTYPE DHT22  // Type de DTH
#define RX_PIN 12
#define LED_PIN 7

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

double a = 17.271;
double b = 237.7;

int Port1;             // Variable pour mémoriser la valeur l'entrée A1
double Lumiere;        // Variable qui reçoit la valeur de tension convertie en volt
double PressionA;      // Variable Pression Absolue
double PressionR;      // Variable Pression Relative
double humDHT;         // Variable Humidité
double tempDHT;        // Variable Température
double humDHT_Ext;     // Variable Humidité Extérieure
double tempDHT_Ext;    // Variable Température Extérieure

const int  buttonPin = 2;     // Crée une variable pour le pin utilisé avec le bouton poussoir
int buttonPushCounter = 0;    // Variable pour le comptage du nombre d'appuis sur le bouton poussoir
int buttonState = 0;          // Variable pour l'état actuel du bouton poussoir
int lastButtonState = 0;      // Variable pour l'état précédent du bouton poussoir
int CounterDisplay = 0;       // Variable pour comptage de l'affichage
int ResetDisplay = 1;

DHT dht(DHTPIN, DHTTYPE); 

void  setup()
{
  Serial.begin(9600); // Indique le taux de transfert au Moniteur Serial : 9600 Bauds

  // Use this initializer if you're using a 1.8" TFT
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);
  tft.setRotation(1);
    
  pinMode(buttonPin, INPUT); // Met le pin 2 en entrée
  
  dht.begin(); // Activation du DHT22

  // En cas d'erreur de lecture du BMP180
  if (!bmp180.begin()) {
  Serial.println("Erreur de lecture du senseur BMP180 !");
  while (1) {}
  }

  // En cas d'erreur de lecture du DHT22
  if (isnan(humDHT) || isnan(tempDHT)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Initialisation du DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

  pinMode(LED_PIN, OUTPUT);  
  digitalWrite(LED_PIN, moo);
  man.setupReceive(RX_PIN, MAN_1200);
  man.beginReceiveArray(BUFFER_SIZE, buffer);
  
  // Réglage du temps pour la compilation du code
  clock.setDateTime(__DATE__, __TIME__);
  // Réglage initial manuel du temps (YYYY, MM, DD, HH, II, SS)
  // clock.setDateTime(2014, 4, 13, 19, 21, 00);
  delay(2000);
}

void  loop()
{  
   dt = clock.getDateTime();
   
   // On lit l'état actuel du bouton poussoir et on mémorise dans la variable
   buttonState = digitalRead(buttonPin);
   
   // On compare l'état actuel du bouton poussoir à l'état précédent mémorisé
  if (buttonState != lastButtonState)
    {
      // Si l'état du bouton poussoir a changé et est HAUT, on incrémente la variable de comptage
      if (buttonState == HIGH)
        {
          // Si l'état actuel du bouton est HAUT
          // il est passé de BAS  à HAUT
          buttonPushCounter++;
        }
      // Mémorise l'état courant du bouton poussoir pour les prochains passages dans la boucle loop
      lastButtonState = buttonState;
    }

   // Rx des données de la sonde
   if (man.receiveComplete())
    {
      uint8_t receivedSize = 0;
      //Utiliser les données du buffer maintenant avant de commencer à recevoir de nouveau le buffer
      man.beginReceiveArray(BUFFER_SIZE, buffer);
      humDHT_Ext = buffer[2];
      tempDHT_Ext = buffer[3];
      moo = ++moo % 2;
      digitalWrite(LED_PIN, moo);
    }
    
   tempDHT = dht.readTemperature();
   humDHT = dht.readHumidity();
   PressionA = bmp180.readPressure();
   PressionA = round(PressionA/10);
   PressionA = PressionA / 10;
   PressionR = PressionA + (48/8.3);  // Calcul de la pression relative en fct de l'atitude
   Port1 = analogRead (lum);          // Lire l'entrée A1 et mémorise dans la variable "Port1"
   Lumiere = map(Port1,0,1024,0,100); // Mapper la valeur de 0 à 1024 en 0 à 100%
   double gamma = ((a*tempDHT)/(b+tempDHT)) + log (humDHT/100);
   double dewpoint = (b * gamma) / (a - gamma); // Calcul du point de rosée
   // Calcul de l'Humidex
   double e = 5417.7530*((1/273.16)-(1/(273.16 + dewpoint)));
   double humidex = tempDHT + 0.5555 * ( 6.11 *  exp (e) - 10);

Je pense que ça devrait fonctionner comme ça (il manque la fin de ton programme)

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <DHT.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <DS3231.h>
#include <Manchester.h>

// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS     10
#define TFT_RST    9  // you can also connect this to the Arduino reset
                      // in which case, set this #define pin to 0!
#define TFT_DC     8

// Option 1 (recommended): must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

// Option 2: use any pins but a little slower!
#define TFT_SCLK 13   // set these to be whatever pins you like!
#define TFT_MOSI 11   // set these to be whatever pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

Adafruit_BMP085 bmp180;
DS3231 clock;
RTCDateTime dt;        // dt variable de temps

#define lum A1         // Définir l'entrée A1 à "lum"
#define DHTPIN 6       // Attribut le pin 6 au DHT
#define DHTTYPE DHT22  // Type de DTH
#define RX_PIN 12
#define LED_PIN 7

uint8_t moo = 1;

double a = 17.271;
double b = 237.7;

int Port1;             // Variable pour mémoriser la valeur l'entrée A1
double Lumiere;        // Variable qui reçoit la valeur de tension convertie en volt
double PressionA;      // Variable Pression Absolue
double PressionR;      // Variable Pression Relative
double humDHT;         // Variable Humidité
double tempDHT;        // Variable Température
double humDHT_Ext;     // Variable Humidité Extérieure
double tempDHT_Ext;    // Variable Température Extérieure

const int  buttonPin = 2;     // Crée une variable pour le pin utilisé avec le bouton poussoir
int buttonPushCounter = 0;    // Variable pour le comptage du nombre d'appuis sur le bouton poussoir
int buttonState = 0;          // Variable pour l'état actuel du bouton poussoir
int lastButtonState = 0;      // Variable pour l'état précédent du bouton poussoir
int CounterDisplay = 0;       // Variable pour comptage de l'affichage
int ResetDisplay = 1;

DHT dht(DHTPIN, DHTTYPE); 

// message à recevoir
struct SMessage
{
  int cpt;
  double hum;
  double temp;
} msgData;

void  setup()
{
  Serial.begin(9600); // Indique le taux de transfert au Moniteur Serial : 9600 Bauds

  // Use this initializer if you're using a 1.8" TFT
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);
  tft.setRotation(1);
    
  pinMode(buttonPin, INPUT); // Met le pin 2 en entrée
  
  dht.begin(); // Activation du DHT22

  // En cas d'erreur de lecture du BMP180
  if (!bmp180.begin()) {
  Serial.println("Erreur de lecture du senseur BMP180 !");
  while (1) {}
  }

  // En cas d'erreur de lecture du DHT22
  if (isnan(humDHT) || isnan(tempDHT)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Initialisation du DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

  pinMode(LED_PIN, OUTPUT);  
  digitalWrite(LED_PIN, moo);
  man.setupReceive(RX_PIN, MAN_1200);
  man.beginReceiveArray(sizeof msgData, (uint8_t *)&msgData);
  
  // Réglage du temps pour la compilation du code
  clock.setDateTime(__DATE__, __TIME__);
  // Réglage initial manuel du temps (YYYY, MM, DD, HH, II, SS)
  // clock.setDateTime(2014, 4, 13, 19, 21, 00);
  delay(2000);
}

void  loop()
{  
   dt = clock.getDateTime();
   
   // On lit l'état actuel du bouton poussoir et on mémorise dans la variable
   buttonState = digitalRead(buttonPin);
   
   // On compare l'état actuel du bouton poussoir à l'état précédent mémorisé
  if (buttonState != lastButtonState)
    {
      // Si l'état du bouton poussoir a changé et est HAUT, on incrémente la variable de comptage
      if (buttonState == HIGH)
        {
          // Si l'état actuel du bouton est HAUT
          // il est passé de BAS  à HAUT
          buttonPushCounter++;
        }
      // Mémorise l'état courant du bouton poussoir pour les prochains passages dans la boucle loop
      lastButtonState = buttonState;
    }

   // Rx des données de la sonde
   if (man.receiveComplete())
    {
      uint8_t receivedSize = 0;
      //Utiliser les données du buffer maintenant avant de commencer à recevoir de nouveau le buffer
      man.beginReceiveArray(sizeof msgData, (uint8_t *)&msgData);
      humDHT_Ext = msgData.hum;
      tempDHT_Ext = msgData.temp;
      moo = ++moo % 2;
      digitalWrite(LED_PIN, moo);
    }
    
   tempDHT = dht.readTemperature();
   humDHT = dht.readHumidity();
   PressionA = bmp180.readPressure();
   PressionA = round(PressionA/10);
   PressionA = PressionA / 10;
   PressionR = PressionA + (48/8.3);  // Calcul de la pression relative en fct de l'atitude
   Port1 = analogRead (lum);          // Lire l'entrée A1 et mémorise dans la variable "Port1"
   Lumiere = map(Port1,0,1024,0,100); // Mapper la valeur de 0 à 1024 en 0 à 100%
   double gamma = ((a*tempDHT)/(b+tempDHT)) + log (humDHT/100);
   double dewpoint = (b * gamma) / (a - gamma); // Calcul du point de rosée
   // Calcul de l'Humidex
   double e = 5417.7530*((1/273.16)-(1/(273.16 + dewpoint)));
   double humidex = tempDHT + 0.5555 * ( 6.11 *  exp (e) - 10);

Impect, merci !!!

J'y étais presque, manquait juste une ligne. Seul problème, la portée du signal c'est fortement réduite (20cm) alors que j'utilise une antenne de 17,3 cm que j'ai mis en spirale. J'avais fait des tests avec d'autres librairies de transmission comme VirtualWire avec la quelle j'avais plus d'une dizaine de mètres de portée mais une intégrité des données moins sûre. As tu une solution pour améliorer la portée ?

J'avais utilisé virtuawire et je n'ai pas eu de problème d'intégrité. Par contre j'avais aussi des problème de portée. Je pense que la portée dépend surtout des emetteur/recepteur

J’alimente mon émetteur avec du 12v et j’obtiens un bonne portée …

Ok, pour l'instant pour les tests j'utilise le 5V de mon arduino nano pour alimenter mon Ex 433 Mhz.

sidwin9: Ok, pour l'instant pour les tests j'utilise le 5V de mon arduino nano pour alimenter mon Ex 433 Mhz.

bonsoir si tu utilise des modules 434 "cheaps" genre çà il faut toujours "adapter/regler" le noyau du recepteur une fois le projet fini. c'est courant sans reglage d'obtenir des portées "ridicules"

C'est bien ces modules que j'utilise. Peux tu me dire comment effectuer les réglages.

Merci.

sidwin9: C'est bien ces modules que j'utilise. Peux tu me dire comment effectuer les réglages.

Merci.

topo demain après-midi :grin:

bonjour Il n'y a pas grand chose à faire du coté des TX mais du coté RX , la solution la plus simple de réglage sans gros moyen "de mesure" est : - mettre un TX en émission soutenue avec un motif simple (un motif identique réémis continuellement avec une petite pause)

  • "Ecouter/voir" * la reception des trames avec en s'eloignant du TX en ajustant la "vis" sur le recepteur.

schema d'une petite "sonde"

video sur un recepteur 434 http://www.cjoint.com/doc/16_04/FDrjPrCvDeP_casqled.mp4

Merci pour l'info et le schéma. Je te tiens au courant du résultat (si cela t'intéresse biensur.)

sidwin9: Merci pour l'info et le schéma. Je te tiens au courant du résultat (si cela t'intéresse biensur.)

un retour est toujours interessant.

A noter un point particulier que j'avais oublié de préciser : L'ideal est d'utiliser des "tournevis HF" ça permet de faire du reglage en continu, mais dans la mesure où ce n'est pas ce qu'il y a de plus courant , il est possible d'utiliser du tournevis métallique, mais en prenant soin de faire des "retouches d'amplitude faible" et en verifiant l'effet en eloignant largement le tournevis metal.

sidwin9: Impect, merci !!!

J'y étais presque, manquait juste une ligne. Seul problème, la portée du signal c'est fortement réduite (20cm) alors que j'utilise une antenne de 17,3 cm que j'ai mis en spirale. J'avais fait des tests avec d'autres librairies de transmission comme VirtualWire avec la quelle j'avais plus d'une dizaine de mètres de portée mais une intégrité des données moins sûre. As tu une solution pour améliorer la portée ?

Bonjour , ton antenne est bien accordée (1/4 d'onde ) essaye de ne pas la spiraler et faire un montage avec un fil blindé et l’éloigner de la platine pour voir si c'est mieux ......