View previous topic :: View next topic |
Author |
Message |
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Mon Dec 22, 2014 11:48 am |
|
|
Thank you
Now when using the “i2c bus scanner” I can get as follows:
Code: |
USED addr: 10
ACK addr: 10
USED addr: 12
ACK addr: 12
USED addr: 14
ACK addr: 14
USED addr: 16
ACK addr: 16
USED addr: 18
ACK addr: 18
USED addr: 1A
ACK addr: 1A
USED addr: 1C
ACK addr: 1C
USED addr: 1E
ACK addr: 1E
USED addr: 20
ACK addr: 20
USED addr: 22
ACK addr: 22
USED addr: 24
ACK addr: 24
USED addr: 26
ACK addr: 26
USED addr: 28
ACK addr: 28
USED addr: 2A
ACK addr: 2A
USED addr: 2C
ACK addr: 2C
…………..
|
I have same result for 330 ohm, 1k ohm, 2.2k ohm.
And now with my first program I have:
Code: |
LSByte = 00
MSByte = 00
PEC = 00
tempData1 = 00
tempData2 = 78
temperature_celsius = -273.16
temperature_fahrenheit = -459.68
Temperature = -273.16
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Dec 22, 2014 12:17 pm |
|
|
330R, exceeds the rated current of the driver. This is why 1K2R, is specified as _minimum_. Don't go just trying things, use the formulae published for the bus. |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Mon Dec 22, 2014 12:54 pm |
|
|
Thank you.
I made some research and I find that there is some one who make this component working with 280 ohm resistor.
When I use 3.3k I have no result with the I2C scanner and with 2.2k I have result for all I2C addresses. So I could not find the problem. :( |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Dec 22, 2014 1:41 pm |
|
|
What people do online is no guide to correct electrical practice or getting designs that will keep working. There are millions of 'designs' posted that in some cases are lethal, yet alone dangerous... That it doesn't work with 3.3K, means that your bus capacitance is significant. Below 1.2K, long term, you risk damage to the drivers in the peripheral (the ones in the PIC are rated much higher). |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Mon Dec 22, 2014 2:07 pm |
|
|
Thanks.
So now I'm using 2.2kohm and with the I2C scanner I get so many correct addresses. And when I run the temperature programm I get 0 as I posted previously.
Quote: | Number of i2c chips found: 112 |
So do you have any idea? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9242 Location: Greensville,Ontario
|
|
Posted: Mon Dec 22, 2014 2:14 pm |
|
|
As it's been several posts,please post your current program that gets the data from the device.
From the data sheet it appears it's 16 bit data that comes back, then you'll need to do some 'math'....
It is necessary to display the 'raw data' from the device, not just the temperature result from your math.
Jay |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Mon Dec 22, 2014 2:22 pm |
|
|
Thank you.
So here is my code:
Code: |
// get the temperature of the object
float get_temperature(int OBJECT_AMBIENT_TEMPERATURE, int fahrenheit_celsius) {
double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90615)
double tempData = 0x0000; // zero out the data
int MSByte = 0x00, LSByte = 0x00, PEC = 0x00;
delay_ms(300);
i2c_start(); // Start condition
i2c_write(0xB6); // Slave Address - write bit low - the '1' here is the
//bit number in the diagram, _not_ the value....
i2c_write(0x07); // Register address
I2C_start(); //Restart the bus
i2c_write(0xB7); // Slave Address - write bit high for a read
LSByte = i2c_read();
printf("LSByte = %x \r\n",LSByte);
MSByte = i2c_read();
printf("MSByte = %x \r\n",MSByte);
PEC = i2c_read(0); //You need to _NACK_ the last byte
printf("PEC = %x \r\n",PEC);
i2c_stop();
// This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
tempData = (double)(((MSByte & 0x007F) << 8) + LSByte);
printf("tempData1 = %x \r\n",tempData);
tempData = (tempData * tempFactor) - 0.01;
printf("tempData2 = %x \r\n",tempData);
// temperature in Celsius
temperature_celsius = tempData - 273.15;
printf("temperature_celsius = %3.2f \r\n",temperature_celsius);
// temperature in Fahrenheit
temperature_fahrenheit = (temperature_celsius*1.8) + 32;
printf("temperature_fahrenheit = %3.2f \r\n",temperature_fahrenheit);
// fahrenheit_celsius = 0 ==> display the Celsius
// fahrenheit_celsius = 1 ==> display the Fahrenheit
if (fahrenheit_celsius == 0 ) {
// return the Celsius value
return temperature_celsius;
} else {
// return the Fahrenheit value
return temperature_fahrenheit;
}
}
|
But is it normal to get so match correct addresses from the device?? |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
Posted: Mon Dec 22, 2014 2:52 pm |
|
|
Hi,
I had to restore a backup to find my original IR reader program.
My pullups were 3K3 or 3K0 from memory
As I said on the original post, be very carefull with decoupling keep cap real close to the device !
Below is my code for reading the device.
Code: |
int8 TempLSB,TempMSB,PEC;
int16 TempRAW;
float Temperature;
float MLX90615_Read_Device_Temp(int8 Address)
{
TempLSB=0; //Clear variables
TempMSB=0; //Clear variables
TempRAW=0; //Clear variables
i2c_start(); // Start condition
i2c_write(Address*2); // (Slave Address * 2) For R/W bit low for a write
i2c_write(0x26); // Device Temp Register address
i2c_start(); // Restart the bus
i2c_write((Address*2)+1); // (Slave Address * 2) - R/W bit high for a read
TempLSB = i2c_read(); // Read LSB of device temp from register
TempMSB = i2c_read(); // Read MSB of device temp from register
PEC = i2c_read(1); // Read PEC
i2c_stop();
TempRAW = make16(TempMSB,TempLSB); // Make 16bit TempRAW from 2 8bit reads
Temperature = ((TempRAW * 0.02) - 273.15); // Calculate Device Temperature
return(Temperature);
}
float MLX90615_Read_Object_Temp(int8 Address)
{
TempLSB=0; //Clear variables
TempMSB=0; //Clear variables
TempRAW=0; //Clear variables
i2c_start(); // Start condition
i2c_write(Address*2); // (Slave Address * 2) For R/W bit low for a write
i2c_write(0x27); // Object Temp Register address
i2c_start(); // Restart the bus
i2c_write((Address*2)+1); // (Slave Address * 2) - R/W bit high for a read
TempLSB = i2c_read(); // Read LSB of object temp from register
TempMSB = i2c_read(); // Read MSB of object temp from register
PEC = i2c_read(1); // Read PEC
i2c_stop();
TempRAW = make16(TempMSB,TempLSB); // Make 16bit TempRAW from 2 8bit reads
Temperature = ((TempRAW * 0.02) - 273.15); // Calculate Object Temperature
return(Temperature);
}
int8 MLX90615_Set_Device_Address(int8 Address)
{
TempLSB=0; //Clear variables
TempMSB=0; //Clear variables
TempRAW=0; //Clear variables
i2c_start(); // Start condition
i2c_write(Address*2); // (Slave Address * 2) For R/W bit low for a write
i2c_write(0x27); // Object Temp Register address
i2c_start(); // Restart the bus
i2c_write((Address*2)+1); // (Slave Address * 2) - R/W bit high for a read
TempLSB = i2c_read(); // Read LSB of object temp from register
TempMSB = i2c_read(); // Read MSB of object temp from register
PEC = i2c_read(1); // Read PEC
i2c_stop();
TempRAW = make16(TempMSB,TempLSB); // Make 16bit TempRAW from 2 8bit reads
Temperature = ((TempRAW * 0.02) - 273.15); // Calculate Object Temperature
return(Temperature);
}
|
And I called it from the main program thus :-
Code: |
T_Device = MLX90615_Read_Device_Temp(0x5a); // Get device temp
Delay_ms(20);
T_Object = MLX90615_Read_Object_Temp(0x5a); // Get object temp
|
Hope this helps, and take Ttelmah and Temptronics advice they have both helped me over the years
Jeff |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 22, 2014 3:13 pm |
|
|
This can't be correct. The last i2c read in a sequence is supposed to
issue a NAK. In CCS, this is done by giving it a 0 parameter. You
are giving it a 1, which is an ACK (and is the default).
Quote: | i2c_write((Address*2)+1); // (Slave Address * 2) - R/W bit high for a read
TempLSB = i2c_read(); // Read LSB of object temp from register
TempMSB = i2c_read(); // Read MSB of object temp from register
PEC = i2c_read(1); // Read PEC
i2c_stop();
|
You have this problem in three places. |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
Posted: Mon Dec 22, 2014 3:19 pm |
|
|
Hi PCM
I cant remember why this was but there are nearly 50 of these systems in the field all working with no reported problems
See earlier discussion
Jeff |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Tue Dec 23, 2014 8:23 am |
|
|
Thanks.
Do you think that I should make some configuration before getting the temperature value or it's normal to get directly the temperature value? |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Tue Dec 23, 2014 11:33 am |
|
|
I tried the posted code but I have always 0x00 and 0x00 for the read values. And I should be sure of my hardware which is as follows:
I'm using 3K0 ohm pull-up resistors. So when I check the voltage for SDA and SCL from microcontrollers PIN I found 3.3 V. But when I add the sensor to the circuit, the voltage of the SCL drop to 1.9 V and for the SDA to 0.588 V.
Is it something normal? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Tue Dec 23, 2014 11:46 am |
|
|
Most definately not.
When deselected, the pins on the sensor have an impedance of several meg ohms. The specified worst case leakage current on these pins is 0.25uA. You either have a damaged sensor (330R could have done that), or a wiring error. The current with 330R, was right on the 'absolute maximum rating' for the SCL output. |
|
|
farouk_baya
Joined: 18 Jun 2010 Posts: 27
|
|
Posted: Tue Dec 23, 2014 12:15 pm |
|
|
Yes thanks .
A very bad fault but ..
Hopefully now I can get the slave with the I2C scanner and I get something, not correct value, but I will try to find something.
Thank you |
|
|
|