View previous topic :: View next topic |
Author |
Message |
jacquesdejager
Joined: 23 Apr 2011 Posts: 11 Location: South Africa
|
MCP9801 issues with LSB |
Posted: Sat Nov 05, 2011 12:47 am |
|
|
Hello guys --
The LSB returned from a MCP9801 is not correct, to do a repeated start condition is it correct in doing the following --
Code: |
int8 byteM = 0;
int8 byteL = 0;
i2c_start(); //start
i2c_write(91); //device addr and read bit set
byteM = i2c_read(1); //ack
byteL = i2c_read(0); //nak
i2c_stop();
|
When evaluating the byteM all is good, but the value of byteL is not right.
The way I handle the i2c read - can this be classified as --
repeated start condition ?
Any help would be appreciated. _________________ The Definition of an Upgrade: Take old bugs out, put new ones in.
Last edited by jacquesdejager on Sun Nov 06, 2011 5:36 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sat Nov 05, 2011 4:37 am |
|
|
This comment.....The LSB returned from a MCP9801 is not correct
does NOT explain what is wrong with the reading. How do you know the value returned is 'not correct'.
You'ld have to show us your code, not just the I2C section as well as expected values and returned values for at least 5 samples.
I can think of 6 different reasons even without seeing more but without more info, I can't say which it is.
The more information you supply the better, faster answers we can give you. |
|
![](templates/subSilver/images/spacer.gif) |
jacquesdejager
Joined: 23 Apr 2011 Posts: 11 Location: South Africa
|
|
Posted: Sun Nov 06, 2011 6:27 am |
|
|
Hello temtronic --
Thank you for prompt response.
I resolve the problem, still doesn't explain why I need to multiply the value twice with the value 2^-4.
The datasheet indicate that you only need to calculate the temperature like this : Ta = Code x 2^-4 for 12 bit resolution, maybe you can make something out, but the code works now except for negative temperature.
Code: |
#use i2c(MASTER,I2C1,FORCE_HW)
#define I2C_SPEED_DEF 100000
#define MCP9800_ADDRESS_WRITE 0x90
#define MCP9800_ADDRESS_READ 0x91
#define MCP9800_ALERT_ACTIVE_LOW 0x00
#define MCP9800_ALERT_ACTIVE_HIGH 0x04
#define MCP9800_COMP_MODE 0x00
#define MCP9800_TEMPERATURE 0x00
#define MCP9800_CONFIGURATION 0x01
#define MCP9800_HYSTERESIS 0x02
#define MCP9800_LIMITSET 0x03
#define MCP9800_INT_MODE 0x02
#define MCP9800_ONESHOT_OFF 0x00
#define MCP9800_ONESHOT_ON 0x80
#define MCP9800_SHUTDOWN_OFF 0x00
#define MCP9800_SHUTDOWN_ON 0x01
#define MCP9800_TSET_DEFAULT 80
#define MCP9800_CONFIG_BITS 0x64
void i2c_init(void);
void mcp9801_config(void);
void mcp9801_read(float *Temp);
void i2c_init(void){
set_tris_c(0b00011011);
i2c_speed(I2C_SPEED_DEF);
} //i2c_init()
void mcp9801_config(){
i2c_start();
i2c_write(MCP9800_ADDRESS_WRITE);
i2c_write(MCP9800_CONFIGURATION);
i2c_write(MCP9800_CONFIG_BITS);
i2c_stop();
} //mcp9801_config
void mcp9801_read(float *Temp){
char ack = 1;
char nak = 0;
int8 RawReadingH = 0;
int8 RawReadingL = 0;
int16 RawReading = 0;
i2c_start(); // get temp using i2c
i2c_write(MCP9800_ADDRESS_WRITE);
i2c_write(MCP9800_TEMPERATURE);
i2c_stop();
i2c_start();
i2c_write(MCP9800_ADDRESS_READ);
RawReadingH = i2c_read(ack);
RawReadingL = i2c_read(nak);
i2c_stop();
RawReading = make16(RawReadingH,RawReadingL);
*Temp = RawReading * 0.0625 * 0.0625; // 2^-4 for 12bit resolution
}//mcp9801_read
|
_________________ The Definition of an Upgrade: Take old bugs out, put new ones in. |
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sun Nov 06, 2011 7:29 am |
|
|
In mathematics notation is used to represent numbers. Since we are familiar with decimal ( base 10 ) notation we often consider it the only true notation.
This is reinforced by hand held calculators that use binary coded decimal ( base 10) . The PIC is strictly a binary device. All numerical ( float integer signed unsigned ) calculations are done in binary using binary notation positive voltage for 1 zero voltage for 0. Since the registers etc are limited a space restriction is made on the binary calculation like 23 bit mantissa or 32 bit integer. These restrictions create upper and lower bounds on the notation that can be employed by the PIC. Only with integers or power series of 2 numbers can binary and decimal notations be exactly aligned. Notation of rational numbers or irrational numbers is different between binary and decimal and only approximations ( often called rounding or precision restrictions) are possible.
Your source data is binary which you manipulate using binary floating point. The source code used decimal notation EX 0.0625 the compiler will translated this notation to binary since this is a whole number power of 2 the binary and the decimal notations will align.
Within the restrictions of this notation the calculation by the PIC is accurate.
This binary notation if transformed to decimal notation will if it involves rational or irrational numbers will always be approximate ( only agreeing to the first few significant digits) .
Now a pic could do everything in BCD but it really needs compiler support and would make the code bulkier and slower. Next best is fixed decimal support in which rational decimal notation is promoted to binary integer notation and the decimal point is tracked separately. Since binary and decimal notation are aligned for all integers it avoids any differences between binary notation and decimal notation. |
|
![](templates/subSilver/images/spacer.gif) |
jacquesdejager
Joined: 23 Apr 2011 Posts: 11 Location: South Africa
|
|
Posted: Sun Nov 06, 2011 8:37 am |
|
|
Hello Douglas --
I understand the notation systems, but why should I do the calculation twice to get to the right answer, is it better to convert the answer to BCD then ?
Looks like this is what Microchip did in the development kit for MCP9801, but with 7 Segment displays.
Thank you _________________ The Definition of an Upgrade: Take old bugs out, put new ones in. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Nov 06, 2011 8:46 am |
|
|
Have another look at the MCP9801 data sheet,especially the Ambient temperature register information.You'll see the lower 4 bits of temperature data in the 'lower half' of the 'temperature reading' are actually the high nibble. The raw reading must be right shifted by 4, then some math done on it to convert to actual temperature, based on resolution that you've chosen. |
|
![](templates/subSilver/images/spacer.gif) |
jacquesdejager
Joined: 23 Apr 2011 Posts: 11 Location: South Africa
|
|
Posted: Sun Nov 06, 2011 11:37 am |
|
|
Hello temtronic --
You are right, all work out well now !!
Code: |
iRawReading = make16(iRawReadingH,iRawReadingL);
iRawReading >>= 4;
*pTempAbs = iRawReading * 0.0625
|
Thank you very much for your help!! _________________ The Definition of an Upgrade: Take old bugs out, put new ones in. |
|
![](templates/subSilver/images/spacer.gif) |
|