i've been following some tutorials of how the I2C bus works and have a small question of understanding.
So in this tutorial he is reading out the temperature of the sensor. The manual shows that it seems to be stored in 2 different adresses TEMP_OUT_H and TEMP_OUT_L (0x41 & 0x42):
In the tutorial he only adresses the "0x41" register at the beginning, but for some reason is able to read out 2 temperature bytes. How is this possible, if he never adressed "0x42"?
Also, what is the purpose of shifting the bits afterwards?
int16_t raw_temp = temp_h << 8 | temp_l;
The code from the tutorial:
void loop(){
Wire.beginTransmission(0x68); // Begin I2C transaction
Wire.write(0x41);// Register to read the data from
Wire.endTransmission();//End the write transaction
Wire.requestFrom(0x68, 2);//Read 2 bytes from the MPU6050
uint8_t temp_h = Wire.read();//Read the high byte
uint8_t temp_l = Wire.read();//Read the low byte
/*
Calculate the raw tempterature
Shift the high byte, 8 bits to the left
*/
int16_t raw_temp = temp_h << 8 | temp_l;
/*
Convert the raw temperature into a "real" value
*/
float temperature = (raw_temp/340.0)+36.53;
Serial.print("Current Temperature: ");
Serial.println(temperature);
delay(1000);
If you start a question as a "quick question", then those get the most replies We will see.
The term "address" is confusing.
On the I2C bus, every I2C device has a "I2C address".
A sensor has often registers, the register is selected by the "register address" or "register pointer", or "register index".
Most I2C devices allows that multiple bytes are read. The I2C device increments the "register address" after every read byte. Sometimes only 2 or 4 bytes can be read sequentially, but often there is no limit, you can just go on reading bytes in the same I2C session.
The sensor has data for TEMP_OUT, a 16 bit value. That has to be re-constructed in the Arduino to get that same 16 bit value.
The sensor chip automatically increases the internal register address to 0x42 for the second byte. If 3 bytes were to be requested, it would increase to 0x43 for the third byte and so on.
Most register-based I2C chips do an auto-increment of the register number thus allowing to read any number of registers in one transmission. See the data sheet of your chip.
This way two bytes are combined into one (16 bit) int.
The 8-bit I2C Bus Address contains the 7-bit I2C Slave address at its upper-positions (bit-7 to bit-1) during bus transactions (Fig-1) . The LSBit of the I2C Bus address is the "data direction bit (0 for write and 1 for read). For example (assuming 110 1000 is the I2C Slave Address):
Master transmits 110 1000 0 (0xD0) during the execution of: Wire.beginTransmission(7-bit_I2C_Slave_Address);//data write command Wire.endTransmission(); //edit
Master transmits 110 1000 1 (0xD1) during the execution of: Wire.requestFrom(7-bit_I2C_Slave_Address, 2); //data read command
The temperature sensor produces 16-bit data which are stored into two 8-bit registers and their names are: TEMP_OUT[15:8] and TEMP_OUT[7:0].
To get single piece of 16-bit temperature data, the 8-bit content of TEMP_OUT[15:8] is to be aligned with the 8-bit content of TEMP_OUT[7:0] as per Fig-1.
Figure-1:
The operations depicted in Fig-1 can be represented by the following codes: 1. Shifting the 8-bit content of TEMP_OUT[15:8] to the left by 8-bit positions and at the same time inserting eight 0s at the right-most eight vacant positions. int tempH = TEMP_OUT << 8; //eight zeros are automatically inserted
2. Perform OR (add) operations between tempH and TEMP_OUT[7:0]. int TEMP = tempH | TEMP_OUT;
The comment is not clear. It should be: //Pointing to TEMP_OUT[7:0] register
After reading the TEMP-OUT[7:0] register, the pointer will be automatically incremented to point/address the next TEMP_OUT[15:8] register.