IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Lecture de satellites TFA Dostmann 30.3208.02


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Touche à tout
    Inscrit en
    Mars 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Touche à tout

    Informations forums :
    Inscription : Mars 2009
    Messages : 120
    Par défaut Lecture de satellites TFA Dostmann 30.3208.02
    Bonjour à tous,

    Novice en Arduino, mais pas en programmation et je suis électricien automaticien de formation, (mais ça date ))

    Ce sont des émetteurs température/humidité

    Je me suis inspiré de ce PDF pour le code
    J'utilise le bête petit récepteur 433 MHz dont la broche data est en TTL

    J'ai les spécifications pour ces émetteurs (en commentaires au début du code) avec notamment ceci : Un bit à 0 est codé par une impulsion de 500 ms suivie d'une impulsion inverse de 1000 ms (2 unités), un bit à 1 par une impulsion de 500ms suivie de l'impulsion inverse de 2000ms (4 unités).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     durH = pulseIn(pin, HIGH);
    lit bien l'impulsion, mais je ne vois pas trop pour ce qui est qualifié d'inverse car ne semble pas fonctionner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    /*
     * 
     * https://cdn.instructables.com/ORIG/FAY/0LCL/H2WERYWD/FAY0LCLH2WERYWD.pdf
     
    TFA Dostmann 30.3208.02 Émetteur de rechange pour régulateur thermique 
     
    https://www.amazon.fr/Dostmann-30-3208-02-Émetteur-rechange-régulateur-thermique/dp/B00SVDVWAA/
     
    Chaque satellite émet à peu près toute les minutes. A chaque fois, il émet le même message 3 fois. 
    Le codage se fait par des impulsions dont la durée est un multiple de 500 micro-secondes. 
    Le début du message commence par une impulsion de 8 unités (8 x 500 = 4000 micro secondes, 4 millisecondes). 
    Le message comporte ensuite 74 impulsions (37 bits). 
    Un bit à 0 est codé par une impulsion de 500 ms suivie d'une impulsion inverse de 1000 ms (2 unités), 
      un bit à 1 par une impulsion de 500ms suivie de l'impulsion inverse de 2000ms (4 unités). 
      Le message se décompose de la manière suivante (certains bits ne servent pas):
     
    bits 0-7: identifiant du satellite (aléatoire).
    bits 8-9: Statut (?)
    bits 10-11: Canal (valeur de l'interrupteur derrière le satellite)
    bits 16-23: Température en dégrés x10. Par exemple, pour 20,2, on aura 202.
    bits 28-35: Humidité en pourcentage.
     */
     
    byte pin = 13;
    unsigned int durH;
    unsigned int durL;
    float durR;
     
     
     
    void setup()
    {
      pinMode(pin, INPUT);
      Serial.begin(9600); Serial.flush();
    }
     
    ;void loop()
    {
     int cpt;
     durH = pulseIn(pin, HIGH);
     if ((durH>3900)&&(durH<4100)) // début de transmission 
     {
        durR=durH/8;
        Serial.print(durR);
        Serial.print(" -:- ");
        do
        {
          durH = pulseIn(pin, HIGH);
          if ((durH>450)&&(durH<550)){
           cpt++;
           Serial.print(".");
           durL=pulseIn(pin,LOW);
           if((durL>900)&&(durL<1100)){
            Serial.print("0");
           }else if ((durL>1800)&&(durL<2200)) {
              Serial.print("1");
           }
          }
         }while(cpt<37);
        }
        if(cpt==37) {Serial.println();}
    }
    Extrait de la sortie, qui n'est pas fluide !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    509.00 -:- .....................................
    495.00 -:- .....................................
    502.00 -:- .....................................
    494.00 -:- .....................................
    490.00 -:- .....................................
    492.00 -:- ...0..................................
    509.00 -:- .....................................
    492.00 -:- ..............................0.......
    Je suis preneur d'idées.
    Cordialement

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Salut,
    Là comme ça et à froid, je dirai que les données sont codées au format Manchester https://fr.wikipedia.org/wiki/Codage_Manchester c'est à dire qu'un bit à 1 correspond à un front descendant et un 0 à un front montant.

    Si c'est le cas il n'est donc pas utile de mesurer la durée de l'état logique. Je pense que c'est ce que tu essayes de faire dans ton soft ? Non ? Il faut regarder le sens de la transition pour décoder le message.

    Tu dis que des bits ne servent à rien. Sache que sur certain émetteur il faut envoyer ce qu'on appelle un préambule avant les données. Ce préambule, composé de données inutiles, sert surtout à donner un peu de temps à la PLL (boucle à verrouillage de phase) pour se synchroniser afin de générer la bonne fréquence. On peut caricaturer ça en disant que c'est le temps de démarrage, ou plutôt de stabilisation, de l'oscillateur.

  3. #3
    Membre actif
    Homme Profil pro
    Touche à tout
    Inscrit en
    Mars 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Touche à tout

    Informations forums :
    Inscription : Mars 2009
    Messages : 120
    Par défaut
    Merci pour ta réponse, @Vincent,

    Deux choses :
    1. La lecture du PDF montre des prompts d'oscilloscope de différents satellites, successions de Hauts de différentes durées.
    2. Les explications des bits sont un copié/collé d'un commentaire sur Amazon ...

    C'est de ces commentaires que j'ai échafaudé l'idée de ce projet.

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Ah ! J'ai dit une bêtise dans mon dernier poste, quand bien même ce serait un codage Manchester, il faut mesurer le temps des états hauts et bas.

    En y regardant de plus prés, ce n'est pas du Manchester mais effectivement du PWM (on aurait vu des décalages dans un codage Manchester, des lignes roses se seraient retrouvées au milieu d'un état haut ou bas) :

    Nom : im1.png
Affichages : 509
Taille : 123,9 Ko

    Je n'ai pas tester mais je pense qu'on peut simplifier un peu ton programme comme suit :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    byte pin = 13;
    unsigned int durH;
    unsigned int cpt;
     
     
    void setup()
    {
       pinMode(pin, INPUT);
       Serial.begin(9600);
       durH = 0;
       cpt = 0;
    }
     
    void loop()
    {
       durH = pulseIn(pin, HIGH);
     
       cpt++;
     
       if(cpt > 8) // on ignore les 8 premiers bits
       {
          if (durH>500)		// bit 1 
    	Serial.print("1");
          else			// bit 0
    	Serial.print("0");
       }
     
       if(cpt == 37)
       {
          Serial.println();
          cpt = 0;
       }
    }

  5. #5
    Membre actif
    Homme Profil pro
    Touche à tout
    Inscrit en
    Mars 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Touche à tout

    Informations forums :
    Inscription : Mars 2009
    Messages : 120
    Par défaut
    Bon, j'ai creusé sur le Web et j'ai trouvé ceci : https://github.com/robwlakes/ArduinoWeatherOS

    Ça fonctionne, y a plus qu'à décoder les bits. Le schéma que j'avais trouvé ne peut pas être correct, car il ne mentionne que 2 bits pour le canal, alors qu'il y en a 3 !

    Et en revenant ici, je remarque seulement maintenant que tu avais donné le protocole "Manchester". Au temps pour moi, j'avais lu trop vite.

    Merci !

  6. #6
    Membre actif
    Homme Profil pro
    Touche à tout
    Inscrit en
    Mars 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Touche à tout

    Informations forums :
    Inscription : Mars 2009
    Messages : 120
    Par défaut
    Nos posts se sont croisés Merci encore Vincent (et je vais tester ton code)

  7. #7
    Membre actif
    Homme Profil pro
    Touche à tout
    Inscrit en
    Mars 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Touche à tout

    Informations forums :
    Inscription : Mars 2009
    Messages : 120
    Par défaut Décodage
    Bonjour à tous,

    Je relance le sujet car j'ai encore des soucis.
    J'utilise le code DebugManchester.ino trouvé là : https://github.com/robwlakes/ArduinoWeatherOS

    Il me sort 5 octets comme ceci : D 51 01010001 4F 01001111 65 01100101 15 00010101 D0 11010000

    J'ai fini par trouver que les bits 10 à 12 correspondent au canal (0 à 7) et ceux de 13 à 24 à la température.
    Nom : Ecran 2018-09-11 14.37.52.png
Affichages : 585
Taille : 8,7 Ko

    Pour le canal, c'est du binaire simple : les 8 valeurs des 3 bits.
    Pour la température : c'est ( la valeur décimale - 720) * 0.0556 J'ai trouvé sur le WEB, mais je ne sais plus où :/

    Par contre, je ne vois pas où pourrait se trouver l'humidité. (Regardez les des lignes surlignées en jaune, c'est 51% d'umidité

    Ma conclusion est que le code ne montre pas la transmission en entier. Il est commenté, mais en Anglais et je ne comprends pas bien.

    Qu'en pensez-vous ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    /*  Manchester Decoding, reading by delay rather than interrupt
     Rob Ward August 2014
     This example code is in the public domain.
     Use at your own risk, I will take no responsibility for any loss whatsoever its deployment.
     Visit https://github.com/robwlakes/ArduinoWeatherOS for the latest version and
     documentation. Filename: DebugManchester.ino
     
     DebugVersion_10, 1stAugust 2014
     
     */
     
     
    //Interface Definitions
    int RxPin           = 8;   //The number of signal from the Rx
     
     
    int ledPin          = 13;  //The number of the onboard LED pin
     
     
    // Variables for Manchester Receiver Logic:
    word    sDelay     = 250;  //Small Delay about 1/4 of bit duration  try like 250 to 500
    word    lDelay     = 500;  //Long Delay about 1/2 of bit duration  try like 500 to 1000, 1/4 + 1/2 = 3/4
    byte    polarity   = 1;    //0 for lo->hi==1 or 1 for hi->lo==1 for Polarity, sets tempBit at start
    byte    tempBit    = 1;    //Reflects the required transition polarity
    byte    discards   = 0;    //how many leading "bits" need to be dumped, usually just a zero if anything eg discards=1
    boolean firstZero  = false;//has it processed the first zero yet?  This a "sync" bit.
    boolean noErrors   = true; //flags if signal does not follow Manchester conventions
    //variables for Header detection
    byte    headerBits = 10;   //The number of ones expected to make a valid header
    byte    headerHits = 0;    //Counts the number of "1"s to determine a header
    //Variables for Byte storage
    byte    dataByte   = 0;    //Accumulates the bit information
    byte    nosBits    = 0;    //Counts to 8 bits within a dataByte
    byte    maxBytes   = 5;    //Set the bytes collected after each header. NB if set too high, any end noise will cause an error
    byte    nosBytes   = 0;    //Counter stays within 0 -> maxBytes
    //Variables for multiple packets
    byte    bank       = 0;    //Points to the array of 0 to 3 banks of results from up to 4 last data downloads 
    byte    nosRepeats = 0;    //Number of times the header/data is fetched at least once or up to 4 times
    //Banks for multiple packets if required (at least one will be needed)
    byte  manchester[4][20];   //Stores 4 banks of manchester pattern decoded on the fly
     
     
    /* Sample Printout, Binary for every packet, but only combined readings after three of the different packets have been received
     This is an example where the Sync '0' is inside the byte alignment (ie always a zero at the start of the packet)
     
     Using a delay of 1/4 bitWaveform 245 uSecs 1/2 bitWaveform 490 uSecs 
     Positive Polarity
     10 bits required for a valid header
     Sync Zero inside Packet
     D 00 00001111 01 22223333 02 44445555 03 66667777 04 88889999 05 AAAABBBB 06 CCCCDDDD 07 EEEEFFFF 08 00001111 90 22223333
     D 5F 01011111 14 00010100 28 00101000 C5 11000101 01 00000001 //Oregon Scientific Temperature
     D 54 01010100 98 10011000 20 00100000 A0 10100000 00 00000000 //Oregon Scientific Rainfall
     D 58 01011000 91 10010001 20 00100000 52 01010010 13 00010011 //Oregon Scientific Anemometer/Wind direction
     These are just raw test dumps. The data has to be processed and require 10-11 bytes for all the packet to be seen
     Oregon Scientific works on nibbles and these need to reversed ie ABCD become DCBA in each nibble
     Also the OS protocol has a simple checksum to assist with validation as the packets are only sent once a cycle
     */
     
     
    void setup() {
      Serial.begin(115200);//make it fast so it dumps quick!
      pinMode(RxPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.println("Debug Manchester Version 09");
      lDelay=2*sDelay;//just to make sure the 1:2 ratio is established. They can have some other ratio if required
      Serial.print("Using a delay of 1/4 bitWaveform ");// +-15% and they still seem to work ok, pretty tolerant!
      Serial.print(sDelay,DEC);
      Serial.print(" uSecs 1/2 bitWaveform ");//these may not be exactly 1:2 ratio as processing also contributes to these delays.
      Serial.print(lDelay,DEC);
      Serial.println(" uSecs ");
      if (polarity){
        Serial.println("Negative Polarity hi->lo=1"); 
      }
      else{
        Serial.println("Positive Polarity lo->hi=1"); 
      }
      Serial.print(headerBits,DEC); 
      Serial.println(" bits expected for a valid header"); 
      if (discards){
        Serial.print(discards,DEC);
        Serial.println(" leading bits discarded from Packet"); 
      }
      else{
        Serial.println("All bits inside the Packet"); 
      }
      Serial.println("D 00 00001111 01 22223333 02 44445555 03 66667777 04 88889999 05 AAAABBBB 06 CCCCDDDD 07 EEEEFFFF 08 00001111 09 22223333"); 
      //if packet is repeated then best to have non matching numbers in the array slots to begin with
      //clear the array to different nos cause if all zeroes it might think that is a valid 3 packets ie all equal
      eraseManchester();  //clear the array to different nos cause if all zeroes it might think that is a valid 3 packets ie all equal
    }//end of setup
     
     
    // Main routines, find header, then sync in with it, get a packet, and decode data in it, plus report any errors.
    void loop(){
      tempBit=polarity^1; //these begin the opposites for a packet
      noErrors=true;
      firstZero=false;
      headerHits=0;
      nosBits=0;
      nosBytes=0;
      digitalWrite(ledPin,0); //Flag LED off
      while (noErrors && (nosBytes<maxBytes)){
        while(digitalRead(RxPin)!=tempBit){
          //pause here until a transition is found
        }//at Data transition, half way through bit pattern, this should be where RxPin==tempBit
        delayMicroseconds(sDelay);//skip ahead to 3/4 of the bit pattern
        // 3/4 the way through, if RxPin has changed it is definitely an error
        digitalWrite(ledPin,0); //Flag LED off!
        if (digitalRead(RxPin)!=tempBit){
          noErrors=false;//something has gone wrong, polarity has changed too early, ie always an error
        }//exit and retry
        else{
          byte bitState = tempBit ^ polarity;//if polarity=1, invert the tempBit or if polarity=0, leave it alone.
          delayMicroseconds(lDelay);
          //now 1 quarter into the next bit pattern,
          if(digitalRead(RxPin)==tempBit){ //if RxPin has not swapped, then bitWaveform is swapping
            //If the header is done, then it means data change is occuring ie 1->0, or 0->1
            //data transition detection must swap, so it loops for the opposite transitions
            tempBit = tempBit^1;
          }//end of detecting no transition at end of bit waveform, ie end of previous bit waveform same as start of next bitwaveform
     
     
          //Now process the tempBit state and make data definite 0 or 1's, allow possibility of Pos or Neg Polarity 
          if(bitState==1){ //1 data could be header or packet
            if(!firstZero){
              headerHits++;
              if (headerHits==headerBits){
                digitalWrite(ledPin,1); //valid header accepted, minimum required found
                //Serial.print("H");
              }
            }
            else{
              add(bitState);//already seen first zero so add bit in
            }
          }//end of dealing with ones
          else{  //bitState==0 could first error, first zero or packet
            // if it is header there must be no "zeroes" or errors
            if(headerHits<headerBits){
              //Still in header checking phase, more header hits required
              noErrors=false;//landing here means header is corrupted, so it is probably an error
            }//end of detecting a "zero" inside a header
            else{
              //we have our header, chewed up any excess and here is a zero
              if ((!firstZero)&&(headerHits>=headerBits)){ //if first zero, it has not been found previously
                firstZero=true;
              }//end of finding first zero
              add(bitState);
            }//end of dealing with a zero
          }//end of dealing with zero's (in header, first or later zeroes)
        }//end of first error check
      }//end of while noErrors=true and getting packet of bytes
      digitalWrite(ledPin,0); //data processing exited, look for another header
    }//end of mainloop
     
     
    //Read the binary data from the bank and apply conversions where necessary to scale and format data
    void analyseData(){ 
    }
     
     
    void add(byte bitData){
      if (discards>0){ //if first one, it has not been found previously
        discards--;
      }
      else{
        dataByte=(dataByte<<1)|bitData;
        nosBits++;
        if (nosBits==8){
          nosBits=0;
          manchester[bank][nosBytes]=dataByte;
          nosBytes++;
          //Serial.print("B");
        }
        if(nosBytes==maxBytes){
          hexBinDump();//for debug purposes dump out in hex and binary
          //analyseData();//later on develop your own analysis routines
        }
      }
    }
     
     
    void hexBinDump(){
      //Print the fully aligned binary data in manchester[bank] array
      Serial.print("D ");
      for( int i=0; i < maxBytes; i++){ 
        byte mask = B10000000;
        if (manchester[bank][i]<16){
          Serial.print("0"); //Pad single digit hex
        }
        Serial.print(manchester[bank][i],HEX);
        Serial.print(" ");
        for (int k=0; k<8; k++){
          if (manchester[bank][i] & mask){
            Serial.print("1");
          }
          else{
            Serial.print("0");
          }
          mask = mask >> 1;
        }
        Serial.print(" ");
      }
      Serial.println();
    }
     
     
    void eraseManchester(){
      //Clear the memory to non matching numbers across the banks
      //If there is only one packet, with no repeats this is not necessary.
      for( int j=0; j < 4; j++){ 
        for( int i=0; i < 20; i++){ 
          manchester[j][i]=j+i;
        }
      }
    }
    Images attachées Images attachées  

Discussions similaires

  1. [PC portable] toshiba satellite plante en lecture video streaming
    Par Jean.Cri1 dans le forum Ordinateurs
    Réponses: 10
    Dernier message: 29/09/2011, 22h34
  2. Lecture de fichiers ".WAV"...
    Par 0x4e84 dans le forum Langage
    Réponses: 2
    Dernier message: 03/09/2002, 09h43
  3. Pb Lecture de bitmap monochrome
    Par Loïc38 dans le forum C++Builder
    Réponses: 4
    Dernier message: 02/07/2002, 18h24
  4. Lecture d'une image bitmap
    Par Geronimo dans le forum x86 32-bits / 64-bits
    Réponses: 18
    Dernier message: 28/06/2002, 12h01
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo