I2C and the MCP9800 Temperature sensor
-
- Posts: 27
- Joined: Sat Aug 01, 2009 3:15 pm
- Has thanked: 2 times
- Been thanked: 10 times
- Contact:
I2C and the MCP9800 Temperature sensor
Hello all,
I am trying to read the 16 bit ambient temperature register of a MCP9800 via I2C
( http://ww1.microchip.com/downloads/en/D ... 21909b.pdf )
Before I even try and perform the calculation to convert the 16 bit code into the temperature can anyone tell me how to read the 16 bit temperature register , and perhaps some pointers on converting the two's complement to temperature + and -,
Thank you in anticipation,
Ben
I have established I2C communication from a 16F877A to the MCP9800, but I am only getting a byte back ( the upper half? ).
An example of what I am getting, returns 11100111 or decimal 231 ( err... I think! ). With the default 9 bit ADC resolution this would have to be halved ( err... I think! ). I am not sure why the MSB is set as this suggests a negative value.
The flow code. Perhaps this is a little naΓ―ve, but at least I have got the hardware talking!!
From the Microchip data sheet……….
AMBIENT TEMPERATURE
REGISTER (TA) The MCP9800/1/2/3 has a 16-bit read-only ambient
temperature register (TA) that contains 9-bit to 12-bit
temperature data. This data is formatted in two’s
complement. The bit assignments, as well as the
corresponding resolution, is shown in the register
assignment below.
I am trying to read the 16 bit ambient temperature register of a MCP9800 via I2C
( http://ww1.microchip.com/downloads/en/D ... 21909b.pdf )
Before I even try and perform the calculation to convert the 16 bit code into the temperature can anyone tell me how to read the 16 bit temperature register , and perhaps some pointers on converting the two's complement to temperature + and -,
Thank you in anticipation,
Ben
I have established I2C communication from a 16F877A to the MCP9800, but I am only getting a byte back ( the upper half? ).
An example of what I am getting, returns 11100111 or decimal 231 ( err... I think! ). With the default 9 bit ADC resolution this would have to be halved ( err... I think! ). I am not sure why the MSB is set as this suggests a negative value.
The flow code. Perhaps this is a little naΓ―ve, but at least I have got the hardware talking!!
From the Microchip data sheet……….
AMBIENT TEMPERATURE
REGISTER (TA) The MCP9800/1/2/3 has a 16-bit read-only ambient
temperature register (TA) that contains 9-bit to 12-bit
temperature data. This data is formatted in two’s
complement. The bit assignments, as well as the
corresponding resolution, is shown in the register
assignment below.
- Dan81
- Valued Contributor
- Posts: 268
- Joined: Sun Jan 15, 2006 4:07 pm
- Location: Albi France
- Been thanked: 60 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Harry
Take a look at this flowchart.
Daniel
Take a look at this flowchart.
Daniel
- Attachments
-
- MCP980x.fcf
- (5.5 KiB) Downloaded 1097 times
-
- Posts: 27
- Joined: Sat Aug 01, 2009 3:15 pm
- Has thanked: 2 times
- Been thanked: 10 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Thankyou Daniel,
I have down loaded your example and converted it to run on my 16F877A hardware.
Should the register pointer be 00 for temperature?
I see how to get the second byte now, I was thinking that to do two RX bytes I would move to the next register.
DECIMAL = ( var1 >> 7 ) * 5
I see what you are doing here the second byte received is the decimal and with the default 9-Bit resolution only the MSB is used ( 0uuu uuuu ) so the >>7 gives 0000 0001 or 0000 0000 which when *5 will = 5 or 0.
Thanks once again.
I have down loaded your example and converted it to run on my 16F877A hardware.
Should the register pointer be 00 for temperature?
I see how to get the second byte now, I was thinking that to do two RX bytes I would move to the next register.
DECIMAL = ( var1 >> 7 ) * 5
I see what you are doing here the second byte received is the decimal and with the default 9-Bit resolution only the MSB is used ( 0uuu uuuu ) so the >>7 gives 0000 0001 or 0000 0000 which when *5 will = 5 or 0.
Thanks once again.
- Dan81
- Valued Contributor
- Posts: 268
- Joined: Sun Jan 15, 2006 4:07 pm
- Location: Albi France
- Been thanked: 60 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Harry
You're right : register pointer must be 0.
(I use a DS1631)
Daniel
You're right : register pointer must be 0.
(I use a DS1631)
Daniel
-
- Posts: 27
- Joined: Sat Aug 01, 2009 3:15 pm
- Has thanked: 2 times
- Been thanked: 10 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Thanks Daniel,
Do you have any idea why I am getting 231 (11100111 ) in the upper half of the ambient temperature register at room temperature? When the MCP9800 is warmed this reading counts up, so I must be in the right place. As this is two’s complement with the MSB being set this would suggest a negative temperature of 103degC if I understand correctly.
Best regards,
ben
Do you have any idea why I am getting 231 (11100111 ) in the upper half of the ambient temperature register at room temperature? When the MCP9800 is warmed this reading counts up, so I must be in the right place. As this is two’s complement with the MSB being set this would suggest a negative temperature of 103degC if I understand correctly.
Best regards,
ben
- Dan81
- Valued Contributor
- Posts: 268
- Joined: Sun Jan 15, 2006 4:07 pm
- Location: Albi France
- Been thanked: 60 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Harry
Can you post your Flowchart (*.fcf) or send it to me by PM.
Daniel
Can you post your Flowchart (*.fcf) or send it to me by PM.
Daniel
-
- Posts: 27
- Joined: Sat Aug 01, 2009 3:15 pm
- Has thanked: 2 times
- Been thanked: 10 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Daniel,
Here is the simple code to read the MCP9800. This is based on a 16f877a with hardware I2C connection to Port C and LCD connected to Port A.
On the LCD the Ambient Temperature Upper Byte is displayed with the Ambient Temperature Lower Byte on the second line.
I get 225 at cold room temerature counting in 1's up to 230 at cold finger temperature. If the MSB is 1 this would make a negative temperature, it can't be that cold in here!!
The lower byte alternates between 0 and 128 ( 1000 000 or 0000 0000 ) which makes sense for the default 9 bit setting.
Thank for having a look at this,
ben
Here is the simple code to read the MCP9800. This is based on a 16f877a with hardware I2C connection to Port C and LCD connected to Port A.
On the LCD the Ambient Temperature Upper Byte is displayed with the Ambient Temperature Lower Byte on the second line.
I get 225 at cold room temerature counting in 1's up to 230 at cold finger temperature. If the MSB is 1 this would make a negative temperature, it can't be that cold in here!!
The lower byte alternates between 0 and 128 ( 1000 000 or 0000 0000 ) which makes sense for the default 9 bit setting.
Thank for having a look at this,
ben
- Dan81
- Valued Contributor
- Posts: 268
- Joined: Sun Jan 15, 2006 4:07 pm
- Location: Albi France
- Been thanked: 60 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Harry
Code seems good, but I can't test it.
May be you can try to
- write Tset (and/or Thyst)
- read Temp
-read Tset (and/or Thyst)
if Tset read = Tset write , may be MCP is unserviceable !
Try to decrease the frequency (100kHz) and use the HARDWARE setting.
Daniel
Code seems good, but I can't test it.
May be you can try to
- write Tset (and/or Thyst)
- read Temp
-read Tset (and/or Thyst)
if Tset read = Tset write , may be MCP is unserviceable !
Try to decrease the frequency (100kHz) and use the HARDWARE setting.
Daniel
- Dan81
- Valued Contributor
- Posts: 268
- Joined: Sun Jan 15, 2006 4:07 pm
- Location: Albi France
- Been thanked: 60 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hello Harry
The component macro "I2C Init" is missing.
Daniel
The component macro "I2C Init" is missing.
Daniel
-
- Posts: 27
- Joined: Sat Aug 01, 2009 3:15 pm
- Has thanked: 2 times
- Been thanked: 10 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Daniel,
I got a replacement PCB and it is now working, so it must have been the IC! I will send it back for testing.
Thanks for your help,
regards,
ben
I got a replacement PCB and it is now working, so it must have been the IC! I will send it back for testing.
Thanks for your help,
regards,
ben
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi to all.
I have been following the threads about using the MCP 9800 Temperature sensor.
But still I do not understand fully.
I have an MCP9800/A5T sensor.
I guess A5 refers to the device address.
Which should be "0x4D"
Is this correct?
How do modify the example program so I can read from the above sensor in a 12 Bit resolution?
Best Regards:
Uli
I have been following the threads about using the MCP 9800 Temperature sensor.
But still I do not understand fully.
I have an MCP9800/A5T sensor.
I guess A5 refers to the device address.
Which should be "0x4D"
Is this correct?
How do modify the example program so I can read from the above sensor in a 12 Bit resolution?
Best Regards:
Uli
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
MCP9800/A5T specifies device type and you are correct about the device address which is 0x4D. I'm trying to understand the functionality of the chip and will post a program for you.I have an MCP9800/A5T sensor. I guess A5 refers to the device address. Which should be "0x4D" Is this correct?
- Attachments
-
- detail.PNG
- (79.78 KiB) Downloaded 14674 times
-
- add.PNG
- (12.12 KiB) Downloaded 14677 times
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
For 9,10,11,12 bits ad conversion time 30, 60, 120 and 240 ms correspondingly. The power-up default register value is...Power up default is 9-bit.
Hope this will help..
which implies that we don't need to initialize anything in power-up as registers are already configured to read temp value. Two bytes have to read using the following I2C protocol..
I have converted the 2's complement temp value into decimal temp value..Hope this will help..
- Attachments
-
- MCP9800_v1.fcf
- (23.26 KiB) Downloaded 425 times
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi
Thanks for the sample program,
Somehow it does not work.
It always shows "1.0°C"
My room is definately warmer than that.
I also wonder, I see the Variable THERM is only used in the Initialisation.
Is that right?
Thanks for the sample program,
Somehow it does not work.
It always shows "1.0°C"
My room is definately warmer than that.
I also wonder, I see the Variable THERM is only used in the Initialisation.
Is that right?
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
I have used THERM to hold device address 0x4D which is then used to produce write and read address..I made a mistake in shifting..
Now I have corrected that it should work now..You can re-download now
I have used THERM to hold device address 0x4D which is then used to produce write and read address..I made a mistake in shifting..
Now I have corrected that it should work now..You can re-download now
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Enamul.
Thanks I really appreciate you help without it I would not have gotten this far.
Now I see how Term is used.
Now it shows "0.0°C
Best Regards:
Uli
Thanks I really appreciate you help without it I would not have gotten this far.
Now I see how Term is used.
Now it shows "0.0°C
Best Regards:
Uli
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
Thanks for the updates..I didn't find any problem except in last code soft I2C was using which I have changed to hardware I2C which is better and also changed some properties of I2C..Hopefully it will work now.
Thanks for the updates..I didn't find any problem except in last code soft I2C was using which I have changed to hardware I2C which is better and also changed some properties of I2C..Hopefully it will work now.
- Attachments
-
- MCP9800_v1.fcf
- (23.26 KiB) Downloaded 384 times
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi
Now it toggles between 0 and 1°
I changed the flowchart so it also displays temp h and temp l
Temp H gives a number corresponding with temperature.
Temp L toggles between 128 and 028
Now it toggles between 0 and 1°
I changed the flowchart so it also displays temp h and temp l
Temp H gives a number corresponding with temperature.
Temp L toggles between 128 and 028
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
Can you please post the program after adding those number display option..so that I can see why it's going wrong..it seems from your last post that I2C is working..just need to tune displaying temperature value right...
I forgot to ask you one very important question..did you used pull-up resistors in SDA and SCK? If you did that can you please try the new post..as I have changed the idea of calculating temp here..
Can you please post the program after adding those number display option..so that I can see why it's going wrong..it seems from your last post that I2C is working..just need to tune displaying temperature value right...
I forgot to ask you one very important question..did you used pull-up resistors in SDA and SCK? If you did that can you please try the new post..as I have changed the idea of calculating temp here..
- Attachments
-
- MCP9800_v2.fcf
- (15.31 KiB) Downloaded 349 times
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi
Yes I do use pull up resistors.
The last code is working better.
However it has a problem it can display 33.5, 32, 31,5 30 the numbers in between it does not show.
So I guess there is still a glitch with the recombining of the high and low bytes.
I have no Idea how to combine them.
I start to get an understanding How I2C works.
I modified the code that it reads in 12bits.
But I do not know how to change the formula to display it. In 12bits.
I have attached the modified code that displays the higher and the lower bits.
Best Regards:
Uli
Yes I do use pull up resistors.
The last code is working better.
However it has a problem it can display 33.5, 32, 31,5 30 the numbers in between it does not show.
So I guess there is still a glitch with the recombining of the high and low bytes.
I have no Idea how to combine them.
I start to get an understanding How I2C works.
I modified the code that it reads in 12bits.
But I do not know how to change the formula to display it. In 12bits.
I have attached the modified code that displays the higher and the lower bits.
Best Regards:
Uli
- Attachments
-
- MCP9800_v21.fcf
- (17.09 KiB) Downloaded 360 times
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
9-bit calculation idea was..
Combing upper and lower byte in integer variable TEMP..But in 9-bit resolution according to datasheet lower 7 bit is useless..that's why I have shifted 7 times to remove those lower 7-bit.
Now remaining 9 bit is data where LSB is 2^(-1) = 0.5, next bit is 2^0, and so on..so basically temperature = TEMP/2
But we can't get fraction in int variable and I want to avoid floating point calculation..I have to do that technically..for example TEMP=49 so temperature will be 24.5 this code will produce TEMP = 24
This will return DP = 1
This will return DP = 5
so displaying TEMP.DP we will get 24.5
Hope that it's clear..I am working on your 12-bit resolution code..There are some issues there...
In 9-bit resolution, you will get for example 30.0, 30.5, 31.0, 31.5 temperatures only no intermediate temp. But I guess you are saying about jump between 30 to 31.5..how you are warming the sensor? If you give high heat in that case it will jump rapidly..but if you just put your finger it should increase slowly..However it has a problem it can display 33.5, 32, 31,5 30 the numbers in between it does not show.
So I guess there is still a glitch with the recombining of the high and low bytes.
9-bit calculation idea was..
Code: Select all
TEMP = (Temp_H << 8) OR Temp_L
TEMP = (TEMP >> 7)
TEMP = TEMP / 2
DP = TEMP MOD 2
DP = (DP * 10) / 2
Now remaining 9 bit is data where LSB is 2^(-1) = 0.5, next bit is 2^0, and so on..so basically temperature = TEMP/2
But we can't get fraction in int variable and I want to avoid floating point calculation..I have to do that technically..for example TEMP=49 so temperature will be 24.5
Code: Select all
TEMP = TEMP / 2
Code: Select all
DP = TEMP MOD 2
Code: Select all
DP = (DP * 10) / 2
so displaying TEMP.DP we will get 24.5
Hope that it's clear..I am working on your 12-bit resolution code..There are some issues there...
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi,
Here is the corrected version for 12-bit resolution..
osccon should be 0x78 not 0x7A as we want to chose INTERNAL clock with configuration osc setting..which is standard. fvrcon is not important for this chunk of code but you might need for Fixed Voltage Reference that's why I keep that..But TRISD initialization isn't necessary as this is redundant (already in FCD; corrected in FCv5.4).
Note: Resolution modification should be done once in the beginning of the code and shouldn't be in the main loop..Any I2C communication should finish with STOP..even if you are reading immediately after writing as it breaks protocol standard.
GetTemperature macro remains as before..but the calculation of temperature is completely changed now as you have moved to much higher resolution..Now you can measure -0.0625 deg to +150
I have to move to floating point calculation here..Now first 4 bit is useless that's why I have shifted 4 times to remove those out. Then I have converted the INT to FLOAT so that I can multiply by TEMP_FP by 2^(-4) = 0.0625 to get real temperature which is TEMP/16.
After that I have converted float to string as in LCD you can't display float. You will get maximum 4 decimal places in result but float will produce 6 decimal places that's why I have discarded last 2 places.
I guess this version will work for 0.0000 deg to +125 deg. For negative temperature I need to manipulate code bit more..
Edit: I made a mistake ..I divided by 0.0625 which should be multiply..I have corrected code
Here is the corrected version for 12-bit resolution..
Code: Select all
//Set Oscillator to 16Mhz
osccon=0x78;
fvrcon= 0x83;
Note: Resolution modification should be done once in the beginning of the code and shouldn't be in the main loop..Any I2C communication should finish with STOP..even if you are reading immediately after writing as it breaks protocol standard.
GetTemperature macro remains as before..but the calculation of temperature is completely changed now as you have moved to much higher resolution..Now you can measure -0.0625 deg to +150
I have to move to floating point calculation here..Now first 4 bit is useless that's why I have shifted 4 times to remove those out. Then I have converted the INT to FLOAT so that I can multiply by TEMP_FP by 2^(-4) = 0.0625 to get real temperature which is TEMP/16.
TA = Code × 2^n
Where:
n = -1, -2, -3 and -4 for 9-bit, 10-bit, 11-bit
and 12-bit resolution, respectively
TA = Ambient Temperature (°C)
Code= MCP980X output in decimal
Code: Select all
TEMP = (Temp_H << 8) OR Temp_L
TEMP = (TEMP >> 4)
TEMP_FP = int2float (TEMP)
TEMP_FP = fdiv (TEMP_FP,16)
DISP_STR = FloatToString$ (TEMP_FP)
DISP_STR = Left$ (DISP_STR,7)
I guess this version will work for 0.0000 deg to +125 deg. For negative temperature I need to manipulate code bit more..
Edit: I made a mistake ..I divided by 0.0625 which should be multiply..I have corrected code
- Attachments
-
- MCP9800_v3.fcf
- (17.58 KiB) Downloaded 356 times
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi,
Finally I have manged to make code for -55 to +125 deg full range of the device..I have tested display portion carefully..it works fine..Enjoy
Finally I have manged to make code for -55 to +125 deg full range of the device..I have tested display portion carefully..it works fine..Enjoy
- Attachments
-
- MCP9800_v4.fcf
- (19.59 KiB) Downloaded 389 times
-
- Posts: 323
- Joined: Tue Sep 06, 2011 2:54 am
- Has thanked: 166 times
- Been thanked: 26 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi
Thanks a lot.
This Program works very fine.
Actually I do not need such high resolution. I only need "0.05"
I am a bit concerned about using too much space on the Chip since I plan to use more than one sensor.
Is it possible to get it to work without floating point?
I tried to add a calculation with a long number the conversion works fine, but I do not know how to get the digital point right and also if it gets down to less than 10° it starts to add zeros on the back.
How could I fix this?
See attachment.
Best Regards:
Uli
Thanks a lot.
This Program works very fine.
Actually I do not need such high resolution. I only need "0.05"
I am a bit concerned about using too much space on the Chip since I plan to use more than one sensor.
Is it possible to get it to work without floating point?
I tried to add a calculation with a long number the conversion works fine, but I do not know how to get the digital point right and also if it gets down to less than 10° it starts to add zeros on the back.
How could I fix this?
See attachment.
Best Regards:
Uli
- Attachments
-
- MCP9800_v41.fcf
- (19.75 KiB) Downloaded 354 times
- Enamul
- Posts: 1772
- Joined: Mon Mar 05, 2012 11:34 pm
- Location: Nottingham, UK
- Has thanked: 271 times
- Been thanked: 814 times
- Contact:
Re: I2C and the MCP9800 Temperature sensor
Hi Uli,
This version removes string and float and 2 decimal places for any temp value..removes long as well as int can sort that case..Hope this will help
This version removes string and float and 2 decimal places for any temp value..removes long as well as int can sort that case..Hope this will help
- Attachments
-
- MCP9800_v5.fcf
- (19.13 KiB) Downloaded 438 times