2

I'm currently learning I2C and having some issues displaying the correct temperature in the serial monitor.

I am using an Arduino Uno and an SI7021 temperature sensor from Sparkfun; here's the datasheet I'm looking at.

The datasheet says that its device address is 0x40 and the temperature register is 0xF3 (maybe I am looking at this wrong?). However when I print the result to the screen it reads -1 degrees F.

Here's my code:

// SparkFun Si7021 Humidity and Temperature Sensor
#include <SparkFun_Si7021_Breakout_Library.h>
#include <Wire.h>

//Weather sensor slave address
int WeatherAddress = 0x40;

#define Temperature_Register_DATA 0xF3

//initialize humidity and temperature variables
float humidity = 0;
float tempf = 0;

//create a sensor from the Weather library
Weather temp_rh_sensor;

void setup() {
  Serial.begin(9600);
  //create wire object
  Wire.begin();
  //begin weather sensor
  temp_rh_sensor.begin();
}

void loop() {
  //begin transmission to weather sensor
  Wire.beginTransmission(WeatherAddress);
  //ask particular register for data (temperature register)
  Wire.write(Temperature_Register_DATA);
  Wire.endTransmission();
  //request the transmitted single byte from the register
  Wire.requestFrom(Temperature_Register_DATA, 1);
  if(Wire.available() <= 1) {
    tempf = Wire.read();
  }
  Serial.print("Temp: ");
  Serial.print(tempf);
  Serial.println("F, ");
  delay(1000);
}
1
  • 2
    You have connected a 3.3V sensor to a 5V Arduino Uno via the sda and scl lines ? Did you use a i2c voltage level shifter ? Did you connect 5V or 3.3V to the + connection of the module ? The sensor could be broken by now.
    – Jot
    Sep 7, 2017 at 23:59

3 Answers 3

1

Reading this sensor is a little more involved. You don't just select a register and then read the value from it. Instead you send it a command to begin a read of a parameter (e.g., temperature) and then you need to wait for it to perform that command before you can read the result.

You need to use command 0xF3 for read with no hold master mode which will return NACK from a read request if the command isn't completed (which you are doing) - you then need to keep retrying the read until you don't get a NACK.

Also you need to read two bytes, not one:

//begin transmission to weather sensor
Wire.beginTransmission(WeatherAddress);

//ask particular register for data (temperature register)
Wire.write(Temperature_Register_DATA);

Wire.endTransmission();


// Keep retrying the read until it succeeds, or times out
uint32_t start = millis();
while (Wire.requestFrom(WeatherAddress, 2) < 2) {
    if (millis() - start > 2000) { // 2 second timeout
        break;
    }
}

if (Wire.available() < 2) { // It timed out
    Serial.println("Timeout");
} else {
    // Read the two bytes
    uint8_t hi = Wire.read();
    uint8_t lo = Wire.read();

    // and combine them into a 16 bit value
    uint16_t temp = (hi << 8) | lo;

    // Now convert the returned value into a real temperature:
    tempf = ((175.25 * temp) / 65536.0) - 46.85
    Serial.print("Temperature: ");
    Serial.println(tempf);
}
2
Wire.requestFrom(Temperature_Register_DATA, 1);

This should have the WeatherAddress as parameter instead of the register.

Wire.requestFrom(WeatherAddress, 1);
1
  • 1
    Hi thanks for the response, I just gave this a shot but it is still spitting out a -1 for the temperature. Does this mean I'm just accessing the wrong register inside the sensor? Sep 7, 2017 at 18:53
0

The datasheet says that its device address is: 0x40

there is no standard notation on how to code i2c addresses - it all depends on how the particular library is coded. In this case, try 0x80 and 0x40 and see which one works.

1
  • 1
    The datasheet is quite clear... "The 7-bit base slave address is 0x40". It even goes so far as to depict it in an entire byte showing the bits of the address (1000000) and the RW bit.
    – Majenko
    Sep 7, 2017 at 23:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.