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 :

Capteur AHT20 température et humidité sans librairie et sans utilisation du type float


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut Capteur AHT20 température et humidité sans librairie et sans utilisation du type float
    Bonjour,

    Voici mon code pour lire l'humidité et la température d'un capteur AHT20 sans libraire et sans utiliser de float

    Compilé tout seul, il prend 6256 octets de flash et 404 octets de RAM

    Mais quand je retire les fonctions Serial.XXX() et que j'intègre ce code à un projet existant qui utilise déjà <Wire.h> et sprintf_P(), alors cela ne me coûte que 690 octets de flash et 4 octets de RAM en plus.
    A peine plus que ce que j'ai économisé en optimisant le code pour piloter la RTC I2C

    Autre avantage : on utilise pas le type float (consommateur de ressources et compliqué à gérer avec Arduino)

    Le capteur renvoi les données sur 20 bits mais c'est beaucoup trop étant donné sa précision :
    +/- 2% pour l'hygrométrie relative (sur une échelle de valeurs allant de 0% à 100%)
    +/- 0,3°C pour la température (sur une échelle de valeurs allant de -50°C à 150°C)

    Etant donné la précision du capteur d'humidité un seul octet non signé suffit pour stocker une valeur de 0 à 100

    La température en dixièmes de degrés (multipliée par dix) est stockée dans un entier signé (il suffit d'en tenir compte dans les calculs et pour l'affichage)

    Le capteur est théoriquement capable de renvoyer des températures de -50°C à 150°C mais les composants électroniques cesseront de fonctionner avant que ces températures soient atteintes

    Ce capteur est plutôt précis et il est assez réactif, sauf quand on passe d'une atmosphère humide à une atmosphère sèche, dans ce sens là, le temps de réponse est plus long (il faut attendre 30 secondes mais c'est déjà assez court)

    On peut l'alimenter en 5V ou en 3.3V, je l'ai alimenté en 3.3V car il partage le bus I2C avec une RTC alimentée en 3.3V

    J'ai laissé en commentaires la fonction qui retourne les valeurs en float.

    A bientôt

    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
    #include <Wire.h>
    #define AHT20_ADDRESS 0x38
     
    void setup() {
        Serial.begin(115200);
        Serial.println(F("ATH20 TEST"));
        ATH20_begin();
    	delay(40); // Needed, if no, first humidity values are bad
    }
     
    void loop() {
        //float humi, temp;
        //if(ATH20_getSensor(&humi, &temp)) {
        byte humi;
    	int temp;
    	int temp10;
    	char Buff[50];
        if(ATH20_getSensor_B(&humi, &temp)) {
    		temp10 = temp/10;
    		sprintf_P(Buff, PSTR("Humidity: %d Temperature %d.%d"),humi,temp10,(temp-temp10*10));
            Serial.println(Buff);
        } else {
            Serial.println(F("ERROR"));
        }
        delay(100);
    }
     
    void ATH20_begin() {
        Wire.begin();
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xBE);
        Wire.endTransmission();    // stop transmitting
    }
     
    bool ATH20_startSensor() {
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xac);
        Wire.write(0x33);
        Wire.write(0x00);
        Wire.endTransmission();    // stop transmitting
        unsigned long timer_s = millis();
        while(1) {
            if(millis()-timer_s > 200) return false;        // time out
            Wire.requestFrom(AHT20_ADDRESS, 1);
    		while(Wire.available()) {
                unsigned char c = Wire.read();
                if(c&0x80 != 0)return true;      // busy
            }
            delay(20);
        }
    }
     
    bool ATH20_getSensor_B(byte *h, int *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80)return false;
        int __humi; // According to humidity sensor accurate, one byte for humidity is OK
    	__humi = 100 * str[1] / 255;
    	*h = (byte) __humi; 
        long __temp; // According to temperature sensor accurate, 14 bits is OK
        __temp = str[3]&0x0f;
        __temp <<=8;
        __temp += str[4];
        __temp <<=2;
        __temp += str[5] >> 6;
    	// temperature      = __temp / 16384.0 * 200.0 - 50.0;
    	//                  = __temp / 81.92 - 50.0;
    	// temperature * 10 = 10 * __temp / 81.92 - 500; // According to sensor accurate, we return temp*10 as int (0.1°C step)
    	__temp = 1000 * __temp / 8192 - 500;
    	*t = (int) __temp;
        return true;
    }
     
    /*
    bool ATH20_getSensor(float *h, float *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80)return false;
        unsigned long __humi = 0;
        unsigned long __temp = 0;
        __humi = str[1];
        __humi <<= 8;
        __humi += str[2];
        __humi <<= 4;
        __humi += str[3] >> 4;
    	//            str[1]   str[2] str[3] 
    	// __humi =  76543210 76543210 7654  (20 bits)
    	// 100%   =  11111111 11111111 1111 
    	//   0%   =  00000000 00000000 0000
        *h = (float)__humi/1048576.0;
        __temp = str[3]&0x0f;
        __temp <<=8;
        __temp += str[4];
        __temp <<=8;
        __temp += str[5];
    	//          str[3]  str[4]   str[5] 
    	// __temp =  3210  76543210 76543210  (20 bits)
    	// 150°C  =  1111  11111111 11111111
    	// -50°C  =  0000  00000000 00000000
        *t = (float)__temp/1048576.0*200.0-50.0;
        return true;
    }
    */

  2. #2
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    On peut faire encore mieux

    12 bits suffisent pour la température

    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
    #include <Wire.h>
    #define AHT20_ADDRESS 0x38
     
    void setup() {
        Serial.begin(115200);
        Serial.println(F("ATH20 TEST"));
        ATH20_begin();
    	delay(40); // Needed, if no, first humidity values are bad
    }
     
    void loop() {
        //float humi, temp;
        //if(ATH20_getSensor(&humi, &temp)) {
        byte humi;
    	int temp;
    	int temp10;
    	char Buff[50];
        if(ATH20_getSensor_B(&humi, &temp)) {
    		temp10 = temp/10;
    		sprintf_P(Buff, PSTR("Humidity: %d Temperature %d.%d"),humi,temp10,(temp-temp10*10));
            Serial.println(Buff);
        } else {
            Serial.println(F("ERROR"));
        }
        delay(100);
    }
     
    void ATH20_begin() {
        Wire.begin();
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xBE);
        Wire.endTransmission();    // stop transmitting
    }
     
    bool ATH20_startSensor() {
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xac);
        Wire.write(0x33);
        Wire.write(0x00);
        Wire.endTransmission();    // stop transmitting
        unsigned long timer_s = millis();
        while(1) {
            if(millis()-timer_s > 200) return false;        // time out
            Wire.requestFrom(AHT20_ADDRESS, 1);
    		while(Wire.available()) {
                unsigned char c = Wire.read();
                if(c&0x80 != 0)return true;      // busy
            }
            delay(20);
        }
    }
     
    bool ATH20_getSensor_B(byte *h, int *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80) return false;
        int val;
    	// According to humidity sensor accurate, one byte for humidity is OK
    	val = 100 * str[1] / 255;
    	*h = val; 
    	// According to temperature sensor accurate, 12 bits is OK
        val = str[3]&0x0f;
        val <<=8;
        val += str[4];
    	// temperature      = __temp / 4096.0 * 200.0 - 50.0;
    	//                  = __temp / 20.48 - 50.0;
    	// temperature * 10 = 10 * __temp / 20.48 - 500; // According to sensor accurate, we return temp*10 as int (0.1°C step)
    	//long __temp = (long)val * 125 / 256 - 500;
    	//*t = (int) __temp;
    	*t = (long)val * 125 / 256 - 500;
        return true;
    }
     
    /*
    bool ATH20_getSensor(float *h, float *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80)return false;
        unsigned long __humi = 0;
        unsigned long __temp = 0;
        __humi = str[1];
        __humi <<= 8;
        __humi += str[2];
        __humi <<= 4;
        __humi += str[3] >> 4;
    	//            str[1]   str[2] str[3] 
    	// __humi =  76543210 76543210 7654  (20 bits)
    	// 100%   =  11111111 11111111 1111 
    	//   0%   =  00000000 00000000 0000
        *h = (float)__humi/1048576.0;
        __temp = str[3]&0x0f;
        __temp <<=8;
        __temp += str[4];
        __temp <<=8;
        __temp += str[5];
    	//          str[3]  str[4]   str[5] 
    	// __temp =  3210  76543210 76543210  (20 bits)
    	// 150°C  =  1111  11111111 11111111
    	// -50°C  =  0000  00000000 00000000
        *t = (float)__temp/1048576.0*200.0-50.0;
        return true;
    }
    */

  3. #3
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    Correction d'un bug dans la ligne d'affichage

    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
    #include <Wire.h>
    #define AHT20_ADDRESS 0x38
     
    void setup() {
        Serial.begin(115200);
        Serial.println(F("ATH20 TEST"));
        ATH20_begin();
    	delay(40); // Needed, if no, first humidity values are bad
    }
     
    void loop() {
        //float humi, temp;
        //if(ATH20_getSensor(&humi, &temp)) {
        byte humi;
    	int temp;
    	int temp10;
    	int temp01;
    	char Buff[50];
        if(ATH20_getSensor_B(&humi, &temp)) {
    		temp10 = temp/10;
    		temp01 = temp-temp10*10;
    		if (temp<0) temp01 *= -1;
    		sprintf_P(Buff, PSTR("Humidity: %d Temperature %d.%d"),humi,temp10,temp01);
            Serial.println(Buff);
        } else {
            Serial.println(F("ERROR"));
        }
        delay(100);
    }
     
    void ATH20_begin() {
        Wire.begin();
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xBE);
        Wire.endTransmission();    // stop transmitting
    }
     
    bool ATH20_startSensor() {
        Wire.beginTransmission(AHT20_ADDRESS); // transmit to device #8
        Wire.write(0xac);
        Wire.write(0x33);
        Wire.write(0x00);
        Wire.endTransmission();    // stop transmitting
        unsigned long timer_s = millis();
        while(1) {
            if(millis()-timer_s > 200) return false;        // time out
            Wire.requestFrom(AHT20_ADDRESS, 1);
    		while(Wire.available()) {
                unsigned char c = Wire.read();
                if(c&0x80 != 0)return true;      // busy
            }
            delay(20);
        }
    }
     
    bool ATH20_getSensor_B(byte *h, int *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80) return false;
        int val;
    	// According to humidity sensor accurate, one byte for humidity is OK
    	val = 100 * str[1] / 255;
    	*h = val; 
    	// According to temperature sensor accurate, 12 bits is OK
        val = str[3]&0x0f;
        val <<=8;
        val += str[4];
    	// temperature      = __temp / 4096.0 * 200.0 - 50.0;
    	//                  = __temp / 20.48 - 50.0;
    	// temperature * 10 = 10 * __temp / 20.48 - 500; // According to sensor accurate, we return temp*10 as int (0.1°C step)
    	//long __temp = (long)val * 125 / 256 - 500;
    	//*t = (int) __temp;
    	*t = (long)val * 125 / 256 - 500;
        return true;
    }
     
    /*
    bool ATH20_getSensor(float *h, float *t) {
        ATH20_startSensor();
        Wire.requestFrom(AHT20_ADDRESS, 6);
        unsigned char str[6];
        int index = 0;
        while (Wire.available()) {
            str[index++] = Wire.read(); // receive a byte as character
        }
        if(str[0] & 0x80)return false;
        unsigned long __humi = 0;
        unsigned long __temp = 0;
        __humi = str[1];
        __humi <<= 8;
        __humi += str[2];
        __humi <<= 4;
        __humi += str[3] >> 4;
    	//            str[1]   str[2] str[3] 
    	// __humi =  76543210 76543210 7654  (20 bits)
    	// 100%   =  11111111 11111111 1111 
    	//   0%   =  00000000 00000000 0000
        *h = (float)__humi/1048576.0;
        __temp = str[3]&0x0f;
        __temp <<=8;
        __temp += str[4];
        __temp <<=8;
        __temp += str[5];
    	//          str[3]  str[4]   str[5] 
    	// __temp =  3210  76543210 76543210  (20 bits)
    	// 150°C  =  1111  11111111 11111111
    	// -50°C  =  0000  00000000 00000000
        *t = (float)__temp/1048576.0*200.0-50.0;
        return true;
    }
    */

Discussions similaires

  1. coder un capteur de température et humidité en c++
    Par azSpeed dans le forum Raspberry Pi
    Réponses: 1
    Dernier message: 06/02/2018, 09h44
  2. Réponses: 1
    Dernier message: 01/08/2015, 10h57
  3. Réponses: 7
    Dernier message: 18/01/2013, 15h16
  4. [16F877] Capteur de température LM et EEPROM externe 24C512
    Par costarimes dans le forum Autres architectures
    Réponses: 0
    Dernier message: 30/03/2009, 02h53
  5. température processeur forte sans raison
    Par jojodu31 dans le forum Composants
    Réponses: 6
    Dernier message: 03/04/2008, 09h33

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