Skip to content

Commit

Permalink
Temperature fix (Firmware > 5.0)
Browse files Browse the repository at this point in the history
The temperature of the sensor for firmware versions greater than 5 has received a fix.

This changes have only been tested on the MHZ19C.

Please note:  older versions no longer offer a float argument for the getTemperature() function. Instead,  the value returned is in accordance with the data sheet. This is due to the float version being somewhat unreliable.

As a result, temperature values received in older library versions will see an increase by 2C as the offset used in the datasheet differed.

The firmware version (the major version) is obtained on initiation and used to determine which temperature code to run.

Please report any issues as there are many firmware versions and I have only two sensors.
  • Loading branch information
WifWaf committed Jul 28, 2022
1 parent b0f7fb1 commit 04a6f85
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 55 deletions.
61 changes: 17 additions & 44 deletions src/MHZ19.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ void MHZ19::begin(Stream &serial)
Serial.println("!ERROR: Initial communication errorCode recieved");
#endif
}

/* What FW version is the sensor running? */
char myVersion[4];
this->getVersion(myVersion);

/* Store the major version number (assumed to be less than 10) */
this->storage.settings.fw_ver = myVersion[1];
}

/*########################-Set Functions-##########################*/
Expand Down Expand Up @@ -197,61 +204,27 @@ float MHZ19::getTransmittance(bool force)
return 0;
}

float MHZ19::getTemperature(bool isFloat, bool force)
float MHZ19::getTemperature(bool force)
{
if(isFloat)
{
static byte baseTemp = 0;
static bool isSet = false;

if(!isSet)
{
provisioning(CO2LIM);
byte buff = (this->storage.responses.CO2LIM[4] - TEMP_ADJUST);

baseTemp = buff - (byte)getTemperatureOffset(true);
isSet = true;
}

if(force)
provisioning(CO2UNLIM);

if(this->errorCode == RESULT_OK || force == false)
{
float buff = baseTemp;
buff += getTemperatureOffset(false);
return buff;
}
}

else if(!isFloat)
if(this->storage.settings.fw_ver < 5)
{
if (force == true)
provisioning(CO2LIM);

if (this->errorCode == RESULT_OK || force == false)
return (this->storage.responses.CO2LIM[4] - TEMP_ADJUST);
}

return -273.15;
}

float MHZ19::getTemperatureOffset(bool force)
{
if (force == true)
provisioning(CO2UNLIM);
else
{
if (force == true)
provisioning(CO2UNLIM);

if (this->errorCode == RESULT_OK || force == false)
{
/* Value appears to be for CO2 offset (useful for deriving CO2 from raw?) */
/* Adjustments and calculations are based on observations of temp behavour */
float calc = (((this->storage.responses.CO2UNLIM[2] - 8) * 1500) + ((this->storage.responses.CO2UNLIM[3] * 100) * 1 / 17));
calc /= 100;
return calc;
if (this->errorCode == RESULT_OK)
return (float)(((int)this->storage.responses.CO2UNLIM[2] << 8) | this->storage.responses.CO2UNLIM[3]) / 100;
}

return -273.15;
}
return -273.15;
}

int MHZ19::getRange()
{
Expand Down
16 changes: 5 additions & 11 deletions src/MHZ19.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@
#endif

#define MHZ19_ERRORS 1 // Set to 0 to disable error prints

#define TEMP_ADJUST 38 // This is the value used to adjust the temeperature.
// Older datsheets use 40, however is likely incorrect.
#define TEMP_ADJUST 40 // This is the value used to adjust the temeperature.
#define TIMEOUT_PERIOD 500 // Time out period for response (ms)

#define DEFAULT_RANGE 2000 // For range function (sensor works best in this range)

#define MHZ19_DATA_LEN 9 // Data protocl length
#define MHZ19_DATA_LEN 9 // Data protocol length

// Command bytes -------------------------- //
#define MHZ19_ABC_PERIOD_OFF 0x00
Expand Down Expand Up @@ -73,8 +69,8 @@ class MHZ19
/* returns Raw CO2 value as a % of transmittance */ //<--- needs work to understand
float getTransmittance(bool force = true);

/* returns temperature using command 134 or 135 if isFloat = true */
float getTemperature(bool isFloat = false, bool force = true);
/* returns temperature using command 133 or 134 */
float getTemperature(bool force = true);

/* reads range using command 153 */
int getRange();
Expand Down Expand Up @@ -155,6 +151,7 @@ class MHZ19
bool filterCleared = true; // Additional flag set by setFiler() to store which mode was selected
bool printcomm = false; // Communication print options
bool _isDec = true; // Holds preferance for communication printing
uint8_t fw_ver = 0; // holds the major version of the firmware
} settings;

byte constructedCommand[MHZ19_DATA_LEN]; // holder for new commands which are to be sent
Expand All @@ -180,9 +177,6 @@ class MHZ19
/* generates a checksum for sending and verifying incoming data */
byte getCRC(byte inBytes[]);

/* Returns what appears to be an offset */ //<----- knowledgable people might have success using against the raw value
float getTemperatureOffset(bool force = true);

/* Sends commands to the sensor */
void write(byte toSend[]);

Expand Down

0 comments on commit 04a6f85

Please sign in to comment.