products:flipper:si70_i2c_arduino

I2C Communication with a temperature/humidity sensor : SI7021


tags: flipper, arduino, si7021, I2C

This is an example code of I2C communication between a temperature/humidity sensor and the flipper board.

The temperature/humidity sensor in the example is a SI7021 .

The sensor is wired on I2C1 communication bus so we will use Wire1 instance (if we were using I2C0 it would have been Wire instance, see flipper arduino bus references ). The i2C address of the SI7021 is 0x40 (see datasheet ).

Following code has been modified from this source.

flipper_si7021.ino
/* Si7021 sensor reading <strong>without</strong> library
 *  Datasheet:      https://www.silabs.com/documents/public/data-sheets/Si7021-A20.pdf
 */
 /******************************I2C COMMAND TABLE*****************************
  * Measure Relative Humidity, Hold Master Mode         0xE5
  * Measure Relative Humidity, No Hold Master Mode      0xF5 
  * Measure Temperature, Hold Master Mode               0xE3
  * Measure Temperature, No Hold Master Mode            0xF3
  * Read Temperature Value from Previous RH Measurement 0xE0
  * Reset                                               0xFE  
  * Write RH/T User Register 1                          0xE6
  * Read RH/T User Register 1                           0xE7
  * Write Heater Control Register                       0x51
  * Read Heater Control Register                        0x11
  * Read Electronic ID 1st Byte                         0xFA 0x0F
  * Read Electronic ID 2nd Byte                         0xFC 0xC9
  * Read Firmware Revision                              0x84 0xB8
  * 
  * source datasheet
  */
 
// This library allows you to communicate with I2C / TWI devices.
 
# include <Wire.h>
 
// SI7021 I2C address is 0x40(64)
 
# define si7021Addr 0x40
 
// function for reading values into a array of unsigned int data[2]
// from the Si7021 with a specific i2c address si7021Addr=0x40
// with one of the commands listed above. Function body at the end of this sketch
void getSiData(unsigned int *_ret_data, byte _i2c_command);
 
void setup()
{
 
 //enabling VDD_SW power rail to give 5V source to the daughter board
 pinMode(SW_VDD_EN, OUTPUT);
 digitalWrite(SW_VDD_EN,HIGH);
 //enabling 5V_sensor power rail to switch on the sensor
 pinMode(EXP_36, OUTPUT);
 digitalWrite(EXP_36,HIGH);
 //enabling 3V3_SW power rail to pull the I2C bus up via the 10K resistors
 pinMode(SW_3V3_EN, OUTPUT);
 digitalWrite(SW_3V3_EN,HIGH);
 //wait for the power sources to be turned on
 delay(1000);
  // Initiate Wire1 and join the I2C1 bus
  Wire1.begin();
  Serial.begin(115200);
  //reset sensor by sending 0xFE command to the Si7021 address
  Wire1.beginTransmission(si7021Addr);
  Wire1.write(0xFE); // Write reset command
  Wire1.endTransmission();
  delay(15); // Default = 15ms
 
}
 
void loop(){
 
  //sensor returns 2 bytes via I2C. It will be converted to temperature or humidity later
  unsigned int data[2];
  //Send humidity measurement command and get response into the array 'data'
  getSiData(data, 0xE5);
  // Convert the data
  float humidity  = ((data[0] * 256.0) + data[1]);
  humidity = ((125 * humidity) / 65536.0) - 6;
  // Send temperature measurement command
  getSiData(data, 0xE3);
  /* re-use temperature already measured by humidity measurement some milliseconds before command -> E0
    *getSiData(data, 0xE0); 
    *
    *However, does not report valid results
    *
    *Datasheet: 
    *Each time a relative humidity measurement is made a temperature measurement is also made for the purposes of
    *temperature  compensation  of  the  relative  humidity  measurement.  If  the  temperature  value  is  required,  
    *it  can  be read  using  command  0xE0;  this  avoids  having  to  perform  a  second  temperature  measurement.  
    *The  measure temperature  commands 0xE3  and  0xF3  will  perform  a  temperature measurement  and  return  the  
    *measurement value, command 0xE0 does not perform a measurement but returns the temperature value measured during the
    *relative humidity measurement. 
  */ 
  // Convert the data
  float temp  = ((data[0] * 256.0) + data[1]);
  float celsTemp = ((175.72 * temp) / 65536.0) - 46.85;
  float fahrTemp = celsTemp * 1.8 + 32;
  // Output data to serial monitor
  Serial.print("Humidity : ");
  Serial.print(humidity);
  Serial.println(" % RH");
  Serial.print("Celsius : ");
  Serial.print(celsTemp);
  Serial.println(" C");
  delay(10000);
}
 
 
 
void getSiData(unsigned int *_ret_data, byte _i2c_command)
{
 
  // start i2c communication 
  Wire1.beginTransmission(si7021Addr);
  //send i2c command to sensor
  Wire1.write(_i2c_command);
  // we are done with our transmission...close i2c communication
  Wire1.endTransmission();
  delay(85);
  // Request 2 bytes of data
  Wire1.requestFrom(si7021Addr, 2);
  // Read 2 bytes of data and save it to _ret_data which points to 'data[2]'
  if(Wire1.available() == 2)
  {
    _ret_data[0] = Wire1.read();
    _ret_data[1] = Wire1.read();
  }
  • products/flipper/si70_i2c_arduino.txt
  • Last modified: 2021/04/04 13:12
  • by manu