user37970: 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);
}


user4143: 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);
}


user359: Wire.requestFrom(Temperature_Register_DATA, 1);

This should have the WeatherAddress as parameter instead of the register.
Wire.requestFrom(WeatherAddress, 1);


37970: <p>I'm currently learning I2C and having some issues displaying the correct temperature in the serial monitor.</p>

<p>I am using an Arduino Uno and an SI7021 temperature sensor from Sparkfun; here's <a href="https://cdn.sparkfun.com/datasheets/Sensors/Weather/Si7021.pdf" rel="nofollow noreferrer">the datasheet</a> I'm looking at.</p>

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

<p>Here's my code:</p>

<pre><code>// SparkFun Si7021 Humidity and Temperature Sensor
#include &lt;SparkFun_Si7021_Breakout_Library.h&gt;
#include &lt;Wire.h&gt;

//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() &lt;= 1) {
    tempf = Wire.read();
  }
  Serial.print("Temp: ");
  Serial.print(tempf);
  Serial.println("F, ");
  delay(1000);
}
</code></pre>
 4143: <p>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.</p>

<p>You need to use command 0xF3 for read with <em>no hold master mode</em> 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.</p>

<p>Also you need to read <em>two</em> bytes, not one:</p>

<pre><code>//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) &lt; 2) {
    if (millis() - start &gt; 2000) { // 2 second timeout
        break;
    }
}

if (Wire.available() &lt; 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 &lt;&lt; 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);
}
</code></pre>
 359: <pre><code>Wire.requestFrom(Temperature_Register_DATA, 1);
</code></pre>

<p>This should have the WeatherAddress as parameter instead of the register.</p>

<pre><code>Wire.requestFrom(WeatherAddress, 1);
</code></pre>
