Show Posts
Pages: [1]
1  Using Arduino / Sensors / Re: Melexis MLX90614 thermal sensor - default EEPROM? on: March 04, 2013, 04:50:00 pm
Hello people smiley

I'm writing a (dreadly late) reply just to clarify something:

As Pylon says, I used a different Arduino (a Leonardo) to put together the circuit. However, my error was not having the I2C pins wired incorrectly, but rather the fact that the code (written for the Uno) assumes the serial connection with the PC stays on the whole time during the boot sequence. Alas, on the Leonardo this is NOT true, and as a consequence you miss that nice warning saying "please store these values because you can messup things big time". By the time the serial connection between the board and the arduino was reestablished the damage was already done (the overwriting of the parameters had failed and I didn't have the original values anywhere to restore them). I just added a "wait until serial is established" at the beginning of the code to make sure I didn't miss anything being sent to the PC... and then changed a lot of other things on the code, if just to know what was going on smiley "My" code is the one listed in the original post (compare it against the original one and you'll see some minor differences).

As mentioned before, the original configuration code has a few quirks. Again, as Pylon says, the "problem" is that the coding is not the nicest one. Specifically, Melexis says not to overwrite some of the bits in one of the registers, and the codes overwrite them without making any attempt to read what was there originally. This may be Ok as long as the bits on your sensor are the same as the ones on the sensor the author had, but nothing guarantees that. Please note I did NOT correct this, because I didn't find a way to implement the CRC computation inside the arduino.

I found some other issues with the sequence the code uses to overwrite the registers, but I think it's just cosmetic.
2  Community / Exhibition / Gallery / Re: Cheap-Thermocam | A cheap thermographic camera for everyone ! on: January 02, 2013, 09:48:57 pm
jay_ar

Here are the default values I have for my BCI.

----------Let's begin!----------
*1: Read filter settings:
Filter settings: 40821.00
*2: Read maximum temp settings:
Maximum temp: 39315.00
*3: Read minimum temp settings:
Minimum temp: 25315.00
Done ! Save those values to restore them if necessary.

Thank you! Now I can confirm those numbers are rather standard for these sensors. Now the only doubt remaining is where/how are the calibration values stored. I'm curious about positions 0x03 and 0x09 (Ta Range and "Melexis reserved")

If anyone is curious about these values, I had started a new thread about this:
http://arduino.cc/forum/index.php/topic,138271.msg1043117.html

Thanks!
3  Using Arduino / Sensors / Re: Melexis MLX90614 thermal sensor - default EEPROM? on: December 24, 2012, 04:22:15 am
Ok... the new MLX90614ESF-BCI is in, and the EEPROM dump is done. Here are the relevant registers (the positions that can be written by the user):
00: 9993 -> ToMax
01: 62E3 -> ToMin
02: 0201 -> PWMCTRL
03: F71C -> Ta Range
04: FFFF -> Emissivity
05: 9F75 -> Config register
0E: BE5A -> SMBus address (LSB only)
0F: 0800 -> Melexis reserved
09: D15A -> ????

Almost all of these registers are the same between the two sensors. The only exception at this point is 0x09 (undocumented), where I think the calibration is stored somehow. Which is relevant because once I fed these new numbers into my older sensor it's sort-of-working again... except now the temperature is just 3~4°C off. I can live with that (the important thing for me is the difference between measured temperatures, not the absolute temperature of any particular point), but correcting it would be nice.

Anyway... if anyone decides to post his/her numbers it would be interesting.

I found why one particular memory position wasn't being written. I checked the new values time and time again, including the CRC, and everything looked fine, so I didn't know what was going on. Well... before anything gets written to any register, that register must be zeroed... and that process ALSO has a CRC, which for one particular register (0x01) was not correct in my code. That made the zero-ing to fail, which in turn prevented the new value from being written. After changing the CRC (and another one on the cycling) everything seems to be working fine.

PD: be VERY careful when messing with register 0x05... from the literature changing bit #3 makes the factory calibration to get out of whack


4  Using Arduino / Sensors / Re: Melexis MLX90614 thermal sensor - default EEPROM? on: December 22, 2012, 02:00:07 am
Hello Pylon,

I have no idea, but I think they just have very slight differences. In any case, I ended up buying a new MLX, and the first thing I plan to do is dump all the EEPROM positions. I guess it's Ok to post those numbers here so, if you upload yours, we can know the answer to your question. And help the next person who tries to use the "configuration sketch" with an Arduino Leonardo and/or doesn't write down the numbers smiley

BTW: even if someone decide to use the configuration sketch with an Arduino Uno, there's something somewhat non kosher with the code. Namely, the sketch overwrites 100% of register 0x05, including some bits that MLX recommends not to touch. The correct way to do this would be to read 0x05, and use bitwise AND/OR to set/clear just the bits we need without changing the others. If I decide to change those bits in my new sensor that's what I'll do, anyway.
5  Using Arduino / Sensors / Melexis MLX90614 thermal sensor - default EEPROM? on: December 19, 2012, 04:25:56 pm
I asked this before but I did it in the wrong place (as a comment to an older thread).
Anyway... I'm trying to use a MLX90614 BCI with an Arduino Leonardo. I was able to use it, get measurements, etc. and life was good. But not great.

So I decided to change some of the registers as recommended at http://www.cheap-thermocam.tk/ , using the "configuration sketch" in that page. BIG mistake. That sketch was written for an Arduino Uno (and let's be honest, it's not the finest piece of code), and by the time you can connect to the Leonardo's serial port the information you are supposed to keep is already gone for good. AND... the code produced an error.

It looks like my sensor was flaky to begin with, and the code at that page didn't help much. Now my MLX is completely out of whack, and Melexis won't offer any support (among other things, because "Arduino is not an approved component"  smiley-mad ).

I wonder if someone around here may help me reading the EEPROM from his/her MLX and sending the values to me. There are 32 positions, and although you are not supposed to mess with more than two or three, having the whole thing may help me identify what part of the EEPROM is bad.

I wrote a sketch that dumps EEPROM, RAM, Flags, etc., but I'm not that familiar with the Arduino and I won't feel comfortable asking you to run it on your devices, but if you can dump (or already did dump) your eeprom and send me the default values I would be very grateful. The code is here anyway...

Code:
// Configuration sketch for the MLX90614
// put together by jay_ar. Based on the
// "Configuration Sketch - Version 1.03"
// from www.cheap-thermocam.tk and some other
// examples

#include <i2cmaster.h>
extern volatile unsigned long timer0_millis;

int ledPin = 13;        // Onboard led
boolean ledOn = true;
unsigned long oldTime;

void setup() {
  pinMode(ledPin, HIGH);  // Output
  
  Serial.begin(9600);
  i2c_init();
  digitalWrite(ledPin, HIGH);   // sets the LED on
  oldTime=timer0_millis; // "now"  
}

//To Do: disable overwriting by default
void loop(){
  if (Serial.available() > 0) {  
      switch (Serial.read()) {
        case '1': readEEP(); break;
        case '2': readRAM(); break;
        case '3': measureTemp(); break;
        case '4': readStats(); break;
/* uncomment only if you know what you are doing!
        case '8': changeTmax(); break;
        case '9': changeTmin(); break;
        case '0': changeCtrl(); break;
*/
      }
  }
  if ((timer0_millis - oldTime)>1000){
    ledOn = !ledOn;
    digitalWrite(ledPin,ledOn);
    oldTime = timer0_millis;
    // led blinking = still alive!
  }
}

void readEEP(){
  Serial.println("EEPROM data");
  char S[32];  
  for (int i = 0; i <= (0x1F); i++) {
    unsigned int value = readAddress(0x00,0x20+i);
    sprintf (S,"%02X:\t%04X",i,value);
    Serial.println(S);
  }
}

void readRAM(){
  Serial.println("RAM data");
  char S[32];  
  for (int i = 0; i <= (0x1F); i++) {
    unsigned int value = readAddress(0x00,i);
    sprintf (S,"%02X:\t%04X",i,value);
    Serial.println(S);
  }
}

void measureTemp(){
  unsigned int data_l = 0;
  unsigned int data_h = 0;
  int pec = 0;
  
  i2c_start_wait(0x00+I2C_WRITE);
  i2c_write(0x07);
  i2c_rep_start(0x00+I2C_READ);
  data_l = i2c_readAck(); //Read 1 byte and then send ack
  data_h = i2c_readAck(); //Read 1 byte and then send ack
  pec = i2c_readNak();
  i2c_stop();  

  double tempFactor = 0.02;
  double temp = 0x0000;

  temp = (double)(((data_h & 0x007F) << 8) + data_l);
  temp = (temp * tempFactor)-0.01-273.15;

  char S[32];
  long int temp_i=round(100*temp);
  sprintf(S,"Temp: %s%li.%02li",(temp_i < 0 ? "-" : ""), abs(temp_i / 100), abs(temp_i % 100));
  Serial.println(S);    
}

void readStats(){
  unsigned int data_l = 0;
  
  i2c_start_wait(0x00+I2C_WRITE);
  i2c_write(0xF0);
  data_l = i2c_readAck(); //Read 1 byte and then send ack
  i2c_stop();

  char S[32];
  sprintf(S,"Flags: 0x%02X",data_l);
  Serial.println(S);
}

// This part of the code may brick your MLX!!!
// Use it (uncomment cases 8..0 above) at your own risk
// To do: keep non-relevant bits from 0x05

void changeTmax(){
  Serial.println("Erasing max temp settings...");
  writeAddress(0x00,0x20,0x00,0x00,0x43);
  delay(100);
  Serial.println("Writing new max temp settings...");
  writeAddress(0x00,0x20,0x23,0xFF,0x21);
  cycleMLX(0x00);
  delay(1000);

  char S[32];  
  unsigned int value = readAddress(0x00,0x20+0x00);
  sprintf (S,"Read:\t%04X",value);
  Serial.println(S);  
}

void changeTmin(){
  Serial.println("Erasing min temp settings...");
  writeAddress(0x00,0x21,0x00,0x00,0x28);  // <- Corrected
  delay(100);
  Serial.println("Writing new min temp settings...");
  writeAddress(0x00,0x21,0x5B,0x4F,0x59);
  cycleMLX(0x00);
  delay(1000);

  char S[32];  
  unsigned int value = readAddress(0x00,0x20+0x01);
  sprintf (S,"Read:\t%04X",value);
  Serial.println(S);  
}

void changeCtrl(){
  Serial.println("Erasing filter settings...");
  writeAddress(0x00,0x25,0x00,0x00,0x83);
  delay(100);
  Serial.println("Writing new filter settings...");
  writeAddress(0x00,0x25,0x74,0xB6,0x7E);
  cycleMLX(0x00);
  delay(1000);

  char S[32];  
  unsigned int value = readAddress(0x00,0x20+0x05);
  sprintf (S,"Read:\t%04X",value);
  Serial.println(S);  
}

unsigned int readAddress (int dev, int address){
  unsigned int data_l = 0;
  unsigned int data_h = 0;
  int pec = 0;
  unsigned int data_t = 0;

  i2c_start_wait(dev+I2C_WRITE);
  i2c_write(address);
  i2c_rep_start(dev+I2C_READ);
  data_l = i2c_readAck();
  data_h = i2c_readAck();
  pec = i2c_readNak();
  i2c_stop();
  data_t = (((data_h) << 8) + data_l);
  return data_t;
}

void writeAddress (int dev, int address, int LB, int HB, int pec){
  i2c_start_wait(dev+I2C_WRITE);
  i2c_write(address); // Should have 0x20 added beforehand!
  i2c_write(LB);  // LSB
  i2c_write(HB);  // MSB
  i2c_write(pec); // Checksum
  i2c_stop();
  delay(5);
}

void cycleMLX(int dev){
  i2c_start_wait(dev+I2C_WRITE);
  i2c_write(0xFF);  // Sleep command
  i2c_write(0xF3); // <- Checksum, corrected
  i2c_stop();
  delay(5);
}

[EDIT 12-24] Corrected two bad CRCs
6  Community / Exhibition / Gallery / Re: Cheap-Thermocam | A cheap thermographic camera for everyone ! on: December 19, 2012, 03:08:45 am
Does anyone see any reason why the 5v version would not work? It just seems like it would be so much easier if the 5v-3v3 translation was not needed. ACI version per the data sheet keeps the narrow angle, but is 5v. Every person I see doing this project is using the 3v unit.

The thing is: have you found the ACI anywhere? Digikey lists a lot of these sensors, but no ACI
7  Community / Exhibition / Gallery / Re: Cheap-Thermocam | A cheap thermographic camera for everyone ! on: December 18, 2012, 04:38:48 am
Jose: you can use either the transistor logic-level translators, or the 4.7K pull-up resistors. The first option is the suggested way to do it, but I'm able to work with my MLX90614 BCI using the resistors.

Now the bad news. For me.
I put together the thermocam using an Arduino Leonardo, and tried to run the configuration sketch to improve the quality of the data received. Alas... when you reset the Leonardo, the serial port disappears... meaning that by the time I fired up TheraTerm to "talk" to the arduino the numbers you are supposed to save for later were already gone, and the sketch had already tried -and failed- to overwrite them. After that I added a long pause at the start of the app and was able to catch the full output from the program, but the writing of the registers kept failing. Now my MLX90614 is waaaay off (ice reports -253 celcius or so, skin 120 degrees or something to that tune). The ambient temperature seems to be accurate, but otherwise the sensor just went bonkers.

If there's anyone around here with a MLX90614ESF-BCI that could dump his/her EEPROM data and send it to me I would be extremely grateful. I rewrote the sketch to rewrite the EEPROM registers (now you have to actively request each register to be overwritten, by hand) and I added the option to dump the EEPROM and/or the RAM, so it's just a matter of loading a sketch, dumping the EEPROM and sending me the results. Please smiley-razz ?
Pages: [1]