Comments (10)
Maybe useful for somebody in the future. I had similar issues when trying to compensate for the environment using the DHT22 with sudden eCO2 values of > 1000. Turns out the DHT22 sensor sends some null
values for temperature and humidity, before sending correct data. Calculating the compensation from null
results in a very large number, which ultimately messes up the readings of the CCS811. By making sure temperature and humidity are not null
before setting the environment data, I was able to get correct (or at least correct looking results).
uint16_t humidity_to_compensation(float humidity) {
// Humidity is stored as an unsigned 16 bits in 1/512%RH.
// The default value is 50% = 0x64, 0x00.
// As an example 48.5% humidity would be 0x61, 0x00.
// return uint16(50 * 512); // Default value
return uint16(humidity * 512);
}
uint16_t temperature_to_compensation(float temperature) {
// Temperature is stored as an unsigned 16 bits integer in 1/512 degrees;
// there is an offset: 0 maps to -25°C. The default value is 25°C = 0x64, 0x00.
// As an example 23.5% temperature would be 0x61, 0x00.
// return uint16(50 * 512); // Default value
return uint16((temperature + 25) * 512);
}
void compensate_for_environment() {
float temperature, humidity;
temperature = dht.readTemperature();
humidity = dht.readHumidity();
// Make sure temperature and humidity are set,
// otherwise CCS sensor values will be all over the place.
if (!(isnan(temperature) | isnan(humidity))) {
ccs811.set_envdata(temperature_to_compensation(temperature), humidity_to_compensation(humidity));
}
}
from ccs811.
Hi, my ccs811 library has two set_envdata methods. I quote the header file:
// Writes t and h to ENV_DATA (see datasheet for format). Returns false on I2C problems.
bool set_envdata(uint16_t t, uint16_t h);
// Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems.
bool set_envdata210(uint16_t t, uint16_t h);
So the plain set_envdata()
uses a format native to the chip, and you need to look that up in the datasheet.
The other one set_envdata210
uses the format from the ens210, which is a temperature humidity chip from the same manufacturer.
There is no general set_envdata
using floats. I dislike float for small embedded microcontrollers :-(
from ccs811.
Having a look at the datasheet it says Temperature is stored as an unsigned 16 bits integer in 1/512 degrees
. Will need to do some conversion I guess. If I figure this out I'll post up the results incase someone else runs into the same problem
from ccs811.
It also says "there is an offset: 0 maps to -25°C."
So, this is my guess; didn't test it!
float TinC;
unsigned int Tfor811 = (TinC+25) * 512;
from ccs811.
Have played around in the code and did a bit of research into what Adafruit and SparkFun have done and come up with the following chunk:
double avgTemp = (temp1 + temp2 + temp3) / 3;
int avgHum = (hum1 + hum2) / 2;
float fract = modf(avgTemp, &avgTemp);
uint16_t tempHIGH = (((uint16_t)avgTemp + 25) << 9);
uint16_t tempLOW = ((uint16_t)(fract / 0.001953125) & 0x1FF);
uint16_t tempCONVERT = (tempHIGH | tempLOW);
uint16_t humCONVERT = avgHum << 1 | 0x00;
ccs811.set_envdata(tempCONVERT, humCONVERT);
this could very well be written as a function if someone was so inclined, but for my purposed doing the quick conversion before was all I needed :)
Thanks for the help Maarten, great work on the library :D
from ccs811.
I believe your code is NOT correct. For negative numbers, the fraction (after modf) is negative!
To fix that, add the 25 before modf.
Secondly, the code is obscuring that you do two times the same (namely *512 is first written as <<9 and then as /0.001953125).
Note that 0≤fract<1, so 0≤fract*512<512 so the &0x1ff is not needed.
So I think you need this.
fract = modf(avgTemp+25, &intg);
uint16_t tempHIGH = (uint16_t)(intg*512);
uint16_t tempLOW = (uint16_t)(fract*512);
uint16_t tempCONVERT = (tempHIGH | tempLOW);
Did you check ... I think this gives the same as
uint16_t tempCONVERT = (avgTemp+25) * 512;
If this is not the same, please let me know with an example.
from ccs811.
I leave this issue open; the functions look good, but I didn't implement them yet.
from ccs811.
uint16_t humidity_to_compensation(float humidity) { // Humidity is stored as an unsigned 16 bits in 1/512%RH. // The default value is 50% = 0x64, 0x00. // As an example 48.5% humidity would be 0x61, 0x00. // return uint16(50 * 512); // Default value return uint16(humidity * 512); } uint16_t temperature_to_compensation(float temperature) { // Temperature is stored as an unsigned 16 bits integer in 1/512 degrees; // there is an offset: 0 maps to -25°C. The default value is 25°C = 0x64, 0x00. // As an example 23.5% temperature would be 0x61, 0x00. // return uint16(50 * 512); // Default value return uint16((temperature + 25) * 512); } void compensate_for_environment() { float temperature, humidity; temperature = dht.readTemperature(); humidity = dht.readHumidity(); // Make sure temperature and humidity are set, // otherwise CCS sensor values will be all over the place. if (!(isnan(temperature) | isnan(humidity))) { ccs811.set_envdata(temperature_to_compensation(temperature), humidity_to_compensation(humidity)); } }
Thanks for this, i am using a DTH22 also and was looking for the right conversion to set the environment data. Readings looking good. Thanks for posting. maybe move the conversion to the right format into the CSS library so only have to pass the correct temp and humidity values to make it easy for anyone else in the future.
from ccs811.
I double checked the conversions and I agree with janjagusch
return uint16(50 * 512); // Default value 0x64
return uint16((25+25) * 512); // Default value 0x64
Merge it.
from ccs811.
Merged
from ccs811.
Related Issues (20)
- Esp32 Deepsleep confusion HOT 1
- Problem with CCS811 version HOT 1
- CCS811 firmware demoted to version 1.1.0 HOT 3
- Seek help from CCS811
- begin() required before flash() ? HOT 2
- Self over-heating
- Having a simple questions about the CCS811 function when it comes to modes HOT 5
- [Question] Modes, Burn-In - Several Questions HOT 3
- ESP32 ERRO I2C HOT 2
- IC2 Error with nodemcu HOT 2
- LilyGo T5 V2.3 and cjmcu-8128. Unable to flash ccs811 HOT 3
- Sensor faulty or soldering issue? HOT 2
- Issues in CCS811 sensor reading HOT 2
- version checking functions have wrong comment, I think HOT 2
- Readings drift higher over time. HOT 3
- CCS811 Baseline Issues HOT 8
- My CCS811 from CJMCU does not works after flashing comleted. HOT 2
- Can it really be used for co2 monitoring? HOT 2
- C811 baseline HOT 2
- Firmware version not detected HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ccs811.