2015-03-14 2 views
0

Comment son code calcule-t-il la température?Comment le programme technions DHT22.c calcule-t-il la température?

Il est particulièrement cette partie du programme que je suis à la recherche d'une explication (je n'undetsand pas pourquoi il fait (& 0x7F) et en multipliant par 256):

if ((j >= 40) && 
    (dht22_dat[4] == ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF))) { 
    float t, h; 
    h = (float)dht22_dat[0] * 256 + (float)dht22_dat[1]; 
    h /= 10; 
    t = (float)(dht22_dat[2] & 0x7F)* 256 + (float)dht22_dat[3]; 
    t /= 10.0; 
    if ((dht22_dat[2] & 0x80) != 0) t *= -1; 
    sicher = 0;  
    dsicher = false; 
    temp = t; 
printf("Humidity = %.2f %% Temperature = %.2f *C \n", h, t); 

Je serais plus reconnaissant si quelqu'un pouvait commenter le code ci-dessus. se trouve le programme complet ici: http://pastebin.com/zkaTjQiS

Répondre

1

Comme vous pouvez le voir dans le DHT22 datasheet, le capteur, lorsqu'on lui a demandé, horloges sur 40 bits de données sur 1 fils. Les 16 premiers bits codent l'humidité relative comme dixièmes de pourcentage, les 16 bits suivants la température comme les dixièmes de degrés Celsius, et les 8 derniers sont une somme de contrôle. Tout ce qui se passe dans l'ordre MSBit, et les numéros dans les 5 octets transcrits sont donc codés en big endian

En outre, comme vous pouvez également le voir dans la feuille de données, les données de température sont codées en tant que magnitude signée plutôt que complément à deux.

Alors:

if ((j >= 40) && 
    (dht22_dat[4] == ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF))) { 

vérifie que 40 bits ont été cadencés à et que la somme de contrôle est valide.

h = (float)dht22_dat[0] * 256 + (float)dht22_dat[1]; 
h /= 10; 

rend l'utilisation inutile de l'arithmétique à virgule flottante afin de maintenir l'humidité pour cent plutôt que promille, mais à part ça juste déplace l'octet supérieur en valeur à sa juste place et ajoute la partie inférieure à cela. Vous pouvez aussi bien écrire

h = dht22_dat[0] << 8 | dht22_dat[1]; 

si vous préférez cette notation; le point est de faire des deux octets individuels la valeur entière de 16 bits qu'ils représentent. Pensez à ceci, si vous voulez, comme si le capteur vous avait donné deux chiffres décimaux 2 et 3, et vous deviez en reconstruire la valeur. Si vous saviez 2 être le chiffre le plus significatif, vous devez calculer 2 * 10 + 3 pour obtenir la valeur réelle de 23. Le même principe s'applique ici, sauf que le capteur ne vous a pas donné de chiffres décimaux, mais 256-ary, et ainsi de a * 10 + b vous calculez a * 256 + b.

De même,

t = (float)(dht22_dat[2] & 0x7F)* 256 + (float)dht22_dat[3]; 
t /= 10.0; 

assemble la partie inférieure 7 bit de l'octet supérieur et l'octet inférieur à la valeur absolue de la température. L'isolation du plus petit octet de l'octet supérieur est nécessaire car son bit le plus élevé est un bit de signe utilisé pour représenter les températures négatives et non une partie de la valeur absolue de la température.

Puis

if ((dht22_dat[2] & 0x80) != 0) t *= -1; 

vérifie si ce bit de signe est défini et ajuste le signe du résultat si elle est, et

printf("Humidity = %.2f %% Temperature = %.2f *C \n", h, t); 

imprime les résultats de la transformation.

+0

Votre explication m'a aidé, merci – peterretief