CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SMBus / I2C Problem
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
farouk_baya



Joined: 18 Jun 2010
Posts: 27

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 11:48 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 12:17 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 12:54 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 1:41 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 2:07 pm     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 2:14 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 2:22 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 2:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 3:13 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 22, 2014 3:19 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 23, 2014 8:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 23, 2014 11:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 23, 2014 11:41 am     Reply with quote

Are you sure you have it connected correctly ? This diagram shows
the MLX90615 pinout from the top of the case:
http://pinout-circuits-images.dz863.com/589/MLX90615.jpg
Make sure you have the correct pin connections.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Dec 23, 2014 11:46 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 23, 2014 12:15 pm     Reply with quote

Yes thanks Smile .

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group