Capteur sans fil pour compteur de gaz Gazpar

Capteur sans fil pour compteur de gaz Gazpar

Gazpar est le nom du nouveau compteur de gaz communiquant déployé en France par GRDF depuis maintenant quelques années. Ils émettent deux fois par jour la consommation vers un concentrateur situé à quelques km maximum sur une fréquence de 169MHz, puis les données du quartier sont transférées chez GRDF via le réseau 2G/3G. En tant que particulier nous n’avons pas accès à ces données directement, on ne peut que récupérer sa conso et son historique via le site de GRDF.

Néanmoins, ce compteur dispose d’une sortie impulsion que nous allons utiliser pour récupérer et transmettre en temps réel la consommation.

La sortie impulsion

Ce qui va nous intéresser ici c’est la prise située sur le côté du compteur, il s’agit d’une sortie impulsion. C’est une sortie à collecteur ouvert si c’est un transistor bipolaire ou à drain ouvert si c’est un mos  sur laquel on va venir capter l’impulsion émise.

Je ne sais pas si c’est le cas sur tous les modèles de compteur mais le miens émet une impulsion tous les daL, donc tous les 10L de gaz, soit 100 impulsions par m3.

Capter les impulsions

Pour capter l’impulsion, on va d’abord utiliser une résistance de tirage car quand le transistor interne au compteur n’est pas passant, c’est à dire la plupart du temps, le collecteur est « en l’air » et donc sa tension est indéterminée.

Avec ce schéma, en effectuant une mesure à l’oscilloscope, on obtient la courbe suivante où l’impulsion à durée environ 300ms. À noter que l’impulsion se déclenche lors du passage sur l’unité de litre 6. Au début je pensais que ça ne fonctionnait pas car je m’attendais à avoir l’impulsion au changement de dizaine quand les unités passent de 9 à 0.

Schéma du capteur

Le circuit s’articule autour d’un Atmega328p comme dans la plupart des circuits présentés sur ce blog. C’est le même que celui présent sur l’Arduino Uno. La partie sans fil est assurée par un module Nrf24l01+. Il est alimenté en 3.3V, avec un accu LiFePO4 par exemple, qui, vu la faible consommation, peut tenir plusieurs mois.

J’aurais pu utiliser un ESP32, du Wifi… mais je n’ai pas d’alimentation électrique à proximité immédiate du Gazpar, donc consommation minimale requise.

Le connecteur relié à Rx, Tx et Reset avec C8 et R9 est facultatif, il sert à pouvoir programmer directement comme un arduino et à utiliser le débogage serie.

Branchement sur le compteur

Normalement il existe une prise spéciale fabriquée par JAE pour se brancher sur le compteur, elle est en vente en ligne sur divers sites pour très cher. Ça peut être intéressant de l’utiliser si votre compteur est dans un endroit très humide et sujet aux intempéries. Néanmoins, la plupart des connecteurs au pas de 2.54mm, ou même des connecteurs dupont fonctionnent très bien. Pour ma part, ça sera un connecteur molex kk que j’avais en stock et qui fait parfaitement l’affaire.

La masse est en haut, et l’impulsion en bas.

Le programme

Le fonctionnement est assez simple : Lors d’une impulsion générée par le compteur, une interruption incrémente un compteur qui est sauvegardé dans l’eeprom. Toutes les 5min, la valeur de ce compteur est transmise par radio. L’eeprom de l’atmega est donnée pour 100 000 cycles d’écriture, ce qui finalement est assez peu. En théorie la zone mémoire sur laquelle on écrit sera probablement morte au bout de 1000m3 de gaz consommés. Pour prolonger la durée de vie on peut modifier le programme pour déplacer la zone dans l’eeprom selon la valeur de l’index.

A la première programmation, il sera aussi nécessaire de mettre en mémoire l’index actuel du compteur de gaz.

Librairies utilisées :

#include <LowPower.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <EEPROM.h>
#include <stdint.h>

#include <PinChangeInterrupt.h>

/* -------CONFIG---------*/
#define LOGDEBUG 0
/* --------------------- */

#define NODE_ID 5
/* --------------------- */

#define EE_ADDR 0
/* --------------------- */

#define RF24_CH 25
/* --------------------- */

#define SLEEP_DT 36 //5min , 8s par cycle
#define SLEEP_VT 75 //10min
/* --------------------- */


#define VT_PIN 14 //ADC3
#define RF24_ON 6
#define LED_PIN 5
#define PULSE_PIN 16 //PCINT10
/* --------------------- */

//DEBUG
#if LOGDEBUG==1
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTDEC(x) Serial.print(x, DEC)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_RADIO() radio.printDetails()
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTDEC(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_RADIO()
#endif
/* --------------------- */


uint8_t server_address[5] = {10, 20, 30, 40, 50};
uint8_t node_address[5] = {1, 20, 30, 40, 50};
/* --------------------- */


uint16_t nodeId = NODE_ID;
RF24 radio(9,10);

uint8_t radioBuffer[32] = {0};

uint16_t cntVT = SLEEP_VT;
uint16_t cntDT = SLEEP_DT;

float voltage = 0;
uint32_t daLCount = 5018;


void radioSetup(){
radio.begin();
radio.setChannel(RF24_CH);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setCRCLength(RF24_CRC_16);
radio.setRetries(15, 5);
radio.setAutoAck(1);
radio.openReadingPipe(1, node_address);
radio.openWritingPipe(server_address);

DEBUG_RADIO();
}


void setup() {
delay(500);

#if LOGDEBUG==1
Serial.begin(9600);
printf_begin();
#endif

//EEPROM.put(EE_ADDR, daLCount);

pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

pinMode(PULSE_PIN, INPUT);

pinMode(RF24_ON, OUTPUT);
digitalWrite(RF24_ON, HIGH);


//flash led
digitalWrite(LED_PIN, HIGH);
delay(250);
digitalWrite(LED_PIN, LOW);


analogReference(INTERNAL);

DEBUG_PRINTLN("Read EEPROM");
EEPROM.get(EE_ADDR, daLCount);


//flash led
delay(500);
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);

DEBUG_PRINTLN("attachPCIN");
attachPCINT(digitalPinToPCINT(PULSE_PIN), pulseEvent, FALLING);
}


void pulseEvent(){
DEBUG_PRINT("Pulse.");
++daLCount;

//save to eeprom
DEBUG_PRINT("Save to EEPROM daL=");
DEBUG_PRINTLN(daLCount);
EEPROM.put(EE_ADDR, daLCount);
}


void loop() {
DEBUG_PRINTLN(">");


if( (cntDT >= SLEEP_DT) || (cntVT >= SLEEP_VT)){

//power on radio
digitalWrite(RF24_ON, LOW);

delay(100);
radioSetup();

DEBUG_PRINTLN("Radio up");

if(cntDT >= SLEEP_DT){
//send message
memcpy(radioBuffer, &nodeId, 2);
memcpy(radioBuffer+2, "CS", 2);
memcpy(radioBuffer+4, &daLCount, 4);

if(radio.write(radioBuffer, 32)){
cntDT = 0;
}
else{
if(cntDT >= (SLEEP_DT+5)){
//retry up to 5 cycles of 8s.
cntDT = 0;
}
}

}

delay(250);
radio.flush_tx();



if(cntVT >= SLEEP_VT){
voltage = analogRead(VT_PIN);
voltage = voltage * 1.1 * ((1670000.0)/470000.0) / 1024.0;

DEBUG_PRINT("V=");
DEBUG_PRINTLN(voltage);


memcpy(radioBuffer, &nodeId, 2);
memcpy(radioBuffer+2, "VT", 2);

memcpy(radioBuffer+4, &voltage, 4);

if(radio.write(radioBuffer, 32)){
cntVT = 0;
}
else{
if(cntVT >= (SLEEP_VT+5)){
//retry up to 5 cycles of 8s.
cntVT = 0;
}
}
}


delay(50);

//power down radio
radio.powerDown();
digitalWrite(RF24_ON, HIGH);
}

++cntVT;
++cntDT;

//flash led
digitalWrite(LED_PIN, HIGH);
delay(1);
digitalWrite(LED_PIN, LOW);

DEBUG_PRINTLN(".");

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

}
Capteur Gazpar

La consommation est stockée dans une base de donnée, et il est possible de générer un graph en temps réel de la consommation. Si le compteur envoyait la consommation aussi souvent à GRDF, ils seraient en mesure de savoir à quelle heure vous avez pris votre douche… contrairement au linky qui n’a pas trop de soucis à se faire niveau alimentation électrique, le gazpar fonctionne sur une pile lithium, le nombre de relevé n’est pas illimité.

 

21 réflexions sur « Capteur sans fil pour compteur de gaz Gazpar »

  1. Bonjour,
    Merci pour votre article.
    Concernant la sortie impulsion, vous dite:
    C’est une sortie à collecteur ouvert si c’est un transistor bipolaire ou à drain ouvert si c’est un mos.
    Dois-je en conclure qu’il y a deux type de sortie, donc tous les compteurs GAZPAR ne sont pas identiques?
    Est-il possible d’identifier visuellement quel montage est utiliser sur le compteur?
    Si non comment l’identifier?
    Merci pour votre aide.
    Bien cordialement

    1. Bonjour,
      Je ne sais pas s’il existe plusieurs types de compteur gazpar avec des différences d’électronique à l’intérieur. C’était pour exprimer que pour nous c’est une boîte noire, quelque soit le type de transistor qui peut être dedans on aura le même fonctionnement de l’impulsion vu de l’extérieur.

  2. Bonjour,
    Merci pour ce partage.

    Une chose doit m’échapper surement mais à la vue du code je ne vois pas comment vous pouvez envoyer toutes les 5 minutes. Si aucune interruption ne se produit ok, là vous repartez dans la mainLoop 36 fois avec 8sec de sleep (36*8 ~ 5min).

    Mais si vous avez des pulseEvent() vous repartez dans la mainLoop et alors cntVT est incrémenté sans que 8sec soit passé. Si vous avez 1 interruption/sec alors l’envoi sera fait toute les 36 secondes (et non plus toutes les 5 minutes) non ?

    Cordialement.

    1. Bonjour,
      Merci pour votre remarque qui est très pertinente. Vous avez raison, je pense que chaque pulseEvent() vient consommer une des 36 boucles de 8s de sleep, plus ou moins selon comment les 8s de sommeil sont déjà entamées. D’un point de vu fonctionnement, ça fait des transmissions des mesures un peu plus rapprochées quand la consommation de gaz est plus importante. Quand ma chaudière est au maximum, j’ai environ une impulsion toutes les 15s, je ne m’étais pas aperçu de ça.
      Cordialement 🙂

      1. Mince j’avais tant d’espoir d’avoir raté un truc. J’ai essayé de regarder du coté des timer (timer2 notamment que l’on peut détourner de son utilisation principale si j’ai bien compris pour faire le décompte des pulse et ainsi ne pas utiliser d’interruption) mais j’ai pas réussi. Je suis arrivé à la conclusion que sans hardware supplémentaire (clock externe ) je n’arriverai pas à compter et envoyer toutes les X minutes en low power. Donc je vais rester avec votre algo ou alors j’envoie tous les X pulses (20 semble pertinent chez moi).

        Merci beaucoup.

  3. Bonjour,

    je vais bientôt avoir ce compteur. Où peut on trouver ce compteur à impulsion ? Y a t’il un moyen de le fabriquer ?

    Merci d’avance pour la réponse

    1. Bonjour,
      Oui, le but de la publication c’est que n’importe qui puisse le fabriquer, l’améliorer ou l’adapter à son besoin à partir du schéma électronique et du code source du programme transféré dans le microcontrôleur.

      1. Bonjour,
        ok merci. Je n’y connais rien au niveau électronique. Je prends généralement du tout fait, mais là rien n’existe.
        Il va falloir que je trouve quelqu’un qui me fasse la partie électronique.
        Le module Nrf24l01+, c’est bien pour la partie wifi ?
        Le transfert du code se fait comment ?

        1. Bonjour,
          Le module Nrf24l01+ est utilisé pour transférer les mesures du capteur sans fil. Ce n’est ni du wifi ni du bluetooth. Le capteur ne pourrait pas tenir plusieurs mois sur une pile en utilisant le wifi.
          Le transfert du code sur le microcontrôleur peut se faire avec un arduino uno ou avec un « arduino on a breadboard » (https://www.arduino.cc/en/main/standalone) et en utilisant un programmeur du type UsbAsp.

  4. Bonjour, sujet intéressant , j’avais un capteur Zwave NorthQ, qui fonctionnait avec un capteur optique ou magnétique, je vais adapter la sortie pour le North, j’ai récupéré les infos de GRDF.
    Je peux les partager, mais c’est sous la forme d’images

  5. Bravo pour ce post!
    Ce projet décrit l’émetteur en radio (branché au GAZPAR). Pouvez-vous décrire en quelques mots ce que vous utilisiez côté récepteur ? Un Nrf24l01 également ? Sur un Arduino ou autre ? Comment ensuite transférer les données vers un PC ?
    Merci!

    1. Bonjour,
      Pour le récepteur, j’utilise également un nrf24. Il était branché sur un autre microcontrôleur de la famille atmega (1284P) dans un précédent projet (https://blog.zesanglier.fr/2019/12/08/passerelle-nrf24-ethernet/) où, via un module ethernet, les infos reçues étaient poussée vers une BDD MySql sur un NAS Synology.
      J’ai eu l’occasion de tester avec le nrf branché directement sur un raspberry ce qui fonctionnement également.
      Actuellement, j’utilise une nouvelle passerelle Nrf/Ethernet basée sur un ESP32, mais qui a l’avantage de pourvoir être utilisé en Wifi pour le réseau ou la mise à jour du firmware.

  6. Bonjour,

    J’étais en cours de réalisation du même capteur que toi.

    D’abord, un grand merci pour toutes les informations que je n’avais pas.

    Je réalise cela avec un ESP32 dont la consommation tombe à quelque 10uA en mode DeepSleep. Ce qui donne une autonomie….assez grande. Par ailleurs, l’ESP32 dispose de tous les moyens de communication nécessaire (BT WIFI BLE)

    Une petite question cependant, quand tu tire du gaz au maximum, as-tu une idée de la fréquence des impulsions?

     

    cordialement,

    1. Bonjour,

      ça fait plaisir que mes recherches puissent être utiles 😀
      L’ESP32 est un bon choix aussi avec beaucoup de capacités pour un prix compétitif.
      Le maximum que j’ai pu mesurer c’est une impulsion par 20s environ. En Partant de là, par le calcul on retrouve à peu près la puissance de chauffe de la chaudière donc c’est cohérent.

      Bonne soirée!

  7. Bonsoir à tous,

    Au sujet du connecteur sur le compteur Gazpar, j’ai pu lire dans cet article :
    « la plupart des connecteurs au pas de 2.54 mm conviennent ».

    Intéressé par le sujet j’ai vérifié sur mon compteur. La distance entre les 2 pins est très proche de 4 mm.
    A priori, connecteur à 3 pins au pas de 2 mm dont pin du milieu absente.
    Attention : pour ceux qui voudraient « bricoler » une prise.

  8. Bonsoir à tous,

    Sauf cas de force majeure, je trouve que la liaison radio pour transmettre les impulsions Gazpar est un peu « lourde ».

    Pour mon cas, coffrets Linky et Gazpar en limite de propriété sur la rue, voici ce que je me propose de réaliser.
    Plus simple et plus fiable à mon avis.
    Profitez-en et merci de bien vouloir me faire par de vos remarques et améliorations.
    Compte-tenu de la fréquences des impulsions, je n’ai pas jugé utile de mettre une DEL dans le circuit Gazpar.

    voir le schéma sur ce lien : http://www.microfer.fr/geryko/telechargements_publics/Linky_Gazpar.JPG

    http://www.microfer.fr/geryko/telechargements_publics/Linky_Gazpar.JPG

    Bravo à ZeSanglier !

  9. un esp32 avec le comptage d’impulsion intégré (esphome) devrait faire l’affaire, codage très simple, wifi, hardware très simple.

  10. Bonsoir,

    Je lis avec attention, mais je ne vois marqué nul part la valeur de résistance de charge.

    En effet, je suis également sur ce projet, pour finir complètement mes télérelèves avec un EcoCompteur Legrand 412000. Je suis passé au gaz avec un compteur Gazpar mais la remontée ne fonctionne pas. J’ai acheté un câble JAE puis continué avec un câble RJ45 en doublant deux paires ( 2fils/ pin) du compteur à l’ecocompteur…mais nada ! cela ne fonctionne pas.

    Pourtant, quand je simule, depuis le compteur jusqu’à l’eco, (25m) cela fonctionne. Quand je contrôle à l’ohmètre, depuis l’eco, le signal, je vois bien l’état changer, mais quand tout est branché, rien ne se passe.

    Donc la solution avec la résistance de charge et alim de 5vcc me semble être une idée à tester, d’où mon interrogation de la valeur de résistance.

    Merci de votre aide.

     

Répondre à Gilles Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *