Archives par mot-clé : VirtualWire

Spectre occupé par un module émetteur 433 MHz

433 MHz RX + TX modules (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2015/01/1402 NULL.jpg)Ce matin j’ai eu un peu de temps pour bricoler et la curiosité m’a poussé à regarder la tête qu’avait le signal émis par les petits modules 433 MHz que j’utilise pour le capteur extérieur de ma station météo (http://xv4y NULL.radioclub NULL.asia/2013/02/04/station-meteo-avec-serveur-web-code-source/) par exemple.

Pour mémoire, ces modules à transmission unidirectionnelle sont très bon marché et très simple techniquement (http://www NULL.icstation NULL.com/product_info NULL.php?ref=5&products_id=1402&affiliate_banner_id=1). Ils utilisent un oscillateur qui fonctionne en continue et la modulation est du type “tout ou rien” (OOK, On-Off Keying) un peu comme de la CW. C’est à vous d’apporter l’intelligence nécessaire pour s’assurer de l’intégrité et de l’authenticité des données, ou plutôt à une librairie que vous utiliserez comme la librairie VirtualWire (http://xv4y NULL.radioclub NULL.asia/2013/01/09/librairie-virtualwire-1-10-pour-le-msp430/).

En pratique, j’ai trouvé ces modules pratiques et plutôt fiables. Le débit maximal théorique est autour de 9000 bps, mais pour la majorité des usages 2000bps est suffisant et donnera une meilleure couverture. Je n’ai pas trouvé de gain à descendre plus bas dans la vitesse de transmission, la limite devant être celle de la sensibilité du récepteur. Du moins en partie.

XV4Y - Capture SDR Sharp Signal 433 MHz (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2015/01/burst433MHz NULL.png)Comme vous le voyez sur la capture d’écran de SDR#, le spectre en émission est plutôt laid et occupe environ 50 KHz ! Les réglages d’attaque et de relâchement de la visualisation FFT ont été mis aux extrêmes pour faire ressortir la forme du signal. En réalité, la durée d’un train de données est de l’ordre que quelques milli-secondes. Une telle largeur de spectre gaspillé explique pourquoi le récepteur n’a aucun mal à accrocher l’émetteur alors qu’aucun verrouillage de la fréquence n’est prévu! C’est simple et pas cher, mais franchement pas efficace. Si vous rêviez d’utiliser ces modules avec un amplificateur vous pouvez oublier tout de suite. Au-delà des quelques milliwatts qu’ils sont sensés produire vous aller vous attirer les foudres des autorités de régulation !

Techniquement, une telle largeur de spectre s’explique parce qu’aucune mise en forme de la modulation n’est réalisée. Les transitions émission-réception sont très abruptes et génèrent ce qu’on appelle communément les key-clicks. Résultat : une mauvais efficacité spectrale nuisible au rapport signal/bruit (et donc au DX maximum) car la puissance est inutilement étalée, mais une meilleure fiabilité car même un récepteur mal syntonisé accrochera le signal.

Station météo avec serveur web – code source

Prototype station météo (http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2013/02/100_3440 NULL.jpg)J’ai continué mes travaux autour de ma mini-station météo avec serveur web. J’ai atteint les objectifs de fonctionnalités que je m’étais fixés, même s’il me reste à enrichir de quelques indicateurs les statistiques. Ensuite il me faudra repasser toutes les valeurs en type float car je les avais mises en entier pour gagner de la place mémoire et parce que l’espace d’affichage sur l’écran LCD était limité. Il me faudra aussi faire un peu de gestion de la cohérence des valeurs pour éviter d’afficher 255°C quand mon capteur distant n’a plus de piles (comme actuellement). A propos du capteur distant, il faudra aussi que je travaille sur son code pour gérer la mise en veille afin d’économiser les batteries. Dernier point important, j’attends toujours mes capteurs de pression atmosphérique (ils sont assez chers donc j’ai hésité à les inclure dans les kits) pour pouvoir gérer ce type de mesures. L’architecture générale étant présente ça ne devrait pas prendre trop de temps à mettre en place.

Vous pouvez donc le voir par vous-même sur ce prototype de mini serveur web météo (http://cairang NULL.radioclub NULL.asia:8080/), cela fonctionne et plutôt bien à mon goût. Ne vous étonnez pas si parfois il y a peu de valeurs affichées car je continue à faire des tests et à remettre à zéro les mémoires…

J’ai même eu ma première commande, car XYL a trouvé cela pratique (pour une fois à propos de mes montages) et en aura besoin d’un pour son café-restaurant. Les services de l’hygiène demande de relever ces valeurs chaque jour en principe, même si dans la réalité peu de monde le fait… Comme elle ne prévoit pas d’ouvrir le service de restauration avant avril, j’ai le temps de mettre tout cela au point.

Je dois encore faire une étude précise, mais je pense pouvoir proposer ces stations météos autour de 70$, le prix variant suivant les options (écran, contrôleur Ethernet, capteur de pression…). Dès que je peux, je mets les informations à jour sur la page produit de la boutique (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=31). Les composants sont en fait assez chers si on veut une précision correcte (les capteurs DHT-11 par exemple ne sont bons que pour des mesures relatives) et il y a deux micro-contrôleurs (un pour la station et un pour le capteur distant). Dans tous les cas ça ne sera pas avant mi-mars prochain car les approvisionnements vont être bloqués pour plusieurs semaines à partir du week-end prochain avec le nouvel an lunaire.

En attendant je partage avec vous le code source du premier programme de test que j’avais fait pour mon prototype de mini station météo web (http://xv4y NULL.radioclub NULL.asia/2013/02/01/mini-station-meteo-web/). Il a évolué depuis mais celui-ci en principe fonctionne et offre le service de base… Il est prévu pour un Arduino Nano (ATMega328) et se compile avec Arduino 1.0.1. Je vous conseille d’utiliser mes packages librairies (http://xv4y NULL.radioclub NULL.asia/boutique/docs/) pour pouvoir les compiler.

/*
Arduino Thermometer and Humidity mini web server using internal and remote DHT11 sensors
By Yannick DEVOS - XV4Y
http://xv4y.radioclub.asia/

Copyright 2013 Yannick DEVOS under GPL 3.0 license
Any commercial use or inclusion in a kit is subject to author approval

====
This program sense and displays the current temperature and relative humidity for a local and remote sensors
It serve the values to a mini web server thanks to an ENC28J60 Ethernet module

In order to compile this program with Arduino 1.0.1, you will need to install 3 libraries :
- DHT-sensor Library by Adafruit
https://github.com/adafruit/DHT-sensor-library
- VirtualWire Library by Mike McCauley
http://www.open.com.au/mikem/arduino/VirtualWire.pdf
- Ethercard Library by JeeLabs
http://jeelabs.net/pub/docs/ethercard/index.html
====
Revision history :
v1.00    2013-02-02
         First release with mini web server test
====
This program needs at least 2KB of SRAM, that means an ATMega328...

The DHT11 Sensor need to be connected as described here below
- Connect pin 1 (on the left) of the sensor to +5V
- Connect pin 2 of the sensor to whatever your DHTPIN is (here pin D12)
- Connect pin 4 (on the right) of the sensor to GROUND
- Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
We also need a push button on pin D2.

For RF modules, please see the VirtualWire documentation

====
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

#include <EtherCard.h>
#include "DHT.h"
#include <VirtualWire.h>

// Here some parameters you would like to edit

#define RXPIN  A1        // What pin we use for Remote Sensor RX module
#define BAUDRATE 2000    // Transmission speed in bps, 1000-2000 is ok a give similar ranges, higher is useless
#define RX_LOST 60       // Max time in seconds without the sensor is considered lost
#define DHTPIN A2        // What pin we have connected the DHT sensor
#define DHTTYPE DHT22

// ethernet interface ip address
static byte myip[] = { 192,168,1,100 };
// gateway ip address
static byte gwip[] = { 192,168,1,254 };

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

const byte header[4] = {0x01,'D','H','T'};

// Here you should not be touching it

const char http_OK[] PROGMEM =
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
    "HTTP/1.0 302 Found\r\n"
    "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
    "HTTP/1.0 401 Unauthorized\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<h1>401 Unauthorized</h1>";

DHT dht(DHTPIN, DHTTYPE);

byte Ethernet::buffer[700]; // tcp/ip send and receive buffer
BufferFiller bfill;

int hi=0xFF, ti=0xFF, hr=0xFF, tr=0xFF;
int last_rx;
unsigned int counter=0;

float tf=1;

byte buf[VW_MAX_MESSAGE_LEN];
byte buflen = VW_MAX_MESSAGE_LEN;

void setup(){
  ether.begin(sizeof Ethernet::buffer, mymac);  // Start the Ethernet module
  ether.staticSetup(myip, gwip);

  vw_set_rx_pin(RXPIN);
  vw_setup(BAUDRATE);

  vw_rx_start();       // Start the RF receiver PLL running
}

void loop() {

  hi = int(dht.readHumidity());    // we convert to integer since the DHT11 has not enough precision anyway
  ti = int(dht.readTemperature());

  if (vw_have_message()) {  // If we have a message from the RF module
    if (vw_get_message(buf, &buflen) && !memcmp(&buf, &header,4)) // If it is checked and the header is the same
    {
      // First temp, the RF module send a float but we only display an integer
      memcpy(&tf, &buf[4], 4);
      tr = int(tf);

      // THen humidity
      memcpy(&tf, &buf[8], 4);
      hr = int(tf);

      last_rx = millis()/1000;  // We save when was the last data received
    }
  }

  if ((millis()/1000) > (last_rx+RX_LOST)) {    // Without signal from the sensor for more than RX_LOST seconds, the sensor is considered out of reach
    hr = 0xFF;
    tr = 0xFF;
  }  

  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len); 
  if (pos) {
    delay(1);
       bfill = ether.tcpOffset();
       char *data = (char *) Ethernet::buffer + pos;
    if (strncmp("GET /", data, 5) != 0) {
       // Unsupported HTTP request
       // 304 or 501 response would be more appropriate
       bfill.emit_p(http_Unauthorized);
    } else {
       data += 5;

       if (data[0] == ' ') {
           // Return home page
           homePage();
           counter++;
       } else {
           // Page not found
           bfill.emit_p(http_Unauthorized);
       }
    }
        ether.httpServerReply(bfill.position());    // send http response
  }
}

void homePage()
{
    bfill.emit_p(PSTR("$F"
        "<meta http-equiv='refresh' content='5'/>"
        "<title>Mini web météo v1.0 XV4Y</title>" 
        "<h1>Le temps du delta du mékong chez <a href=\"http://xv4y.radioclub.asia\">XV4Y</a></h1>"
        "<h2>Capteur interne</h2>"
        "Temp : $D°C</br>"
        "Hum. : $D%</br>"
        "<h2>Capteur distant</h2>"
        "Temp : $D°C</br>"
        "Hum. : $D%"
        "<h6>$Dème connexion.</h6>"
        "<h5>Copyright(C)2013 - <a href=\"http://xv4y.radioclub.asia/\">Yannick DEVOS XV4Y</a></h5>"
        ),
        http_OK,
        ti,
        hi,
        tr,
        hr,
        counter);
}

Voici aussi le code pour le capteur distant. Il fonctionne lui sur un MSP430G2452 et est écrit avec Energia 009.

/* Remote Temperature/Humidity sensor for MSP430G2452
 * Code for Energia 009

 * By Yannick DEVOS - XV4Y - December 2012
    http://xv4y.radioclub.asia/

    Copyright 2012-2013 Yannick DEVOS under GPL 3.0 license
    Any commercial use or inclusion in a kit is subject to author approval

====
  * Run on MSP430G2452
  * Hook a DHT sensor module to pin P2_1
  * Hook a 433MHz TX module to P2_4
  * Several pins are available for LED debugging
====
Revision history :
v1.00    2012-12-18
         First release, without MCU power saving features

====
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/>
*/

#include "DHT.h"
#include <VirtualWire.h>

#define DHTTYPE DHT11
#define DHTPIN   P2_1     // DATA Pin pour le DHT
#define TXPIN    P2_4     // DATA Pin pour le module TX RF
#define BAUDRATE 2000     // Transmission speed in bps, 1000-2000 is ok a give similar ranges, higher is useless
#define PWRPIN   P1_6     // Pin to turn ON/OFF power to the modules
#define LEDERR   P1_0     // This LED will turn on when DHT is not ok

float h, t;
byte trame[12] = {0x01,'D','H','T',0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  // The frame to be transmitted with "DHT" as header

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(PWRPIN, OUTPUT);     
  pinMode(LEDERR, OUTPUT);     

  vw_set_tx_pin(TXPIN);
  vw_setup(BAUDRATE);

  dht.begin();
}

void loop() {
  digitalWrite(PWRPIN, HIGH);  // Apply power to the modules
  delay (1000);                // We have to wait 1 second to let the DHT sensor stabilize

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  t = dht.readTemperature();
  h = dht.readHumidity();

  // Check if returns are valid, if they are both 0 then something went wrong!
  if (t == 0 && h == 0) {
    digitalWrite(LEDERR, HIGH);
  } else {
    // First temperature
    memcpy(&trame[4], &t, 4);
    // Then humidity
    memcpy(&trame[8], &h, 4);
    vw_send((byte *)trame, 12);
    digitalWrite(LEDERR, LOW);
  }
  vw_wait_tx(); // Wait until the whole message is gone

  digitalWrite(PWRPIN, LOW);  // We turn off power to save batteries
  delay(5000);                // We rest 5 seconds before the next reading, longer wait time will save more batteries...

}

 

Librairie VirtualWire 1.12 pour le MSP430 [MAJ2]

[GTranslate]

Pour une fois, je ne cache pas ma fierté. En environ 2 heures de travail, j’ai réussi mon premier vrai portage d’une libairie conçue pour l’Arduino, la librairie VirtualWire (http://www NULL.open NULL.com NULL.au/mikem/arduino/), vers le MSP430 avec Energia. Sans être un exploit, c’est un succès personnel car cela demande de se plonger dans le travail des autres, ce qui n’est jamais facile.

La difficulté technique était, je l’avoue, faible, car la seule spécificité matérielle était liée aux Timer de l’AVR qui sont différents du MSP430. Par contre, une certaine dose de réécriture de code a été nécessaire pour que cela se compile convenablement car il y a toute de même quelques différences entre les deux environnements Arduino et Energia dès qu’on commence à écrire en C.

Pour mémoire, le but de cette librairie et de pouvoir utiliser des petits modules de communication sans-fil sur 433 MHz ou 2,4 GHz pour relier deux micro-contrôleurs. Ces modules étant souvent très sommaires au niveau matériel avec une transmission du signal bande de base en On-Off Keying (tout ou rien), il faut que le logiciel apporte quelques subtilités supplémentaires pour rendre la transmission fiable. On peut ensuite obtenir des débits de 9000 bps ou plus souvent environ 2000 bps si on s’éloigne de 150 mètres. C’est suffisant pour faire un capteur de station météo (http://xv4y NULL.radioclub NULL.asia/boutique/?slug=product_info NULL.php&products_id=31) par exemple…

Le code n’est pas complètement testé mais compile correctement et les premiers essais que j’ai pu faire s’avèrent très concluants. J’ai entre autres fait communiquer un Arduino et un MSP430 par liaison sans-fil ce qui prouve que les timings sont stables!

Je mets à disposition le code source tel qu’il est aujourd’hui avec peut-être encore des bugs. N’hésitez pas à me faire parvenir vos commentaires pour l’améliorer! La documentation d’origine (http://www NULL.open NULL.com NULL.au/mikem/arduino/VirtualWire NULL.pdf) reste valable pour cette version du code.

MAJ :   (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire_110_EnergiaMSP430_20120109 NULL.zip)L’auteur a intégré mes modifications et publié une nouvelle version de la librairie, la 1.12, qui devrait fonctionner à la fois sur Arduino et Energia. Elle est téléchargeable ici (http://www NULL.open NULL.com NULL.au/mikem/arduino/VirtualWire/).

MAJ2 :   (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire_110_EnergiaMSP430_20120109 NULL.zip)Il semblerait que l’auteur de la librairie originale a bien intégré mes apports mais n’a pas testé la librairie et celle-ci ne fonctionne pas. Voici mon portage de VirtualWire 1.10 pour Energia/MSP430 tel que je l’utilise (http://xv4y NULL.radioclub NULL.asia/ftp/VirtualWire110_Energia_XV4Y NULL.zip).