Go Down

Topic: MLX90614 - dumping EEPROM data (Read 5372 times) previous topic - next topic

www_MKRD_info

Hello folks,

I would like to dump EEPROM data over I2C from MLX90614 using the I2CMaster library.

I need to change Config Register1 with faster FIR and IIR filter settings. Before I do that I need to be confident that I have saved old data, and that I am accessing correct data.

There are a few posts on this forum which describe something like my problem. If I don't understand the answer, then excuse me. I am having a fever right now, and I might not be thinking strait.


The truncated code below (full code too long to be posted on forum)
Code: [Select]

// Read and Write to Melexis MLX90614 over SMBus
// http://www.MKRD.info/
// 8April2015
// Revision 8

#include <i2cmaster.h> //For Melexis SMBus communication

////////////////////////////////Thermal Infrared sensor variables and constants/////////
int thermal_dev = 0x5A << 1; //Default MLX90614 address in Hex, shifted left by one bit due to I2C protocol

int Emissivity_correction_coefficient_low = 0;  //Initializing low byte of Emissivity_correction_coefficient data
int Emissivity_correction_coefficient_high = 0;  //Initializing high byte of Emissivity_correction_coefficient data
int Emissivity_correction_coefficient = 0;

Config_Register1 decimal: 834
Config_Register1 hex: 342
Config_Register1 binary: 1101000010

int thermal_pec = 0;        //Initializing PEC. TODO check that this is calculated properly, or at least ignored properly

////////////////////////////////////////////////////////////////////////////////////////


void setup()
{

  ////////////////////Initialize I2C  ////////////////////
  i2c_init(); //Initialise the I2C bus
  PORTC = (1 << PORTC4) | (1 << PORTC5); //enable pullups, but this is not necessary as I am using external resistors
  ////////////////////////////////////////////////////////

  Serial.begin(9600);


  //////////////// Read Melexis EEPROM Emissivity_correction_coefficient over SMBUS to obtain default values ////////////////
  /*
  Tomax 0x00
  Tomin 0x01
  PWMCTRL 0x02
  Ta range 0x03
  Emissivity correction coefficient 0x04
  Config Register1 0x05
  SMBus address (LSByte only) 0x0E
  ID number 0x1C
  ID number 0x1D
  ID number 0x1E
  ID number 0x1F
  */

  i2c_start_wait(thermal_dev + I2C_WRITE);
  i2c_write(0b00100000 | 0x04);  //0b00100000 for EEPROM ACCESS

  // read
  i2c_rep_start(thermal_dev + I2C_READ);
  Emissivity_correction_coefficient_low = i2c_readAck(); //Read 1 byte and then send ack
  Emissivity_correction_coefficient_high = i2c_readAck(); //Read 1 byte and then send ack
  thermal_pec = i2c_readNak();
  i2c_stop();

  //This converts high and low bytes together - moves it left 8 bits and adds the low byte.
  Emissivity_correction_coefficient = ((Emissivity_correction_coefficient_high << 8) | Emissivity_correction_coefficient_low);

  Serial.println();
  Serial.print("Emissivity_correction_coefficient decimal: ");
  Serial.print(Emissivity_correction_coefficient, DEC);
  Serial.println();
  Serial.print("Emissivity_correction_coefficient hex: ");
  Serial.print(Emissivity_correction_coefficient, HEX);
  Serial.println();
  Serial.print("Emissivity_correction_coefficient binary: ");
  Serial.print(Emissivity_correction_coefficient, BIN);
  Serial.println();
 
//  printf("Printf: %x", Emissivity_correction_coefficient);


  /////////////////END of Read Melexis EEPROM over SMBUS to obtain default values/////////////////////////////////////////////


  //////////////// Read Melexis EEPROM Config_Register1 over SMBUS to obtain default values ////////////////
  /*
  Tomax 0x00
  Tomin 0x01
  PWMCTRL 0x02
  Ta range 0x03
  Emissivity correction coefficient 0x04
  Config Register1 0x05
  SMBus address (LSByte only) 0x0E
  ID number 0x1C
  ID number 0x1D
  ID number 0x1E
  ID number 0x1F
  */

  i2c_start_wait(thermal_dev + I2C_WRITE);
  i2c_write(0b00100000 | 0x05);  //0b00100000 for EEPROM ACCESS

  // read
  i2c_rep_start(thermal_dev + I2C_READ);
  Config_Register1_low = i2c_readAck(); //Read 1 byte and then send ack
  Config_Register1_high = i2c_readAck(); //Read 1 byte and then send ack
  thermal_pec = i2c_readNak();
  i2c_stop();

  //This converts high and low bytes together - moves it left 8 bits and adds the low byte.
  Config_Register1 = (Config_Register1_high << 8) | Config_Register1_low;

  Serial.println();
  Serial.print("Config_Register1 decimal: ");
  Serial.print(Config_Register1, DEC);
  Serial.println();
  Serial.print("Config_Register1 hex: ");
  Serial.print(Config_Register1, HEX);
  Serial.println();
  Serial.print("Config_Register1 binary: ");
  Serial.print(Config_Register1, BIN);
  Serial.println();

  /////////////////END of Read Melexis EEPROM over SMBUS to obtain default values/////////////////////////////////////////////

}


void loop() //MAIN LOOP
{

}//LOOPING







Produces this output:
Code: [Select]


Tomax decimal: -26221
Tomax hex: FFFF9993
Tomax binary: 11111111111111111001100110010011

Tomin decimal: 25315
Tomin hex: 62E3
Tomin binary: 110001011100011

PWMCTRL decimal: 513
PWMCTRL hex: 201
PWMCTRL binary: 1000000001

Ta_range decimal: -2276
Ta_range hex: FFFFF71C
Ta_range binary: 11111111111111111111011100011100

Emissivity_correction_coefficient decimal: -1
Emissivity_correction_coefficient hex: FFFFFFFF
Emissivity_correction_coefficient binary: 11111111111111111111111111111111

Config_Register1 decimal: -24652
Config_Register1 hex: FFFF9FB4
Config_Register1 binary: 11111111111111111001111110110100

SMBus_address_LSByte_only decimal: -16806
SMBus_address_LSByte_only hex: FFFFBE5A
SMBus_address_LSByte_only binary: 11111111111111111011111001011010

ID_number_C decimal: 12
ID_number_C hex: C
ID_number_C binary: 1100

ID_number_D decimal: 19171
ID_number_D hex: 4AE3
ID_number_D binary: 100101011100011

ID_number_E decimal: 29064
ID_number_E hex: 7188
ID_number_E binary: 111000110001000

ID_number_F decimal: -20280
ID_number_F hex: FFFFB0C8
ID_number_F binary: 11111111111111111011000011001000




What I don't understand is how can I have a 32-bit long output from Serial.print() if I am reading two bytes, and combining them into an integer???

For reference, I am expecting Emissivity_correction_coefficient hex: to be FFFF


Some other posts which talk about a similar issue:

http://forum.arduino.cc/index.php?topic=55524.0
http://forum.arduino.cc/index.php?topic=138271.0
http://forum.arduino.cc/index.php?topic=162324.0
http://forum.arduino.cc/index.php?topic=297725.15

I would like to understand what's going on, instead of copy-pasting someone else's code.

nickgammon

Quote
The truncated code below (full code too long to be posted on forum)
You can attach code to posts.

Quote
What I don't understand is how can I have a 32-bit long output from Serial.print() if I am reading two bytes, and combining them into an integer???
That's a printing artifact, nothing more.  Negative numbers are sign-extended to the left, giving you the illusion of lots of 1 bits.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

johnwasser

To get rid of the printing artifacts use unsigned values.  To save on code the .print(char) and .print(int) functions just pass the value on to .print(long), causing the sign extension.  The .print(unsigned char) and .print(unsigned int) functions just pass the value on to .print(unsigned long) so no sign extension is done.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp
See who has no social life: https://forum.arduino.cc/index.php?action=stats :)

www_MKRD_info

To get rid of the printing artifacts use unsigned values.
I will try unsigned int next. Thank you for the tip. Actually, I tried using uint16 but I did not see improvement. I will try again.


The .print(unsigned char) and .print(unsigned int) functions just pass the value on to .print(unsigned long) so no sign extension is done.
I don't understand this part. How can I put what you said into code? How can I print values without type casting them into signed long?

nickgammon

#4
Apr 17, 2015, 11:31 pm Last Edit: Apr 17, 2015, 11:32 pm by Nick Gammon
Code: [Select]
unsigned int foo = 0x9993;
void setup ()
  {
  Serial.begin (115200);
  Serial.println (foo, HEX);
  }  // end of setup
void loop () { }


That printed 9993 for me without any leading Fs.

Please post (or attach) any amended code you are still having problems with.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

www_MKRD_info

.print(int) just calls .print(long).  This causes a sign extension to 32 bits which is a problem in BIN and HEX formats.  If you cast the value to 'unsigned' it will call .print(unsigned) which will call .print(unsigned long) and therefore no sign extension.

www_MKRD_info

#6
Apr 18, 2015, 01:19 am Last Edit: Apr 18, 2015, 04:55 am by www_MKRD_info
Although there appears to be working code available here:
http://forum.arduino.cc/index.php?topic=138271.0
I learn by doing things myself, and not by copy-pasting. Therefore:

Objective:
I have a Melexis MLX90614ESF-ACF-000-TU with a default settling time of 1.33 seconds. I need to (if it is not already - I have not even been able to verify this) set the Object Temperature maximum range to 380C, and reduce settling time to 0.1 seconds. I have a cheaper sensor to experiment on (MLX90614ESF-ACA-000-TU).

I have created a reference data package with datasheet and application notes:
http://mkrd.info/uploads/tmp/Melexis_MLX90614.zip


(you can use Digi-Key.com to look up part numbers for data and datasheets, and Melexis.com for application notes).



I will try to create an article here (WITH YOUR HELP!) on a detailed procedure to:

1. Read EEPROM contents (as shown on page 11 of datasheet)
2. Save bit-accurate EEPROM contents so that contents can be recovered if I mess up
3. Match EEPROM contents to data from section "8.3.3 EEPROM" of the datasheet. Datasheet is not very helpful for explaining default values. Hence requirement to save data first. I need to understand things that I am modifying.
4. Pick correct data to write into EEPROM to have 380C range, 0.1second settling time.
5. Erase contents as instructed by datasheet for EEPROM, and write bit-accurate data without modifying any contents which are not being changed (by using bit masking, etc). I have stopped working on a solution myself because given my confusing sign-extended results, I am not absolutely sure I am reading data correctly.
6. Supply a valid PEC to the chip. I have read articles on PEC, but I need working Arduino code to generate PEC given an arbitrary data to compute it against.

www_MKRD_info

Using unsigned int, this is the output. Much better now that one's complement is no longer a problem. I now need to match these values to what the datasheet says.

Code: [Select]

Tomax decimal: 39315
Tomax hex: 9993
Tomax binary: 1001100110010011

Tomin decimal: 25315
Tomin hex: 62E3
Tomin binary: 110001011100011

PWMCTRL decimal: 513
PWMCTRL hex: 201
PWMCTRL binary: 1000000001

Ta_range decimal: 63260
Ta_range hex: F71C
Ta_range binary: 1111011100011100

Emissivity_correction_coefficient decimal: 65535
Emissivity_correction_coefficient hex: FFFF
Emissivity_correction_coefficient binary: 1111111111111111

Config_Register1 decimal: 47088
Config_Register1 hex: B7F0
Config_Register1 binary: 1011011111110000

SMBus_address_LSByte_only decimal: 48730
SMBus_address_LSByte_only hex: BE5A
SMBus_address_LSByte_only binary: 1011111001011010

ID_number_C decimal: 33803
ID_number_C hex: 840B
ID_number_C binary: 1000010000001011

ID_number_D decimal: 28634
ID_number_D hex: 6FDA
ID_number_D binary: 110111111011010

ID_number_E decimal: 38020
ID_number_E hex: 9484
ID_number_E binary: 1001010010000100

ID_number_F decimal: 45314
ID_number_F hex: B102
ID_number_F binary: 1011000100000010

www_MKRD_info

Some physical details about I2C:

1) After a week of effort, I could not get Wire library to work with Repeated Start that this sensor requires. I2CMaster works with Repeated Start and is easy to use.

2) Built-in I2C pull-up resistors are very weak. I recommend supplementing with external discrete 10k resistors.

3) I2C Address requires you to shift left by one bit the sensor address in Hex as found in the datasheet (due to I2C protocol).
You can either code with the address bit-shifted beforehand, or for ease of understanding do:
Code: [Select]
unsigned int thermal_dev = 0x5A << 1; //Default MLX90614 address in Hex, shifted left by one bit due to I2C protocol

4) Remote wiring of the sensor over a long wire run can make issues. I initially had issues talking to the sensor over 1 ft of tightly coupled (wires next to each other) wire harness. Oscilloscope placed on Data and Clock lines were showing signal corruption. Re-wiring, shortening wire length, and strengthening (reducing value of) pull-up resistor allowed me to communicate.

5) JIC the question came to you too - I2CMaster communicates over same I2C Arduino pins as Wire.h. It is not possible to communicate over some other Arduino pins.


nickgammon

Can you confirm the chip is responding by using my I2C scanner on this page: http://www.gammon.com.au/i2c
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

www_MKRD_info

Can you confirm the chip is responding by using my I2C scanner on this page: http://www.gammon.com.au/i2c

Can you confirm the chip is responding by using my I2C scanner on this page: http://www.gammon.com.au/i2c

I am just documenting my experiences for others who find this forum thread. I am way past the point of I2C device identification, and some other code of my robot is already reading sensor temperature without any issues. I2CMaster code to read Melexis MLX90614 posted in other locations on the forum works just fine. Now I need to re-configure the sensor so that it responds faster.

www_MKRD_info

After a day's worth of effort, code is almost complete.

One last part is calculation of PEC CRC.

My previous effort searching rest of Internet was not fruitful.

However, this forum has a couple posts on the topic of PEC CRC calculation:

http://forum.arduino.cc/index.php?topic=58509.0

http://forum.arduino.cc/index.php?topic=54170.0


I will post complete code when I have tested it.

www_MKRD_info

Nick Gammon was nice to write a function to calculate PEC CRC-8.

I have edited it to make it into a calculator instead of a I2C writing tool:

Code: [Select]
// I2C PEC (Packet Error Code) CRC-8 (Cyclic Redundancy Check, 8 bits) calculator
// Calculates a
// CRC-8 with polynomial X8+X2+X1+1.

// Originally written by Nick Gammon
// Modified by http://www.MKRD.info/
// V1 18 April 2015

byte crc8(byte *addr, byte len)
{
  byte crc = 0;
  while (len--) {
    byte inbyte = *addr++;
    for (byte i = 8; i; i--)
    {
      byte carry = (crc ^ inbyte) & 0x80;
      crc <<= 1;
      if (carry)
        crc ^= 0x7;
      inbyte <<= 1;
    }
  }
  return crc;
}  // end of crc8

#define ADDRESS 0x00    // device address

#define COMMAND (0b00100000 | 0b00001110)   // command to act on

#define LOW_BYTE 0x5A      // LOW_BYTE of data

#define HIGH_BYTE 0x00      // HIGH_BYTE of data


void setup ()
{

  Serial.begin (9600);
  Serial.println ();

  byte buf [] = {ADDRESS << 1, COMMAND, LOW_BYTE, HIGH_BYTE};  //Concatenate parts of I2C packet into one variable

  byte crc = crc8 (buf, sizeof buf);

  Serial.print ("Calculated CRC is: 0x");
  Serial.println (crc, HEX);

}  // end of setup

void loop () {}

www_MKRD_info

#13
Apr 19, 2015, 02:44 am Last Edit: Apr 19, 2015, 03:35 am by www_MKRD_info
I have a bug somewhere in my code, as new values are not written. Another pair of eyes on my code would be appreciated:

Code: [Select]
// Read and Write to Melexis MLX90614 Config Register1 0x05 over SMBus
// http://www.MKRD.info/
// 18April2015
// Revision 6

#include <i2cmaster.h> //For Melexis SMBus communication

//Thermal Infrared sensor variables and constants//
//Variables below must be unsigned to prevent sign extension and one's complement representation.
unsigned int i2c_device_address = 0x5A << 1; //Default MLX90614 address in Hex, shifted left by one bit due to I2C protocol

unsigned int Config_Register1_low = 0;  //Initializing low byte of Config_Register1 data
unsigned int Config_Register1_high = 0;  //Initializing high byte of Config_Register1 data
unsigned int Config_Register1 = 0;
byte Config_Register1_write_low = 0;
byte Config_Register1_write_high = 0;

unsigned int thermal_pec = 0;        //Initializing PEC. TODO check that this is calculated properly, or at least ignored properly

//


void setup()
{

  //Initialize I2C  //
  i2c_init(); //Initialise the I2C bus
  PORTC = (1 << PORTC4) | (1 << PORTC5); //enable pullups, but this is not necessary as I am using external resistors
  //

  Serial.begin(9600);

  //Notify user of what this program does
  Serial.println("This utility reads (and optionally modifies) contents of");
  Serial.println("Melexis MLX90614 thermal transducer EEPROM Config Register1");
  Serial.println("Reading old data present in EEPROM Config Register1:");

  // Read Melexis EEPROM Config_Register1 over SMBUS to obtain default values //
  /*  Config Register1 0x05    */

  i2c_start_wait(i2c_device_address + I2C_WRITE);
  i2c_write(0b00100000 | 0x05);  //0b00100000 for EEPROM ACCESS

  // read
  i2c_rep_start(i2c_device_address + I2C_READ);
  Config_Register1_low = i2c_readAck(); //Read 1 byte and then send ack
  Config_Register1_high = i2c_readAck(); //Read 1 byte and then send ack
  thermal_pec = i2c_readNak();
  i2c_stop();

  //This converts high and low bytes together - moves it left 8 bits and adds the low byte.
  Config_Register1 = (Config_Register1_high << 8) | Config_Register1_low;

  //  Serial.println();
  //  Serial.print("Config_Register1 decimal: ");
  //  Serial.print(Config_Register1, DEC);
  //  Serial.println();
  //  Serial.print("Config_Register1 hex: ");
  //  Serial.print(Config_Register1, HEX);
  Serial.println();
  Serial.print("Config_Register1 binary: ");
  Serial.print(Config_Register1, BIN);
  Serial.println();

  //PRINT FIR AND IIR SEPARATELY

  Serial.print("Old IIR: ");
  Serial.print(bitRead(Config_Register1, 10));
  Serial.print(bitRead(Config_Register1, 9));
  Serial.print(bitRead(Config_Register1, 8));

  Serial.println();
  Serial.print("Old FIR: ");
  Serial.print(bitRead(Config_Register1, 2));
  Serial.print(bitRead(Config_Register1, 1));
  Serial.print(bitRead(Config_Register1, 0));

  Serial.println();
  Serial.println();
  Serial.println("Please copy-paste and/or write down the values");
  Serial.println("As these may be overwritten irrevocably!");


  //TODO SAVE RESULTS IN FILE

  /////////////////END of Read Melexis EEPROM over SMBUS to obtain default values/////////////////////////////////////////////


  //Prompt user about whether new value is to be written//
  Serial.println();
  Serial.println("Do you wish to write to EEPROM");
  Serial.println("The following settings");
  Serial.println("For fastest settling time?");
  Serial.println("EEPROM IIR and FIR settings will be overwritten irrevocably!");
  Serial.println("Please copy-paste and/or write down the values");
  Serial.println();
  Serial.println("New settings which can be written:");
  Serial.println("IIR setting: 100  FIR setting: 100");
  Serial.println("Settling time (90614xCx) (s): 0.06");
  Serial.println("Settling time (90614xAx) (s): 0.04");
  Serial.println("Spike limit: 100.00% (none)");
  Serial.println("Press Y to write to EEPROM, N or any other button to Exit.");


  //RUN IN LOOP UNTIL NO INPUT, THEN ONLY RUN ONCE
  boolean keep_looping = true;
  while (keep_looping) {
    if (Serial.available() > 0) {
      switch (Serial.read()) {
        case 'Y': {
            WriteToEEPROM();
            keep_looping = false;
            break;
          }
        case 'N': {
            Serial.println("Not changing contents of EEPROM...");
            keep_looping = false;
            break;
          }
        default: {
            Serial.println("Not changing contents of EEPROM...");
            keep_looping = false;
            break;
          }
      }
    }
  }
}


void loop() //MAIN LOOP
{
  //TODO enter low-power mode
}//LOOPING!

void WriteToEEPROM() {

  Serial.println("Preparing to write to EEPROM...");

  Config_Register1_write_low = byte(Config_Register1);

  Config_Register1_write_high = Config_Register1 >> 8;

  Serial.println();
  Serial.println("Splitting unsigned integer into two bytes");
  Serial.print("Config Register1 low byte  ");
  Serial.print(Config_Register1_write_low, BIN);
  Serial.println();
  Serial.print("Config Register1 high byte ");
  Serial.print(Config_Register1_write_high, BIN);

  //CLEAR BITS FOR FIR AND IIR

  //00000100  00000100
  //     FIR       IIR

  Config_Register1_write_low = Config_Register1_write_low & B11111000;
  Config_Register1_write_high = Config_Register1_write_high & B11111000;

  Serial.println();
  Serial.println();
  Serial.println("Clearing bits for FIR and IIR:");
  Serial.print("Config Register1 low byte  ");
  Serial.print(Config_Register1_write_low, BIN);
  Serial.println();
  Serial.print("Config Register1 high byte ");
  Serial.print(Config_Register1_write_high, BIN);


  //SET NEW BITS
  //00000100  00000100
  //     FIR       IIR
  //Config_Register1_write

  Config_Register1_write_low = Config_Register1_write_low | B00000100;
  Config_Register1_write_high = Config_Register1_write_high | B00000100;

  Serial.println();
  Serial.println();
  Serial.println("New values for Config Register1:");
  Serial.print("Config Register1 low byte  ");
  Serial.print(Config_Register1_write_low, BIN);
  Serial.println();
  Serial.print("Config Register1 high byte ");
  Serial.print(Config_Register1_write_high, BIN);


  //WRITE ZERO

  Serial.println();
  Serial.println();
  Serial.println("Erasing EEPROM Config Register1 location...");

  byte zeroing_buffer[] = {i2c_device_address << 1, (0b00100000 | 0x05), B00000000, B00000000};  //Concatenate parts of I2C packet into one variable

  byte zeroing_crc = crc8(zeroing_buffer, sizeof zeroing_buffer);

  Serial.println();
  Serial.println();
  Serial.print("Calculated Zeroing CRC is: 0x");
  Serial.print(zeroing_crc, HEX);

  i2c_start_wait(i2c_device_address + I2C_WRITE);
  i2c_write(0b00100000 | 0x05);  //0b00100000 for EEPROM ACCESS
  i2c_write(B00000000);  // Zero out low byte of EEPROM location
  i2c_write(B00000000);  // Zero out high byte of EEPROM location
  i2c_write(zeroing_crc); // Checksum
  i2c_stop();
  delay(50);    //Wait for ten times the recommended value of 5ms.


  //WRITE BYTES and PEC, Wait

  byte calculation_buffer[] = {i2c_device_address << 1, (0b00100000 | 0x05), Config_Register1_write_low, Config_Register1_write_high};  //Concatenate parts of I2C packet into one variable

  byte calculated_crc = crc8(calculation_buffer, sizeof calculation_buffer);

  Serial.println();
  Serial.println();
  Serial.print("Calculated Writing CRC is: 0x");
  Serial.print(calculated_crc, HEX);

  Serial.println();
  Serial.println();
  Serial.println("Writing new data into EEPROM Config Register1 location...");
  i2c_start_wait(i2c_device_address + I2C_WRITE);
  i2c_write(0b00100000 | 0x05);  //0b00100000 for EEPROM ACCESS
  i2c_write(Config_Register1_write_low);  // Write low byte to EEPROM location
  i2c_write(Config_Register1_write_high);  // Write high byte to EEPROM location
  i2c_write(calculated_crc); // Checksum
  i2c_stop();
  delay(50);    //Wait for ten times the recommended value of 5ms.


  //TELL USER TO CYCLE POWER
  //Since Sleep mode is not available for the 5V supply version
  Serial.println();
  Serial.println();
  Serial.println("You must now cycle power to the sensor/board");
  Serial.println("Since Sleep mode is not available for the 5V supply version");

  //Stop I2C
  //i2c_stop();
  //STOP SERIAL
  Serial.flush();
  Serial.end();

}//RETURNS BACK TO ORIGINAL FUNCTION!


byte crc8(byte *addr, byte len)
//The PEC calculation includes all bits except the START, REPEATED START, STOP, ACK, and NACK bits. The PEC is a CRC-8 with polynomial X8+X2+X1+1.
{
  byte crc = 0;
  while (len--) {
    byte inbyte = *addr++;
    for (byte i = 8; i; i--)
    {
      byte carry = (crc ^ inbyte) & 0x80;
      crc <<= 1;
      if (carry)
        crc ^= 0x7;
      inbyte <<= 1;
    }
  }
  return crc;
}  // end of crc8



www_MKRD_info

#14
Apr 19, 2015, 02:45 am Last Edit: Apr 19, 2015, 03:33 am by www_MKRD_info
Produces:

Code: [Select]
This utility reads (and optionally modifies) contents of
Melexis MLX90614 thermal transducer EEPROM Config Register1
Reading old data present in EEPROM Config Register1:

Config_Register1 binary: 1001111110110100
Old IIR: 111
Old FIR: 100

Please copy-paste and/or write down the values
As these may be overwritten irrevocably!

Do you wish to write to EEPROM
The following settings
For fastest settling time?
EEPROM IIR and FIR settings will be overwritten irrevocably!
Please copy-paste and/or write down the values

New settings which can be written:
IIR setting: 100  FIR setting: 100
Settling time (90614xCx) (s): 0.06
Settling time (90614xAx) (s): 0.04
Spike limit: 100.00% (none)
Press Y to write to EEPROM, N or any other button to Exit.
Preparing to write to EEPROM...

Splitting unsigned integer into two bytes
Config Register1 low byte  10110100
Config Register1 high byte 10011111

Clearing bits for FIR and IIR:
Config Register1 low byte  10110000
Config Register1 high byte 10011000

New values for Config Register1:
Config Register1 low byte  10110100
Config Register1 high byte 10011100

Erasing EEPROM Config Register1 location...


Calculated Zeroing CRC is: 0x66

Calculated Writing CRC is: 0xA0

Writing new data into EEPROM Config Register1 location...


You must now cycle power to the sensor/board
Since Sleep mode is not available for the 5V supply version


IIR and FIR are not changed after power is cycled...

Go Up