For the last week, I've been trying to get working a prototype of an IR thermometer, based on MLX90614. I ordered a DCC version, which means a 3 V power supply, medical accuracy (0,5 centigrade in 0 to 50 centigrade area), gradient compensated (compensates package temperature difference), 35 degrees field of view. My idea was to use it as a quick body thermometer, but also have to possibility to measure some interesting places from time to time - walls, windows, heating elements, ...
I try to work incrementally, one step at a time, here is my procedure:
1) Connecting the HW and verifying that it works.
MLX90614 communicates over SMBus, which means I couldn't use my favorite analysis technique - Digilent Analog Discovery 2 | Farnell element14 . I always connect new sensors to the analyzer, power them up (love the feature of integrated power supplies) and apply knowledge from studying the datasheet, how to start measuring or whether only read some output registers.
Maxim (but also other manufacturers) created easy to read comparison of I2C vs SMBus: https://www.maximintegrated.com/en/app-notes/index.mvp/id/476
One important feature of SMBus makes it impossible to "manually" communicate with the sensor - timeout between commands. A write and a following read operation need to be performed within 35 ms. This requires some program code, so I started writing the code for a microcontroller.
However, using an I2C interface in a microcontroller and speed between 10 a 100 kHz work OK.
I can read the temperature registers storing ambient and object temperature and interpret the values. The sensor responsiveness is great.
2) Cyclic Redundancy Check (CRC)
Another difference between I2C and SMBus is, that SMBus uses Packet Error Code (PEC) during communication. So I started studying CRC on Wikipedia.
The sensor supports only "read word" and "write word" commands, the data is always 2 bytes of data and 1 byte of PEC. PEC for is CRC8 with X8+X2+X1+1 polynomial.
I have no idea why, but I can't figure that PEC number.
There are online calculators on the internet that reveal there are many variants for computing CRC: different polynomial length, different polynomial, reflection of input and/or output CRC and finally XORing the output CRC. Wow.
Here is an example of my temperature readings from the sensor:
0x7E 0x39 0xCB
0x7F 0x39 0xDE
Comparing this to the online calculators (polynomial is 0x107 or 0x07 if stored in an 8 bit number, no reflection, no XORing):
Online CRC-8 CRC-16 CRC-32 Calculator says 0xDB for 0x7E39 and 0xCE for 0x7F39
It is probably not a coincidence that I get calculated 0xDB instead of sensor's 0xCB and calculated 0xCE instead of sensor's 0xDE.
I just don't know why.
During searching the internet for some code related to MLX90614, I found out that majority of developers just ignore the PEC. It is not necessary for them to check the data validity.
However, PEC is needed by SMBus for writing data to the sensor. There is one good reason for writing data to the sensor: when you want to change emissivity and in my case, internal gradient compensation factor (or SMBus address, which I don't want to change).
I also found a great introduction with examples on Dr. Ross Williams' webpage. I got the idea of modulo n arithmetic, I can perform the division manually using a pen an a piece of paper, but I can't figure out, how to put this algorithm into C code.
I would appreciate any ideas. Should I be able to write my own (easy to read, but inefficient) algorithm or take some advanced and optimized code from the internet and test it? Should I trust the online calculators for manual verification?