Dear Arduino-Enthusiasts,
My Introduction:
I am relatively new to Arduino and the Community and this is the first problem within a project I was not able to solve on my own within some weeks. I am trying to incroporate the Arduino in an univsersity project, where it will controll some sensors measuring CO2, relative humidity, temperature and pressure during air tight storage of grains. I am an agriculrural / environmental scientist and not a computer engineer, so programming unfortunately is not my background. I apologize if I should mix things up. I am trying to be as correct and precise as possible.
I hope the forum here will provide me the droids....uhm answers I am looking for.
Overview of the problem:
When reading out CO2 concentration via I2C from a Senseair CO2-Engine BLG (similar to CO2 Meter K33 BLG) the two bytes that should contain the data only are (in hex) 7F and FF. They do not change. All in all, I am reading four bytes: Status, Data, Checksum.
Statusbyte and Checksum appear to be okay, the output allways is (Hex): 21|7F|FF|9F .
Detailed problem, setup and code
I am having an Arduino Pro Mini 3.3V / 8 Mhz hooked up via FTDI to my computer.
The Senseair K33 BLG (diffusion, not the one with pump) is connected via I2C-
SDA goes to A4 and SCL to A5. Power supply is 5V and comes from external current (Arduino Uno 5V output).
The code is modified from the one supplied by Andrew Robinson, CO2 Meter <co2meter.com> (Thanks to you guys by the way, here is the original).
I think, most of the code is working. I have modified it for debugging reasons, so it will Serial.print() the buffer bytes that are received via Wire.read().
The Sensor is working, I get rather reliable data for RH and Temperature I have checked with an other sensor. Also, there is a status light within the K33 that blinks twice at the beginning of each measurment.
The wake up cycle seems to be working, the measurment cylce as well. Measurment of CO2, RH and temperature are coded in 3 separate functions.
Now comes the sequence that troubles me. This is the request for CO2 data within function double readCO2()
Wire.beginTransmission(K33); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ?? I have no clue what this one does
Wire.write(0x08); //Two bytes starting from 0x08 (high byte) and 0x09 (low byte). They contain the CO2 data
Wire.write(0x2A); //Checksum
Wire.endTransmission();
delay(50);
The addresses are taken from the CO2meter.com example and rechecked with 2 documentations. The draft one from Senseair (pdf via cdn.shopify.com) and the one from CO2meter.com, which is better (pdf via source.hacker.lu)
Afterwards the data from the sensor is read, the bytes are transformed and stored in int CO2_value:
Wire.requestFrom(K33, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++; }
CO2_value = 0;
CO2_value |= buffer[1] & 0xFF;
CO2_value = CO2_value << 8;
CO2_value |= buffer[2] & 0xFF;
To be honest, I don't really understand what is happening here. It is bitwise operation. From my understanding, the high byte and the low byte a transformed to an integer, which would be 2 bytes long.
Including the Serial.print() function for debugging and the functions for RH and temperature, this is what the serial monitor will show:
RH Data 21|B|5A|86
T Data 21|9|D7|1
CO2 Data 21|7F|FF|9F
RH: 29.06% | Temp: 25.19C | CO2: 32767ppm
I understand, that 32767 is the maximum value of an integer in a Pro Mini board and that this value is achieved from the above posted bitwise operators. Nevertheless, this does not solve my problem with the CO2 data, since the bytes that should contain the values do not change.
I also understand, that 0x7F is the address for "any sensor" and 0xFF the byte being sent for a response from the K33 to this address (see page 22 from the CO2meter.com documentation). What is the point in having these information in the bytes that should contain the CO2 data?
An option might be, that the RAM address I am using is wrong. I also tried (no particular reason, just trial and error) with 0x10 and 0x16, but both do not yield CO2 data. I understand, that the example from CO2meter.com used and Arduino Due which stores 4 byte in an integer, but I don't see any difference that would be making here.
I have no idea, where to continue from here on and would highly appreciate any idea or hint that could help!
For better understanding I'll attach the complete code.
Best regards and thanks for a discussion,
Simon
