Hi, i'm trying to read the value of a sensor (Digilent PmodTMP2) that have 16-bit resolution. It's address is 0x4B. When i try to read the value, i receive on my serial monitor only a square character! the code i'm using is this:
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(0x4B, 2); // Request 2byte (16bit) from the sensor
while(Wire.available()){
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
};
delay(100);
}
How can i achieve my test? I'd like to see the real accuracy of the sensor, then i'd like to receive something like a float! Thanks and regards
You are reading the two bytes and printing them as characters which is why they print as weird squares. You need to combine the two characters into one 16-bit integer.
Also, as the datasheet describes, the read register address starts at zero which allows you to read the temperature at power up without having to set the read register. But every time after that you have to write zero into the read register.
Pete
Thanks el_supremo! Sorry but is the first time that i use i2c in this way and i'm a little bit confused! Then what's the best way to do this? Should i read the byte like now? Or i must change type? How can i cast them into a float?
For the second hint that you gave me i think that i must do a Wire.Write(0) outside the While statement, right?
Thanks a lot 
A 16 bit value is not a float value, and there is no reason to cast it as a float.
You need to study page 12 of the ADT7420 data sheet, which explains how to convert the data to temperature.
That page 12 is weird. The number is a twos complement integer. All you need to do is store the two bytes from the sensor into a 16-bit signed integer and then divide it by 128.0 to give a floating point representation of the temperature. No need to have a different conversion formula for each resolution - other than perhaps masking off the unused bits (just in case the unused low-order bits of the number aren't automatically zero).
In the specific case of 9-bit resolution, only a right shift by 7 bits is needed since there won't be a fraction anyway.
Pete
I agree that the description is poorly written, but the result is a 16 bit signed integer ONLY if you set up the sensor to produce a 16 bit result, in which case it is a sign-extended result of lower resolution. Otherwise the bottom bits are flag bits, etc. and thus the result requires some care to interpret.
The number of bits in the temperature data-word can be extended
to 16 bits, twos complement, by setting Bit 7 to 1 in the configuration
register (Register Address 0x03). When using a 16-bit
temperature data value, Bit 0 to Bit 2 are not used as flag bits
and are, instead, the LSB bits of the temperature value.
Yes, but all that does is extend the precision on the right, which only requires "masking off the unused bits". Once the unused bits are masked off all that's needed is a division by 128 or 128.0
Pete
Sorry for the delay but i hadn't the sensor in my hand these days and i could not try anything.
Now i've read the page 12 of the datasheet of the ADT7420, and yes, it is not written well!
I've stored the value from the sensor in a signed 16 bit integer (then in an int type variable), then i've divided it by 128 and i've print the value in the serial monitor. After this i write a 0 in the read register and then i start again the loop. But what i get is only a 0 or a 1. I've tried to print the value without make the division, and i get something like 9 224 9 224 9 222 9 224 and so on...
I'm surprised that digilent have developed a sensor module with this poor information on how to set it and to make it work!
You need floating point divide. Use 128.0
If that doesn't work, post your code.
Pete