View previous topic :: View next topic |
Author |
Message |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Jan 09, 2012 1:23 pm |
|
|
my 2 cents
with a compiler update
you may find the 18F45Kxx family possibly
to be of some help as well |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Jan 09, 2012 1:27 pm |
|
|
my 2 cents
with a compiler update
you may find the 18F45Kxx family possibly
also tho i have not used it
the 45J50 comes to mind
these may be of some help as well |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
Posted: Mon Jan 09, 2012 1:38 pm |
|
|
Hi Marco
First as someone has already pointed out the PIC should be a 3.3v type I'm not entirley sure that is will work with a 5v PIC
The second from memory there was a "GOTCHA" in the datasheet for the melexis.
I cant access my code for this device (which worked well) until wed or thurs
I will have a look and let you know
Jeff |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
Posted: Mon Jan 09, 2012 1:53 pm |
|
|
Hi Marco
Here is my code for reading the MLX90615
I was able to access it from home !
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);
}
|
This is called by this
Code: |
#include <18f67j60_Trial_RS232.h>
#include <Math.h>
#include <MLX90615.c>
float T_Device1,T_Object1;
float T_Device2,T_Object2;
float T_Device3,T_Object3;
void main()
{
while(true){
Delay_ms (1000);
output_low(LED);
Delay_ms(10);
T_Device1 = MLX90615_Read_Device_Temp(0x5A);
Delay_ms(10);
T_Object1 = MLX90615_Read_Object_Temp(0x5A);
Delay_ms(10);
T_Device2 = MLX90615_Read_Device_Temp(0x5B);
Delay_ms(10);
T_Object2 = MLX90615_Read_Object_Temp(0x5B);
Delay_ms(10);
T_Device3 = MLX90615_Read_Device_Temp(0x5c);
Delay_ms(10);
T_Object3 = MLX90615_Read_Object_Temp(0x5c);
Delay_ms(10);
output_high(LED);
printf("\033[2J");
printf ("Device 1 Temperature = %3.1f\n\r",T_Device1);
printf ("Object 1 Temperature = %3.1f\n\r",T_Object1);
printf ("Device 2 Temperature = %3.1f\n\r",T_Device2);
printf ("Object 2 Temperature = %3.1f\n\r",T_Object2);
printf ("Device 3 Temperature = %3.1f\n\r",T_Device3);
printf ("Object 3 Temperature = %3.1f\n\r",T_Object3);
}}
|
I have had to remove some code so it may not compile
Jeff |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 09, 2012 3:02 pm |
|
|
The code you posted above doesn't do a NACK on the last i2c_read() in
two places. Ttelmah said to do a NACK in the link that you posted.
You are doing this, and it's not a NACK:
That's an ACK, and it's the default. It's the same as if no parameter
was used.
The SMBus spec, on page 20, says that a NACK is required:
Quote: |
• If a master-receiver is involved in the transaction it must signal the end
of data to the slave-transmitter by generating an NACK on the last byte
that was clocked out by the slave. The slave-transmitter must release the
data line to allow the master to generate a STOP condition.
|
Link to spec:
http://smbus.org/specs/
The MLX90615 data sheet doesn't show a NACK on the last byte of a read
operation, but that's probably a mistake in the data sheet. |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Thu Jan 19, 2012 6:03 am |
|
|
Thanks for answers. I have ordered a new IR sensor. Now it works but as output i just get 255.
Can anyone have a look on the timing diagramm? And compare it with my i2c - routine?
In the Datasheet 0x5B is given as slave adress but in internet many say 0xB6. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Jan 19, 2012 8:10 am |
|
|
0X5B, is the _seven bit_ slave address. The byte you send to address a device, is the seven bit slave address, left shifted by one, with the R/W bit below it.
So a device with a 7bit slave address 0f 0x5B, requires the byte 0xB6, to be sent for a 'write', and 0xB7 for a read. If a manufacturer lists a 'pair' of address bytes, then they are doing this for you. If only a single address is given, then it is the seven bit actual address number.
Best Wishes |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Thu Jan 19, 2012 3:04 pm |
|
|
Oh sorry didn't looked on 2nd page
Thanks for all your help.
To JeffLewcock: whats about math.h and MLX90615.c ? |
|
|
JeffLewcock
Joined: 10 Apr 2007 Posts: 29
|
|
Posted: Sat Jan 21, 2012 5:29 pm |
|
|
As Ttelmah has said, you need to left shift the address by one bit, multiplying by 2 does this in my code. You can just shift if you want
As I said this is a small part of a much larger program math.h is not used for the MLX
The MLX90615.c is the code I have posted to read the device. its "included" and called by the main program thus
T_Device1 = MLX90615_Read_Device_Temp(Address);
and
T_Object1 = MLX90615_Read_Object_Temp(Address);
and returns the temperature
Jeff |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Mon Jan 23, 2012 1:21 am |
|
|
Okay I understand but I always get back:
Object/Device 1/2/3 Temperature = -273.15
For the make16 method i use this:
Code: | TempRAW = ( (int16)TempMSB << 8 ) | TempLSB;
Temperature = ((TempRAW * 0.02) - 273.15); // Calculate Object Temperature
return(Temperature); |
The rest of the code is like you posted before.
What's wrong?
Last edited by prixsecco on Mon Jan 23, 2012 5:49 am; edited 1 time in total |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Mon Jan 23, 2012 2:47 am |
|
|
Shouldn't the second i2c_write, i2c_write(0x26) and i2c_write(0x27)
better on address 0x06 and 0x07 ?
Isn't that the address for Ta and To?
Thanks... |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Wed Jan 25, 2012 6:36 pm |
|
|
No idea?
Dont know whats the problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 25, 2012 7:53 pm |
|
|
Quote: | But I always get back:
Object/Device 1/2/3 Temperature = -273.15
Dont know whats the problem.
int8 TempLSB,TempMSB,PEC;
int16 TempRAW;
float Temperature;
TempRAW = ( (int16)TempMSB << 8 ) | TempLSB;
Temperature = ((TempRAW * 0.02) - 273.15); // Calculate Temperature
|
Learn to troubleshoot your program. Put a printf statement after the line
that calculates TempRAW. Put a 2nd print after the line that calculates
the Temperature. Then run the program and see what values are
displayed for each line. This method will show you which line is causing
the problem. |
|
|
prixsecco
Joined: 18 Dec 2011 Posts: 26
|
|
Posted: Fri Jan 27, 2012 11:44 am |
|
|
Sorry.
I've done like you said. All values are "0" (TempMSB,TempLSB,TempRAW) in both methods.
Hyperterminal:
Code: | OBJECT TEMPERATURE:
TempLSB_obj = 0
TempMSB_obj = 0
TempRAW_obj = 0
Object Temperature = -273.15
Device TEMPERATURE
TempLSB_dev = 0
TempMSB_dev = 0
TempRAW_dev = 0
Device Temperature = -273.15 |
So I know why Object and Device Temperature are -273.15 :-)
But whats the reason for getting back always "0" ?
Is the sensor in sleep mode? Could it be that? Haven't understand how to "wake it up". |
|
|
|