[RESOLU] Conversion mesure DS18S20. [MERCI ! ]

Bonjour ;

Revenant sur un vieux projet (2016) monté depuis l’exemple de la “lib” <oneWire.h>
J’utilise des sondes de températures DS18S20.

Je fait appel à vos services car après maintes manipulations programme (série), lecture de datasheet et recherches sur le Net.
Je n’arrive toujours pas à m’expliquer pourquoi on réalise un décalage de 8 bits à gauche du BYTE 1 du tableau et une opération bit à bit “ou” avec le BYTE 0.
Ces données sont le retour brut numérique de la valeur de température.

Pour exemple à 25° donne 0000 0000_0011 0010 soit 0032h (0x32) / Pour K=0.5°c par bits. (datasheet)
Suivant opération première (Xn+1<<8…= 0011 0010 0000 0000. (juste inverser ?)
Puis seconde …| Xn-1)
0000 0000
0011 0010

0011 0010

Pour finir Ensuite suivant modèle S décalage à 3 de plus à gauche soit 12 au total. Résolution oblige (?).
<<3 => 1001 0000.

J’en arrive à chercher cela suite au faite que les huit bite de poids fort (gauche) ne sont utilisés que pour le signe de la valeur (+/-) et que si l’on exploite directement la donnée d’index 1 du tableau cela fonctionne. (A condition de rester dans le positif je suppose!)
De plus si je fait une conversion via la valeur décimal suivant le coef K cela fonctionne aussi. (logique suivant le résultat idem)
0.5*50(32h) = 25.
Ci-dessous l’exemple.

int16_t raw = (data[1] << 8) | data[0]; //inhibé pour test.
 Serial.print("raw<<8|data[0]  /"); Serial.println(raw, BIN); //Affichage

//----- TEST série------//
Serial.print(data[0]*0.5); //Affichage résultat sur K.

//-----Application de la résolution-----//
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    Serial.print("<<3             /"); Serial.println(raw << 3, BIN); //Affichag
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
//-----Affichage des valeurs-----//
      Serial.print("& 0xFFF0  /"); Serial.println(raw & 0xFFF0, BIN); //Affichag
      Serial.print("+12       /"); Serial.println((raw & 0xFFF0) + 12, BIN); //Affichag
      Serial.print("- data[6] /"); Serial.println((raw & 0xFFF0) + 12 - data[6], BIN); //Affichag
    }
  while (1); //stop boucle

Quel est le but de l’opérations ?
Quelqu’un à une réponse sur le fonctionnement de cette logique? une chose m’échappe je sais pas quoi !! :frowning:

Ci dessous le code origine de la lib <oneWire.h>
Exemple => DS18x20_Temperature

Vous remerciant;
salutations.

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

Bonjour,

Je n’arrive toujours pas à m’expliquer pourquoi on réalise un décalage de 8 bits à gauche du BYTE 1 du tableau et une opération bit à bit “ou” avec le BYTE 0.

(octet1 << 8) | octet0

Cette opération ne fait que construire un int16 à partir des deux octets.

Par exemple pour -25°C:

_octet1_ _octet0_
11111111 11001110

On peut décomposer l’opération comme ça:

_octet1_ << 8 = _octet1_00000000
11111111 << 8 = 1111111100000000
_octet1_00000000 | _octet0_ = _octet1__octet0_
1111111100000000 | 11001110 = 1111111111001110 = -50

Pour le décalage de 3 à gauche, c’est l’équivalent d’une multiplication par 8

1111111111001110 << 3 = 1111111001110000 = -400

(les multiplications de puissances de 2 sont très probablement optimisées lors de la compilation donc inutile d’écrire << 3 si l’intention est de multiplier par 8, autant écrire * 8 pour que ce soit plus clair…)

J’avoue ne pas comprendre le reste, ça n’a pas l’air de correspondre à ce qui est marqué dans la fiche technique. A vrai dire je n’ai pas beaucoup cherché à comprendre, il est tôt…

manumanu:
Bonjour ;

Revenant sur un vieux projet (2016) monté depuis l’exemple de la “lib” <oneWire.h>
J’utilise des sondes de températures DS18S20.

Je fait appel à vos services car après maintes manipulations programme (série), lecture de datasheet et recherches sur le Net.
Je n’arrive toujours pas à m’expliquer pourquoi on réalise un décalage de 8 bits à gauche du BYTE 1 du tableau et une opération bit à bit “ou” avec le BYTE 0.

bonjour
un peu de lecture sur le sujet

Bonjour
Merci pour votre réponse.
Je regarde cela est vous fait un retour des que possible.
Salutations.


Bonjour tous ;

Ca y est j'ai - je pense avoir compris-
La réponse était sous mes yeux. Dans le datasheet.
Merci Guix et Artouste pour vos infos.
Effectivement, via le moniteur, avec une valeur positive le calcul des bits est "transparent". Par contre en valeur négatif c'est tout autre en lecture par le moniteur.

La raison du décalage à gauche est dus au fait que "l'extraction" des bytes de donnée température sont réalisé par le byte de poids fort du scratch pad de la sonde
Pour 25° en acquisition tableau cela donne.
Byte0 Byte1
00110010 00000000. (110010 0)

Or suivant le datasheet l'expression de la température pour et avant conversion doit être interprété sur 16bits.
Soit 00000000 00110010. Le premier byte étant l'expression de signe (+/-)

L'opération de décalage et donc là pour reconstituer la donnée dans le bon sens -si je puis dire-

Merci pour votre aide qui m'a permis de voir les chose sous un autre angle.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.