I use the setup of my project Measuring temperature and humidity with Particle Photon. For analyzing the I2C sensor data I use the Scanalogic-2 EDU KIT with the Scanastudio software. I use Version 2.3 of this software. V2.4 is available in beta but worked only in demo mode.
Follow the setup instructions of the project Measuring temperature and humidity with Particle Photon and connect the Logic Analyzer:
- CH1 to the Particle DO pin (SDA)
- CH2 to the Particle D1 pin (SCL)
- GND to ground.
I used some female-male jumper wires instead of the hook probes delivered with the Scanalogic-2 EDU Kit for the connection.
I2C data transferTo understand the information provided by the logic analyzer you need to know the addresses of the sensor and the codes for the commands.
You find this information in the file Adafruit_Si7021.h in the Particle IDE (click on libraries and search for Adafruit_Si7021). In this file you find the addresses of the sensor and all commands:
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define SI7021_DEFAULT_ADDRESS (0x40)
#define SI7021_MEASRH_HOLD_CMD 0xE5
#define SI7021_MEASRH_NOHOLD_CMD 0xF5
#define SI7021_MEASTEMP_HOLD_CMD 0xE3
#define SI7021_MEASTEMP_NOHOLD_CMD 0xF3
...
In the implementation in Adafruit_Si7021.cpp you find the commands used. For reading the temperature:
float Adafruit_Si7021::readTemperature(void) {
Wire.beginTransmission(_i2caddr);
Wire.write((uint8_t)SI7021_MEASTEMP_NOHOLD_CMD);
...
And for reading the humidity:
float Adafruit_Si7021::readHumidity(void) {
Wire.beginTransmission(_i2caddr);
Wire.write((uint8_t)SI7021_MEASRH_NOHOLD_CMD);
...
So we are looking for the write commands 0xF3 (temperature) or 0xF5 (humidity).
Prepare the measurementMeasurement sequence
The Si7021 datasheet (p. 20) shows the sequence to perform a measurement and read back result.
Timing considerations
According to the Implementation of the function readHumidity in Adafruit_Si7021.cpp there is a delay of 25ms between writing the command to the sensor and reading the results.
float Adafruit_Si7021::readHumidity(void) {
Wire.beginTransmission(_i2caddr);
Wire.write((uint8_t)SI7021_MEASRH_NOHOLD_CMD);
Wire.endTransmission(false);
delay(25);
...
So you have to choose the sampling rate to have a total capture time of more than 25ms. I chose 250 kHz which resulted in a capture time of approx. 40 ms with a resolution of 4 microseconds. I was able to capture one whole measurement and read back cycle (and the following write command for the next measurement).
Setting the triggerChoose a trigger on rising edge and a position of approx. 10%. Click on decoder in the menu bar to add the I2C decoder (hex format).
Start measurementTo start the measurement click on the start button. Because there is a delay of 30 seconds between measurements you have to wait up to 30 seconds till the next reading triggers the recording.
void loop() {
h = sensor.readHumidity();
t = sensor.readTemperature();
// Publish data
String temperature = String(t);
String humidity = String(h);
temperature = temperature.format("%1.2f", t);
Particle.publish("temperature", temperature, PRIVATE);
delay(30000);
Particle.publish("humidity", humidity, PRIVATE);
delay(30000);
}
Logic Analyzer measurementsThe following figure shows the frame with the writing of the command 0xF5 - read humidity - to device with address 0x40.
The next figure shows the frames with the reading of the measurement from device with address 0x40 with the data 0x75 0xAA 0x6B.
Click on packets to get the packets view of the frames:
You see three frames:
- the command to the sensor (0x40) to read the humidity (0xF5)
- the read back from the sensor (0x40) with the humidity measurement data
- the command to the sensor (0x40) to read the temperature (0xF3)
You can calculate the relative humidity (RH) according to the following formula (see datasheet, p. 21).
%RH is the resulting relative humidity value, RH_Code is the 16-bit word returned by the Si7021. This calculation is implemented in Adafruit_Si7021.cpp:
...
uint16_t hum = Wire.read();
hum <<= 8;
hum |= Wire.read();
uint8_t chxsum = Wire.read();
float humidity = hum;
humidity *= 125;
humidity /= 65536;
humidity -= 6;
return humidity;
...
Using the first two bytes of the data 0x75 0xAA calculate the value of RH_Code:
RH_Code = 0x75 * 0xFF + 0xAA = 117 * 256 + 170 = 30,122
Now calculate RH (Relative Humidity):
( (117 * 256 + 170) * 125 ) / 65536 - 6 = 51.453156
ValidationI used ThingSpeak to store the measurement data (see Measuring temperature and humidity with Particle Photon). So we can compare the data for validation:
The results match.
Comments