Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[i2c] MLX90614 #1694

Closed
andriyadi opened this issue Jul 28, 2018 · 17 comments
Closed

[i2c] MLX90614 #1694

andriyadi opened this issue Jul 28, 2018 · 17 comments

Comments

@andriyadi
Copy link

Hardware:

Board: Custom board
Core Installation/update date: Latest master
IDE: esp-idf with Arduino as component

Description:

I'm having issue with MLX90614 sensor. Using latest core and this Arduino code, it doesn't work anymore. If using previously I2C, before @stickbreaker I2C code merged to master, it all works fine on the very same board. So, the issue is clearly not hardware.

What I meant by "doesn't work" is that the data returned by Wire.read() never be right. Using previous I2C code, it return expected values.

I've tried two libs:
https://github.com/adafruit/Adafruit-MLX90614-Library
https://github.com/sparkfun/SparkFun_MLX90614_Arduino_Library
both not working.

Sketch:

Using examples on both libraries

What I did:

Tried to change clock varying from 10KHz to 100KHz doesn't help (the sensor supports that range). Also changing timeout doesn't help.

Tried to change Adafruit's library to this:

  uint16_t ret;

  Wire.beginTransmission(_addr); // start transmission to device 
  Wire.write(a); // sends register address to read from
  uint8_t err = Wire.endTransmission(false); // end transmission
  if( err!=7){ // something went wrong
    Serial.printf("Error setting register pointer =%d (%s)",Wire.lastError(),Wire.getErrorText(Wire.lastError()));
  }

  uint8_t cnt = Wire.requestFrom(uint8_t(_addr), (uint8_t)3);// send data n-bytes read

  ret = Wire.read(); // receive DATA
  ret |= Wire.read() << 8; // receive DATA

  uint8_t pec = Wire.read();
  Serial.printf("\nCnt: %d, ret: 0x%x, pec: 0x%x, reg: 0x%x\n", cnt, ret, pec, a);

  return ret;

Always return Cnt: 3, ret: 0x0, pec: 0x0, reg: 0x7
Meaning ret is always zero.

Please kindly advice. Thanks.

@stickbreaker
Copy link
Contributor

stickbreaker commented Jul 29, 2018

@andriyadi which version are you using? RC3, RC4, Release 1.0.0, or Github direct?
Release 1.0.0 is the one you should try. use the Arduino Board Manager to install it.

Try this test code:

#declare SLAVEADDR 0x5A

void setup(){
Serial.begin(115200);
Wire.begin();
Wire.beginTransmission(SLAVEADDR);
Wire.write((uint8_t)0);
uint8_t err = Wire.endTransmission(false);
if(err !=7) {
  Serial.printf("Setting Eeprom read to address 0 failed =%d(%s).\n",Wire.lastError(),Wire.getErrorText(Wire.lastError)));
}
uint8_t count = Wire.requestFrom(SLAVEADDR,64);// 32 address 16bits each so 64 bytes
if( count != 64 ){
  Serial.printf("Reading Eeprom data failed =%d(%s).  Only read %bytes.\n",Wire.lastError(),Wire.getErrorText(Wire.lastError)),count);
}
uint16_t a=0; // eeprom address register
while (Wire.available()){
   uint16_t b,c;
   b = Wire.read();
   c = Wire.read();
   b = b | (c << 8);
  Serial.printf("0x%02: 0x%02X\n", a++, b);
  }
Serial.println(" all done"); 
}

void loop(){}

Chuck.
p.s. this is uncompiled code, It could have syntax errors.

@andriyadi
Copy link
Author

Thanks for your reply @stickbreaker
I'm using the latest from Github by cloning it.

Will get the Release 1.0.0 and try your suggested code.

@andriyadi
Copy link
Author

Hi @stickbreaker
I've tried your code, and revise so it's compiled to this:

        Wire.begin(21, 22, 50000);
	Wire.beginTransmission(SLAVEADDR);
	Wire.write((uint8_t) 0);
	uint8_t err = Wire.endTransmission(false);
	if (err != 7) {
		Serial.printf("Setting Eeprom read to address 0 failed = %d (%s).\n",
				Wire.lastError(), Wire.getErrorText(Wire.lastError()));
	}
	uint8_t count = Wire.requestFrom(SLAVEADDR, 64); // 32 address 16bits each so 64 bytes
	if (count != 64) {
		Serial.printf(
				"Reading Eeprom data failed = %d (%s).  Only read %d bytes.\n",
				Wire.lastError(), Wire.getErrorText(Wire.lastError()), count);
	}
	uint16_t a = 0; // eeprom address register
	while (Wire.available()) {
		uint16_t b, c;
		b = Wire.read();
		c = Wire.read();
		b = b | (c << 8);
		Serial.printf("0x%02X: 0x%02X\n", a++, b);
	}
	Serial.println(" all done");

The output is:

Reading Eeprom data failed = 0 (OK).  Only read 0 bytes.
0x00: 0x00
0x01: 0x00
0x02: 0x00
0x03: 0x00
0x04: 0x00
0x05: 0x00
0x06: 0x00
0x07: 0x00
0x08: 0x00
0x09: 0x00
0x0A: 0x00
0x0B: 0x00
0x0C: 0x00
0x0D: 0x00
0x0E: 0x00
0x0F: 0x00
0x10: 0x00
0x11: 0x00
0x12: 0x00
0x13: 0x00
0x14: 0x00
0x15: 0x00
0x16: 0x00
0x17: 0x00
0x18: 0x00
0x19: 0x00
0x1A: 0x00
0x1B: 0x00
0x1C: 0x00
0x1D: 0x00
0x1E: 0x00
0x1F: 0x00
 all done

@andriyadi
Copy link
Author

Interestingly, I tried your older code (the one before merging, I attach them here), I can communicate properly with the MLX90614 sensor and it returns expected result.
i2c.zip

As for running your test code, I got this:

0x00: 0x2A6B
0x01: 0xFFD0
0x02: 0xFFFF
0x03: 0xFFFF
0x04: 0xFFFF
0x05: 0xFFFF
0x06: 0xFFFF
0x07: 0xFFFF
0x08: 0xFFFF
0x09: 0xFFFF
0x0A: 0xFFFF
0x0B: 0xFFFF
0x0C: 0xFFFF
0x0D: 0xFFFF
0x0E: 0xFFFF
0x0F: 0xFFFF
0x10: 0xFFFF
0x11: 0xFFFF
0x12: 0xFFFF
0x13: 0xFFFF
0x14: 0xFFFF
0x15: 0xFFFF
0x16: 0xFFFF
0x17: 0xFFFF
0x18: 0xFFFF
0x19: 0xFFFF
0x1A: 0xFFFF
0x1B: 0xFFFF
0x1C: 0xFFFF
0x1D: 0xFFFF
0x1E: 0xFFFF
0x1F: 0xFFFF
 all done

The first two (0x00: 0x2A6B 0x01: 0xFFD0) is never the same when I reset the board.

@andriyadi
Copy link
Author

In fact, I also tried to use your code in your repo of July 2 version, it also works well. I can communicate the sensor properly.

Please kindly advice.

@stickbreaker
Copy link
Contributor

Can you set core debug level to Verbose
And run the test again?

I'll look through the read code and see if i can find anything.

Chuck

@andriyadi
Copy link
Author

andriyadi commented Jul 30, 2018

I don't know whether it's meaningful to you. Here's what I got @stickbreaker :
By the way, I use 2.7KOhm pullups on SDA SCL line.

[V][esp32-hal-i2c.c:1204] i2cInit(): num=0 sda=21 scl=22 freq=0
[V][esp32-hal-i2c.c:1387] i2cSetFrequency(): Fifo threshold=3
[E][esp32-hal-i2c.c:505] emptyRxFifo(): RxEmpty(29) call on TxBuffer? dq=0
[E][esp32-hal-i2c.c:505] emptyRxFifo(): RxEmpty(32) call on TxBuffer? dq=0
Reading Eeprom data failed = 0 (OK).  Only read 0 bytes.
0x00: 0x00
0x01: 0x00
0x02: 0x00
0x03: 0x00
0x04: 0x00
0x05: 0x00
0x06: 0x00
0x07: 0x00
0x08: 0x00
0x09: 0x00
0x0A: 0x00
0x0B: 0x00
0x0C: 0x00
0x0D: 0x00
0x0E: 0x00
0x0F: 0x00
0x10: 0x00
0x11: 0x00
0x12: 0x00
0x13: 0x00
0x14: 0x00
0x15: 0x00
0x16: 0x00
0x17: 0x00
0x18: 0x00
0x19: 0x00
0x1A: 0x00
0x1B: 0x00
0x1C: 0x00
0x1D: 0x00
0x1E: 0x00
0x1F: 0x00
 all done

@stickbreaker
Copy link
Contributor

Thats great, now i have something,

@stickbreaker
Copy link
Contributor

@andriyadi found the problem, working through the fix, and TEST it!

Chuck.

@stickbreaker
Copy link
Contributor

@andriyadi try this fix;
esp32-hal-i2c.zip

substitute this file for: (on a window 7 pro, Arduino 1.8.5)

C:\Users{user}\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.0\cores\esp32\esp32-hal-i2c.c

The fault it mine, I updated the I2C core to fix an interrupt saturation problem, I missed the ReSTART case. Sorry.

It works for me but I have not thoroughly tested it. I need some more testing before I create a pr.

Chuck.

@andriyadi
Copy link
Author

Hi @stickbreaker
Awesome! I've tested on few other sensors, other than MLX90614: BME680, MAX17055, TSL2591, LSM6SDL, and SX1509 I/O expander, all works using that patch.

Few things I've found:

  1. If I do Wire.begin() in another thread/task, as the sensor reading will be in that task as well, I got a lot of [E][esp32-hal-i2c.c:985] i2cProcQueue(): install interrupt handler Failed=261

  2. On LSM6DSL, every 10 - 20 seconds during reading accelerometer data, I got this:

[E][esp32-hal-i2c.c:1474] i2cDumpI2c(): i2c=0x3ffc12dc
[E][esp32-hal-i2c.c:1475] i2cDumpI2c(): dev=0x60027000 date=0x16042000
[E][esp32-hal-i2c.c:1479] i2cDumpI2c(): num=1
[E][esp32-hal-i2c.c:1480] i2cDumpI2c(): mode=1
[E][esp32-hal-i2c.c:1481] i2cDumpI2c(): stage=3
[E][esp32-hal-i2c.c:1482] i2cDumpI2c(): error=5
[E][esp32-hal-i2c.c:1483] i2cDumpI2c(): event=0x3ffc6a14 bits=112
[E][esp32-hal-i2c.c:1484] i2cDumpI2c(): intr_handle=0x3ffca9dc
[E][esp32-hal-i2c.c:1485] i2cDumpI2c(): dq=0x3ffc6afc
[E][esp32-hal-i2c.c:1486] i2cDumpI2c(): queueCount=2
[E][esp32-hal-i2c.c:1487] i2cDumpI2c(): queuePos=1
[E][esp32-hal-i2c.c:1488] i2cDumpI2c(): errorByteCnt=1
[E][esp32-hal-i2c.c:1489] i2cDumpI2c(): errorQueue=0
[E][esp32-hal-i2c.c:1447] i2cDumpDqData(): [0] 7bit 6b W  buf@=0x3ffc6932, len=1, pos=1, eventH=0x0 bits=0
[E][esp32-hal-i2c.c:1465] i2cDumpDqData(): 0x0000: -                                2d 
[E][esp32-hal-i2c.c:1447] i2cDumpDqData(): [1] 7bit 6b R STOP buf@=0x3ffc68ac, len=1, pos=0, eventH=0x0 bits=0
[E][esp32-hal-i2c.c:1465] i2cDumpDqData(): 0x0000: .                                06 
[E][esp32-hal-i2c.c:1500] i2cDumpInts(): 1 row  count   INTR    TX     RX
[E][esp32-hal-i2c.c:1504] i2cDumpInts(): [01] 0x0001 0x0002 0x0003 0x0000 0x00001e59
[E][esp32-hal-i2c.c:1504] i2cDumpInts(): [02] 0x0001 0x0200 0x0000 0x0000 0x00001e59
[E][esp32-hal-i2c.c:1504] i2cDumpInts(): [03] 0x0001 0x0020 0x0000 0x0000 0x00001e5a

Data are read successfully, but I think you may want to know.

Thanks for awesome fix!

@stickbreaker
Copy link
Contributor

@andriyadi that error is bus_busy, read the data sheet on your acc, it looks like the sensor is stretching SCL to indicate it is busy. I'll look over it.

Chuck.

@stickbreaker
Copy link
Contributor

@andriyadi posted a new pull #1717. It changes all 4 files of the i2c subsystem. You might try it by swapping these four files with the release version.

Chuck.

@andriyadi
Copy link
Author

@stickbreaker thanks for the fix and sorry late response. I've put few comments on PR #1717

@copercini
Copy link
Contributor

Fixed on #1717 =)

@Ritesh236
Copy link

Ritesh236 commented Apr 27, 2020

Hello,

I am getting all registers are FFFF while accessing MLX90614 over I2C

12:21:53.108 -> 0 = FFFF
12:21:53.175 -> 1 = FFFF
12:21:53.209 -> 2 = FFFF
12:21:53.276 -> 3 = FFFF
12:21:53.310 -> 4 = FFFF
12:21:53.378 -> 5 = FFFF
12:21:53.412 -> 6 = FFFF
12:21:53.446 -> 7 = FFFF
12:21:53.514 -> 8 = FFFF
12:21:53.548 -> 9 = FFFF
12:21:53.616 -> 10 = FFFF
12:21:53.650 -> 11 = FFFF
12:21:53.718 -> 12 = FFFF
12:21:53.752 -> 13 = FFFF
12:21:53.820 -> 14 = FFFF
12:21:53.854 -> 15 = FFFF
12:21:53.922 -> 16 = FFFF
12:21:53.956 -> 17 = FFFF
12:21:54.024 -> 18 = FFFF
12:21:54.058 -> 19 = FFFF
12:21:54.126 -> 20 = FFFF
12:21:54.160 -> 21 = FFFF
12:21:54.228 -> 22 = FFFF
12:21:54.262 -> 23 = FFFF
12:21:54.296 -> 24 = FFFF
12:21:54.364 -> 25 = FFFF
12:21:54.398 -> 26 = FFFF
12:21:54.466 -> 27 = FFFF
12:21:54.499 -> 28 = FFFF
12:21:54.567 -> 29 = FFFF
12:21:54.601 -> 30 = FFFF
12:21:54.669 -> 31 = FFFF
12:21:54.703 -> 28 = FFFF
12:21:54.771 -> 29 = FFFF
12:21:54.805 -> 30 = FFFF
12:21:54.873 -> 31 = FFFF

so what can be the issue for that?

@SpoturDeal
Copy link

I have changed line 25 in Adafruit_mlx90614.h

to

#define MLX90614_I2CADDR 0x0E

The original address was 0x5A it seems the mlx90614 is on address 0x0E
No i am reading proper values

Ambient = 27.65*C       Object = 26.83*C
Ambient = 81.77*F       Object = 80.29*F

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants