Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Interfacing / Re: Melexis SMBus IR Thermometer - NFI on: October 13, 2008, 04:21:05 pm
The device could not accept a stop/start condition transmission during a transaction. From what I understand, you cannot send a repeated start condition in the wire library without first sending a stop condition. This does not work with the smbus device I was using. I don't know if the device is out of spec or the wire simply doesn't support all smbus communication protocols.
2  Forum 2005-2010 (read only) / Interfacing / Re: Melexis SMBus IR Thermometer - NFI on: August 22, 2008, 06:25:26 am
OK,

Well I got it working using a different library. It appears wiring cannot do it.

I used Peter Fleurys libray here:

http://homepage.hispeed.ch/peterfleury/avr-software.html

Scroll down and download the i2c master libraries.  Create a folder in /{arduino root}/hardware/libraries and copy the
i2cmaster.h and which .c file you want (it supports hardware and software i2c, I only used the hardware one twimaster.c).

You need to change the .c file to .cpp (otherwise it won't link when compiling) and don't forget to change some of the values
in the .h and .c file depending on your mcu etc.

Once you load arduino ide, it should build a .o file in the folder you created and then you can import the library from the menu or put in
your code:
Code:
#include <i2cmaster.h>

Then write your program, the help file lists all the functions available and it worked on the first try for me. So I can say this library works for smbus devices.  Here's my sample code using the library (NB: You must bit shift left whatever your device address is):

Code:
//Simple program to read data from smbus device and convert from degrees kelvin to degrees C and print to serial port.

#include <i2cmaster.h>

void setup()
{
  Serial.begin(9600);
  i2c_init();  //Initialise the i2c bus
  
}
void loop()
{
  int dev = 0x5A<<1; [b]//Address must be bit shifted left, library does not automatically do it[/b]
  int data_low = 0;
  int data_high = 0;
  int pec = 0;
  i2c_start_wait(dev+I2C_WRITE); //send start condition and write bit
  i2c_write(0x07); //send command for device to action
 
  
  i2c_rep_start(dev+I2C_READ); //send repeated start condition, device will ack
  data_low = i2c_readAck();  //Read 1 byte and then send ack
  data_high = i2c_readAck(); //Read 1 byte and then send ack
  pec = i2c_readNak(); //Read error check byte and send Nack to tell device no more data to send
  i2c_stop(); //Release bus, end transaction
  
 //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
   double tempFactor = 0.02; // 0.02 degrees per LSB
    int tempData = 0x0000;
    
// This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
    tempData = (int)(((data_high & 0x007F) << 8) + data_low);
    tempData = (tempData * tempFactor)-0.01;
    tempData = tempData - 273.15;
    Serial.println(tempData); //Print temp in degrees C to serial
    delay(1000);
}



Hope this can help somebody with i2c and smbus devices. It is a very simple library to use. His website I think only has limited traffic per day so it might not be available all the time.
3  Forum 2005-2010 (read only) / Interfacing / Re: Melexis SMBus IR Thermometer - NFI on: August 04, 2008, 10:58:47 pm
Hi again,

I have had contact with the manufacturer of the device who has agreed that the stop bit should not be in there after the command only a repeated start condition.  Does anyone know how to send only a repeated start condition and not a stop/start condition using the wire library?

I need it to look like this:

Start Condition
Send Slave Address
Get ACK
Send Command
Get ACK
Send Repeated Start Condition (This is where I stuff up now)
Send Slave Address
Get ACK
Receive 3 bytes (Data Hi, Data Low, Error Check Byte)
Send Stop Condition.

I CANNOT GET THE WIRE LIBRARY TO DO THIS. PLEASE HELP IF YOU CAN.
4  Forum 2005-2010 (read only) / Interfacing / Re: Melexis SMBus IR Thermometer - NFI on: July 26, 2008, 10:35:40 pm
Hi,

Still working on this. I made a logic analyser from a website I found and managed to get a clock diagram of what is happening:



I think the issue is the stop bit after the send command. Reading the pseudocode I posted above it doesn't mention a stop bit so I am not sure if this is stuffing it up.  All I know is
that I shouldn't be getting 255,255,255 as the three bytes.  Reading the melexis forums (whom made the ir thermometer) they mention that a 0xFF suggests a timing issue.

I also read this on the SMBus spec sheet:

"Specific SMBus protocols require the master to generate a repeated START condition followed by the
slave device address without first generating a STOP condition."

I think, from my timing diagram, this is exactly what I am doing.

Please can anyone suggest how I would use the wire library but stop sending that stop bit halfway through until all the 3 bytes (low,high and PEC) are recieved.

Many thanks.

Current Code:

Code:
#include <Wire.h>
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
void loop()
{
  int SA = 0x5A;  // The Slave Address, shitfed one bit left.
                         // Try 0x5A if this doesn't work or 0x00
  //byte CMD = 00101110;       // The read RAM address 0x07 command.
  byte Expected = 0x03;   // we are expecting to get 3 bytes back
 
  Wire.beginTransmission(SA); // Open a connection to slave device
  Wire.send(0x03);
  Wire.endTransmission();
  
  Wire.beginTransmission(SA);
  Wire.requestFrom(0x5A, 2);    // request 6 bytes from slave device #2
 
  while(Wire.available())    // slave may send less than requested
  {
    int c = Wire.receive(); // receive a byte as character
    Serial.print(c);         // print the character
  }
  Wire.endTransmission();
    
}




5  Forum 2005-2010 (read only) / Interfacing / Re: Melexis SMBus IR Thermometer - NFI on: July 13, 2008, 04:27:19 am
Ok, still no luck with this thing but this is the code I am using:

Code:

#include <Wire.h>
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
void loop()
{
  byte SA = 0x00;  // The Slave Address, melexis docs says all units will respond to 0 address
                         // Try 0x5A if this doesn't work or 0x00
  byte CMD = 0x07;       // The read RAM address 0x07 command.
  byte Expected = 0x03;   // we are expecting to get 3 bytes back
 
  Wire.beginTransmission(SA); // Open a connection to slave device
  Wire.send(CMD);             // Transmit the command.
  Wire.endTransmission();     // stop transmitting
 
  Wire.requestFrom(SA, Expected);    // request 3 bytes from slave device #0
  while(Wire.available())    // slave may send less than requested
  {
    int c = Wire.receive(); // receive a byte as integer
    Serial.print(c);         // print the int
  }
  delay(500);
}

Thes Melexis SMBus transfer datasheet shows this as the communication psuedocode:

Pseudo code example: Reading RAM address 0x07 (Tobj1)
1. Send START bit
2. Send Slave Address (0x00* for example) + Rd\-Wr bit**
3. Send Command (0b000x_xxxx + 0b0000_0111 -> 0b0000_0111)
4. Send Repeated START_bit
5. Send Slave Address + Rd\-Wr bit**
6. Read Data Byte Low (master must send ACK bit)
7. Read Data Byte High (master must send ACK bit)
8. Read PEC (master can send ACK or NACK)
9. Send STOP bit
Note* : Any MLX90614 will respond to address 0x00
Note**: Bit Rd\-Wr has no meaning for MLX90614

My question is, does my above code accurately reflect what the pseudo code ( supplied by melexis) is demonstrating. When I compile and run this code all
I get is 700  ( 7 first byte - data byte low, 0 data byte low, 0 PEC).  The 7 however is just the command I sent it in the fist place.

Please help.
6  Forum 2005-2010 (read only) / Interfacing / Melexis SMBus IR Thermometer - NFI on: June 30, 2008, 07:37:13 pm
Hi,  

I have entered the world of Arduino and have gone through some tutorials and have picked up the language ok. I also purchased a Melexis IR Thermometer model # MLX90614ESF-AAA. It uses a SMBus data connection and from my reading its the same as I2c. This unit however only supports the commands read word and write word. I've been playing with the Wire library to get it to read data from the device but I'm not having much luck.   Specifically the problem is working out how to send a command to the unit and how the ram addressing and eeprom addressing works.

I'd appreciate it if anybody could give me some clues and have a quick read of the spec sheets from the melexis website
http://www.melexis.com/Sensor_ICs_Infrared_and_Optical/Infrared/Digital_plug__play_infrared_thermometer_in_a_TO-can_615.aspx

Its got some assembler examples there but I would like to use the Wire library to do talk to this thing.  The spec sheets says the default SMBus address is 0x5A (90) but then I read in the wire library the addressing is using only the top 7 digits so it becomes 45. Is this right?  I can get numbers back from the device but I don't know what they mean, I'm supposed to be reading the temperatures from the device but I don't think thats what I'm doing.

I think if it I just got on the right track with how to communicate to this thing I should be ok.

Any help would be soooo appreciated.
Pages: [1]