Temperature sensor read-write from register

I’m trying to change a configuration register in a temperature sensor IC, ADT7410, with the following register mapping from spec sheet:

If image doesn’t show above (preview doesn’t show it), link to image is below:

So I want to write a hex value 0x80 to register 0x03. I2C slave address is 0x48.
Note that I have used a library for this device and it is working fine, I can get temperature readings.

Here’s my code:

#include <Wire.h>
byte a ;

void setup() {
  
Wire.begin();

//writing step
Wire.beginTransmission(0x48);//Slave I2C address
Wire.write(0x03);//position pointer to config reg address
Wire.write(0x80);//write config reg with 16bit mode
Wire.endTransmission();

//reading back step
Wire.beginTransmission(0x48);//Slave I2C address
Wire.write(0x03);//position pointer to config reg address
Wire.requestFrom(0x48, 1);//request 1 byte of data from slave
byte a = Wire.read();//assign value to a
Wire.endTransmission();

Serial.begin(9600);


}

void loop() {
Serial.print("Config=");
Serial.println(a,HEX);
delay(1000);

}

Here’s what I get, printed to serial monitor:
Config=0
Config=0
Config=0
Config=0
.
.
.
.

On a second issue, if I move the Serial.print statement from the void loop() part into the setup, it just doesn’t work. Is this a known issue with wire and Serial working together, yes?

So questions I have;
1)What am I doing wrong on the register write-read?
2)How to I deal with the Serial.print x wire issue?

Thanks,

Nilo

Global

byte a ;

In setup()

 byte a = Wire.read();//assign value to a

You have two different variables named a. One global and one local to the setup() function

Then in loop()

 Serial.println(a, HEX);

Which one is being printed, do you think ?

Try the following version of your program:

#include <Wire.h>
byte a ;

void setup() 
{
   Serial.begin(9600);  
   Wire.begin();

   //writing step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.write(0x80);//write config reg with 16bit mode
   Wire.endTransmission();

   //reading back step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.endTransmission();

   Wire.requestFrom(0x48, 1);//request 1 byte of data from slave
   a = Wire.read();//assign value to a
   //Wire.endTransmission();

   Serial.print("Config=");
   Serial.println(a, HEX);  
}

void loop() 
{

//delay(1000);

}

Golam, your code brings the issue of question 2. no printout to serial monitor.

I changed the code:

byte a = Wire.read();//assign value to a

to:

a = Wire.read();//assign value to a

Serial monitor output is Config=C
It should be Config=80, yes?

If you are using UNO, then check that you have 2x10k pull-up connected to I2C Bus lines and A0/A1 pins of ADT7410 are shorted to GND. Re-run the following following program which includes few more lines to check that I2C bus transaction is OK.

#include <Wire.h>
byte a ;

void setup() 
{
   Serial.begin(9600);  
   Wire.begin();

   //writing step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.write(0x80);//write config reg with 16bit mode
   byte busStatus = Wire.endTransmission();
   if (busStatus != 0x00)
   {
      Serial.println("I2C Transaction has failed...!");
      while(1);
    }

   //reading back step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.endTransmission();

   Wire.requestFrom(0x48, 1);//request 1 byte of data from slave
   a = Wire.read();//assign value to a
   //Wire.endTransmission();

   Serial.print("Config=");
   Serial.println(a, HEX);  
}

void loop() 
{

//delay(1000);

}

BTW:
(1) Before we were reading 0x00; now, you are reading 0x0C. Is it genuine or noise? Configuration bit has not changed; but, some other bits have changed which you have not requested.

(2) If the above codes do still fail, try to read the ID of the sensor; you should get a value: 0xC0 - 0xCF as per data sheet. Just change the address value from 0x03 (Config Reg) to 0x0B (ID Reg) and comment out un-needed lines.

With the above code

GolamMostafa:
If you are using UNO, then check that you have 2x10k pull-up connected to I2C Bus lines and A0/A1 pins of ADT7410 are shorted to GND. Re-run the following following program which includes few more lines to check that I2C bus transaction is OK.

#include <Wire.h>

byte a ;

void setup()
{
  Serial.begin(9600); 
  Wire.begin();

//writing step
  Wire.beginTransmission(0x48);//Slave I2C address
  Wire.write(0x03);//position pointer to config reg address
  Wire.write(0x80);//write config reg with 16bit mode
  byte busStatus = Wire.endTransmission();
  if (busStatus != 0x00)
  {
      Serial.println(“I2C Transaction has failed…!”);
      while(1);
    }

//reading back step
  Wire.beginTransmission(0x48);//Slave I2C address
  Wire.write(0x03);//position pointer to config reg address
  Wire.endTransmission();

Wire.requestFrom(0x48, 1);//request 1 byte of data from slave
  a = Wire.read();//assign value to a
  //Wire.endTransmission();

Serial.print(“Config=”);
  Serial.println(a, HEX); 
}

void loop()
{

//delay(1000);

}




**BTW:** 
**(1)** Before we were reading 0x00; now, you are reading 0x0C. Is it genuine or noise? Configuration bit has not changed; but, some other bits have changed which you have not requested.

**(2)** If the above codes do still fail, try to read the ID of the sensor; you should get a value: 0xC0 - 0xCF as per data sheet. Just change the address value from 0x03 (Config Reg) to 0x0B (ID Reg) and comment out un-needed lines.

I’m using an arduino Micro with 10K pull-up resistors. I2C is working since temperature can be read and vary with external heating when I use a library found online.

Using the code above return no printout to serial monitor, nothing. Modifying it to the code below returns the following:

New code:

#include <Wire.h>
byte a ;
byte busStatus;
void setup() 
{
   
   Wire.begin();

   //writing step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.write(0x80);//write config reg with 16bit mode
   busStatus = Wire.endTransmission();
  

   //reading back step
   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x03);//position pointer to config reg address
   Wire.endTransmission();

   Wire.requestFrom(0x48, 1);//request 1 byte of data from slave
   a = Wire.read();//assign value to a
   //Wire.endTransmission();

 
}

void loop() 
{
if (busStatus != 0x00)
   {
      Serial.println("I2C Transaction has failed...!");
      while(1);
    }
    else
    {
      Serial.println("I2C Transaction OK...!");
    }
       Serial.print("Config=");
   Serial.println(a, HEX); 
delay(1000);

}

New printout:
I2C Transaction OK…!
Config=C

As per your suggestion, reading the IC ID from 0x0B returns D, which is obviously not correct (outside range 0xC0 to 0cCF).

I have other IC’s and after replacement, reg 0x03 now returns D. Changed reg address to 0x0b, 0x00 or 0x01 (adc address) and still returns D.
So there is definitely something fishy here, just not making sense. Monitored power lines and I2C bus with oscilloscope and no signs of noise.

Note that I have used a library for this device and it is working fine, I can get temperature readings.

Can you please provide a link to the library you are using successfully?

Let us avoid the use of Library Functions and try to read the Temperature Registers directly from the sensor; compute the temperature value and show it on Serial Monitor. This will help us to understand the reasons of being denied to access the Configuration and ID Registers.

#include <Wire.h>
float tempC;
int x = 0, y = 0;

void setup() 
{
   Serial.begin(9600);  
   Wire.begin();
}

void loop()
{

   Wire.beginTransmission(0x48);//Slave I2C address
   Wire.write(0x00);//position pointer to Temp Reg. Address
   Wire.endTransmission();

   Wire.requestFrom(0x48, 2);//request 2 byte of data from slave
   x = Wire.read();    //Temp value of MSByte ; test value = 0x0C for 25 degC
   y = Wire.read();    //Temp value of LSByte ; test value = 0x80 for 25 degc

   y = y>>3;    //see data sheets       
   for (int i= 0, j=5; i<7, j<12; i++, j++)  //test value : xy (0x0C80) ----> 0x0190*0.0625 = 25 degC
   {
    bitWrite(y, j, bitRead(x, i));
   }
   //Serial.println(y, HEX);    //test value = 0x0190
   tempC = (float)y*0.0625;     //test value = 25.00 degC sign-bit + 12-bit temp = 13-bit resolution
   Serial.println(tempC, 2);
  
   delay(1000);
}

BTW: Rub the sensor by fingers and check that the Serial Monitor shows changing temperature. Please, report the result.

Tested and it did report temperature. Blowing on sensor increases reading, but reading seems to be few degrees off and doesn't rise as quickly as it did with the library.

OK! This is a good news that we can access the registers of the sensor. Now, we have to search for the way of changing the resolution to 16-bit by writing 0x80 into the Configuration Register. Notice that there is a 1-sec delay in my test program.

Thanks for the good efforts! K+.

BTW: If you become successful in the journey of accessing the Configuration and ID Registers, please let us know what you have done.

I have seen some indication of issues with I2C rise time requirements for this IC and will be investigating on that direction now. Specs say rise time < 0.3us and I2C bus freq < 400Khz. AtMega328 is max 400Khz I2C, so it should not be an issue, but who knows!

nilonha:
I have seen some indication of issues with I2C rise time requirements for this IC and will be investigating on that direction now. Specs say rise time < 0.3us and I2C bus freq < 400Khz. AtMega328 is max 400Khz I2C, so it should not be an issue, but who knows!

It could be an issue. You reported that the temperature reading was few degrees off, and you also received wrong values from the Config, and ID Registers. Try with Arduino UNO. The default speed of UNO is 100 kHz. Until you become successful in the acquisition of correct ID and Config. values from the sensor, you should not use this sensor for temperate measurement in your intended project; because, there is something that is not really right!

Feedback on I2C bus speed investigation.
Thought I had this taken care of, I really did, but ..
In summary, I2C bus from arduino was crap, huge rising time with high state not even reaching 5V.
I tested both default 400Khz and 100Khz, both garbage. Used Wire.setClock() for selecting the frequency.
I was using 10K resistors for the pull-up. After changing it to 1K, things became much better with reasonable time rise and 5V high state.
But all this didn't do a dent on fixing the issue :confused:
Note that the above was observed on I2C bus with arduino stand alone, not connected to ADT7410. Just the external pull-up resistors. That indicates that arduino board is to blame for the crappy wave forms, somehow having a high internal capacitance that is affecting the switching response.
After further testing with other arduino boards (nano and micro) without success, noticed that reading of reg 0x03 (supposedly reg 0x03) was changing with temperature :angry: . So all this time, I have been reading reg 0x00, which is the MSB for the internal ADC on the 7410.
Conclusion so far is that the write commands are not working, 7410 points to reg 0x00 by default at start-up and that is what has been read so far. Reading command is of course working.
Saga continues...

Do you have any other sensor like BME280 or DS1307/DS3231 RTC Modules? Please, operate these devices before blaming the Arduino. I have started believing that the ADT7410 sensors that you own could be belonging to a 'defective batch'.

GolamMostafa:
Do you have any other sensor like BME280 or DS1307/DS3231 RTC Modules? Please, operate these devices before blaming the Arduino. I have started believing that the ADT7410 sensors that you own could be belonging to a 'defective batch'.

Copy that. I don't think that arduino is the problem here, specially after changing the pull-up res to 1K and 100Khz bus. Either the IC has some specific requirements that are not shown on the spec sheet or Errata yet to be corrected, or a bad batch, like you suggested.