MLX90640 library functions
melexis / mlx90640-library Goto Github PK
View Code? Open in Web Editor NEWMLX90640 library functions
License: Apache License 2.0
MLX90640 library functions
License: Apache License 2.0
Is it possible to recognize the FOV (55 or 110) from the dev_id1, dev_id2, dev_id3 ?
The following code within the I2C driver reverses the endianness of data. I believe it is good to make note of this to users of this library to adapt according to the endianness of the platform in use.
This is also mentioned in #12
The function puts the data into the array in reverse order too.
The code snippet in question is:
for(cnt=0; cnt < nMemAddressRead; cnt++)
{
i = cnt << 1;
*p++ = (uint16_t)i2cData[i]*256 + (uint16_t)i2cData[i+1];
}
This can be seen in the first I2C buffer of the EEPROM dump that shows data as transferred over the wire and the reconstructed buffer returned from the I2C read function after the above code segment is applied.
D (2482) I2C UINT8 BUFFER: 00 a4 69 9f 00 00 20 61 00 04 03 20 03 e0 16 26
D (2482) I2C UINT8 BUFFER: b2 25 61 86 04 99 00 00 ff ff 00 00 00 00 be 33
D (2492) I2C UINT8 BUFFER: 43 20 ff b1 01 01 01 01 01 01 f1 f1 e0 f1 c0 e0
D (2492) I2C UINT8 BUFFER: 00 01 01 02 01 02 f1 02 f1 f2 f1 f2 e0 e2 c0 d1
D (2502) I2C UINT8 BUFFER: 88 95 37 70 dd a9 ff ff 33 22 33 33 11 22 dd ff
D (2512) I2C UINT8 BUFFER: dd bb 00 ff 22 11 32 33 22 33 11 22 ff 01 bc ee
D (2512) I2C UINT8 BUFFER: 17 72 2f ac 25 57 a0 7d 76 56 f1 8c 41 3d 3c 3b
D (2522) I2C UINT8 BUFFER: 24 52 f8 7f ff ff 06 2a ec 00 97 97 97 97 2a fb
D (2532) I2C UINT8 BUFFER: 08 40 05 30 23 e0 f8 5e fb fe 00 90 10 30 ff ff
D (2542) I2C UINT8 BUFFER: 00 60 ff ff 10 2e f3 fe f8 0e ff e0 11 0e f7 ee
D (2542) I2C UINT8 BUFFER: 04 00 ff ff 0c be ec 8e f5 00 f8 60 08 60 e4 1e
D (2552) I2C UINT8 BUFFER: 03 70 f8 60 0c 40 eb 70 f4 1e ff 90 08 12 e4 7e
D (2562) I2C UINT8 BUFFER: 0c 32 05 1e 07 be 14 30 03 c2 00 8e f0 2e 10 10
D (2562) I2C UINT8 BUFFER: ff ff ff ff f4 0e 0f d0 03 c2 03 ae f8 be 17 a0
D (2572) I2C UINT8 BUFFER: 0f d2 0f de f4 9e 0c 70 00 d2 00 4e f4 5e 04 00
D (2582) I2C UINT8 BUFFER: 0f 52 04 50 fc 1e 0f 42 03 e2 0b 7e fb f0 ff ff
D (2582) I2C UINT8 BUFFER: ff ff 0c 20 ff ff ff b0 ff 5e 04 20 ff ff f7 ce
D (2592) I2C UINT8 BUFFER: 00 2e 04 40 17 a0 f3 be ff 8e ff 90 10 70 fb 2e
D (2602) I2C UINT8 BUFFER: 07 a0 07 60 13 e0 f0 0e fc 3e f8 30 ff ff e7 de
D (2612) I2C UINT8 BUFFER: ff ff 00 02 13 d0 e7 a0 f7 b0 ff 20 13 52 e7 fe
D (2612) I2C UINT8 BUFFER: 08 22 0c 70 07 de 14 12 07 a2 08 80 f4 1e 10 40
D (2622) I2C UINT8 BUFFER: 04 70 04 80 fb de 0f f0 03 c2 ff ff f8 ae ff ff
D (2632) I2C UINT8 BUFFER: 0f e2 0f a0 f8 3e 10 50 04 72 00 70 f8 0e 04 30
D (2632) I2C UINT8 BUFFER: 0b 92 08 60 00 20 07 f0 00 02 ff ff ff a0 04 40
D (2642) I2C UINT8 BUFFER: 13 d0 0c 50 27 40 ff ff ff ff 0f f0 1f 40 ff ff
D (2652) I2C UINT8 BUFFER: 08 70 04 70 17 c0 f7 ce 07 ae 07 40 14 80 03 40
D (2662) I2C UINT8 BUFFER: 13 a0 0f 90 1f 90 fb e0 0b d0 00 40 10 30 f3 80
D (2662) I2C UINT8 BUFFER: 03 c0 04 10 17 e0 ff ff ff b0 03 60 13 70 ff ff
D (2672) I2C UINT8 BUFFER: 10 12 08 a0 07 8e 17 d0 0b e2 0c 50 03 8e 0c 90
D (2682) I2C UINT8 BUFFER: 08 b2 04 be fb fe 0f e0 07 f2 ff 90 f4 de 1b 80
D (2682) I2C UINT8 BUFFER: 17 d2 0f ee ff ff 14 10 0c 04 00 70 f4 5e ff ff
D (2692) I2C UINT8 BUFFER: ff ff 08 50 00 10 0b f2 07 f2 0b b0 ff b0 04 70
D (2702) I2C UINT8 BUFFER: ff ff 0c 60 27 60 03 b0 03 90 0c 40 1b c0 f8 2e
D (2702) I2C UINT8 BUFFER: 00 60 ff ff 1b b0 f7 ce 07 40 ff d0 18 10 ff ff
D (2712) I2C UINT8 BUFFER: 0f c2 0f 90 14 20 fb de 07 e2 00 02 0c 20 f3 6e
D (2722) I2C UINT8 BUFFER: 0a c2 08 00 23 82 f3 80 03 80 07 60 1b 12 f0 00
D (2732) I2C UINT8 BUFFER: ff ff 00 b0 03 9e 13 f2 ff d2 04 80 f7 ee ff ff
D (2732) I2C UINT8 BUFFER: fc 80 00 90 f7 de 07 f0 03 72 f8 0e f8 4e 13 a2
D (2742) I2C UINT8 BUFFER: 0f e4 0b d0 f0 4e ff ff 04 02 00 40 f0 50 ff ff
D (2752) I2C UINT8 BUFFER: 12 f4 08 40 07 c0 0f b2 0b b2 ff ff ff 50 ff ff
D (2752) I2C UINT8 BUFFER: 07 f0 0c 92 23 c0 fc 20 03 c0 10 30 14 00 f8 60
D (2762) I2C UINT8 BUFFER: 00 90 08 50 1b 80 f7 a0 07 70 07 82 ff ff 02 de
D (2772) I2C UINT8 BUFFER: 0b a0 0b f0 10 12 f4 00 07 f2 00 10 0c 60 ff ff
D (2772) I2C UINT8 BUFFER: 0b 22 0c 72 18 12 ef d0 03 90 0b 62 13 d2 f3 f0
D (2782) I2C UINT8 BUFFER: fc 22 f8 d0 f7 fe 08 42 fb e2 ff ff ec 3e 04 92
D (2792) I2C UINT8 BUFFER: f8 b2 fc 60 f3 ae 07 c2 ff 82 fb b0 ff ff ff ff
D (2802) I2C UINT8 BUFFER: 07 d2 00 20 f0 3e 08 32 00 34 fc 50 e8 8e fc 60
D (2802) I2C UINT8 BUFFER: 0b 34 fc b0 ff ff 07 e0 ff ff 07 b0 f0 00 08 20
D (2812) I2C UINT8 BUFFER: 0f e0 0c 90 27 70 fc 30 13 52 0c 60 17 b0 ff ff
D (2822) I2C UINT8 BUFFER: 00 70 0b c2 17 50 f7 80 0b 50 ff a0 17 f2 fb b0
D (2822) I2C UINT8 BUFFER: 0f a2 0b f0 17 d0 ff ff 00 32 07 d0 0c 02 ef e0
D (2832) I2C UINT8 BUFFER: 03 42 04 82 17 c0 e8 20 f4 20 03 d0 ff ff ec 00
D (2842) I2C UINT8 BUFFER: 00 12 f4 b0 f7 90 00 60 03 84 f4 80 eb de 04 02
D (2842) I2C UINT8 BUFFER: f4 82 ff ff ff ff fb a0 ff 62 f3 c0 ec 0e 03 d0
D (2852) I2C UINT8 BUFFER: 03 b4 fc 00 ef e0 00 30 f8 54 fb f0 ff ff ff ff
D (2862) I2C UINT8 BUFFER: 03 64 f8 b0 f7 f0 f8 40 f4 32 fc 00 f3 80 fc 10
D (2872) I2C UINT8 BUFFER: f8 40 ff ff 14 10 f4 90 ff b0 0c 52 0f e0 f4 20
D (2872) I2C UINT8 BUFFER: f8 60 00 82 13 70 f3 50 ff 72 ff c0 ff ff fb 40
D (2882) I2C UINT8 BUFFER: fc 02 07 f0 0c 00 f4 2e f8 52 00 40 04 10 eb c0
D (2892) I2C UINT8 BUFFER: ff ff 08 42 10 32 ef d0 f0 20 03 d0 0f 92 ec 10
D (2892) I2C UINT8 BUFFER: 08 42 05 00 00 2e 10 a2 ff ff 10 60 ff ff 18 50
D (2902) I2C UINT8 BUFFER: 08 62 0c 90 03 8e 1b 50 0f 82 0b d0 00 6e ff ff
D (2912) I2C UINT8 BUFFER: 10 12 10 10 00 1e 18 40 ff ff 0c 60 fc 3e 17 e0
D (2922) I2C UINT8 BUFFER: 17 c4 18 80 08 4e 1b f2 10 32 1b f0 ff ff 1c 32
D (2922) I2C UINT8 BUFFER: f3 ce 08 62 0f c0 f0 10 ef e0 04 62 ff ff f7 a0
D (2932) I2C UINT8 BUFFER: f0 50 00 40 0b 80 eb 90 f3 70 ff 40 04 70 f3 80
D (2942) I2C UINT8 BUFFER: ff 92 03 d2 fc 80 ef e0 f7 e0 ff d2 ff ff e7 b0
D (2942) I2C UINT8 BUFFER: f3 80 fc 72 08 00 eb b0 ec 10 ff ff 07 a2 ff ff
D (2952) I2C UINT8 BUFFER: ff c0 00 70 f7 ce 0c 20 fb d2 00 70 f3 ce 13 b2
D (2962) I2C UINT8 BUFFER: fc 62 04 40 f3 9e 0f 80 03 52 03 40 ff ff 13 90
D (2962) I2C UINT8 BUFFER: 0f 94 ff ff ec 9e 13 e0 ff ff 0b d0 f0 1e 0f c0
D (2972) I2C UINT8 BUFFER: 0f 94 0c 80 00 02 13 c0 04 12 13 d0 ff 90 0c 60
D (2982) I2C UINT8 BUFFER: f7 c0 04 32 0b 90 f3 f0 eb e0 00 12 ff ff ec 00
D (2992) I2C UINT8 BUFFER: f4 30 fc 00 f7 f0 ff ff f3 62 f3 a0 f8 70 e4 40
D (2992) I2C UINT8 BUFFER: fb d2 f8 20 f8 80 e4 30 ec 40 f4 22 f8 22 dc 30
D (3002) I2C UINT8 BUFFER: eb f2 f8 a2 ff ff e0 00 e4 10 ff a0 ff ff dc 70
D (3012) I2C UINT8 BUFFER: fb 92 fc 20 ff ff 07 e2 ef d2 f8 10 dc 2e 04 00
D (3012) I2C UINT8 BUFFER: f8 32 fc 10 e3 fe ff b0 ff 72 f3 a0 ff ff fc 50
D (3022) I2C UINT8 BUFFER: 07 e4 f8 60 e0 9e 04 42 fc 62 fc 50 ff ff 00 40
D (3032) I2C UINT8 BUFFER: ff f2 ff ff f4 2e 07 e0 fc 02 0b a0 f3 a0 00 70
D (3032) I2C UINT8 BUFFER: fb 90 18 42 1f 30 0b c0 03 40 14 42 0f f0 fc 60
D (3042) I2C UINT8 BUFFER: fc 30 10 62 13 e0 fb d0 03 60 ff ff 14 40 fc 00
D (3052) I2C UINT8 BUFFER: ff ff 0c 20 0c 80 fc 10 00 10 ff ff 0c 50 ff 90
D (3062) I2C UINT8 BUFFER: 03 a0 14 80 1b d0 ff 90 ff d0 1b 50 13 b2 f8 30
D (3062) I2C UINT8 BUFFER: fb 72 04 20 fb 1e 13 a2 07 02 ff ff ef de ff ff
D (3072) I2C UINT8 BUFFER: 00 32 08 60 f3 de ff ff 0b 52 07 90 fc 4e 17 f0
D (3082) I2C UINT8 BUFFER: 17 92 0c 20 f4 7e 1c 00 0c 12 10 60 f4 4e 1f 90
D (3082) I2C UINT8 BUFFER: 13 b2 18 70 0b ce 1f 70 13 a2 ff ff ff ff 1c 30
D (3092) I2C UINT8 BUFFER: e0 0e 0c 92 07 a0 ff b0 f3 30 0c 12 03 f0 f4 20
D (3102) I2C UINT8 BUFFER: f0 60 04 82 07 f0 ec 2e ef ee fc 12 04 a0 f7 c0
D (3112) I2C UINT8 BUFFER: ff ff 08 12 04 70 f4 50 f0 80 ff ff fc b0 ec 20
D (3112) I2C UINT8 BUFFER: ec 10 08 d0 08 50 ef e0 f3 b0 13 72 f7 f0 f4 30
D (3122) I2C UINT8 BUFFER: db d0 ec 60 df 7e 03 92 ef 02 f7 f0 d7 ce 03 e0
D (3132) I2C UINT8 BUFFER: ff ff f4 60 e3 ee f8 30 ff ff ff ff e4 9e 0b d0
D (3132) I2C UINT8 BUFFER: f8 32 00 10 e8 5e 08 50 f8 60 00 4e e0 9e 08 10
D (3142) I2C UINT8 BUFFER: fb e2 04 a0 f0 0e 0b c0 07 82 0f 50 f3 ae 14 00
D (3152) I2C UINT8 BUFFER: e3 c0 08 02 ff 00 ff ff df 6e ff ff f7 30 eb e0
D (3152) I2C UINT8 BUFFER: e0 60 fc 30 eb ee ff ff e0 0e fb b0 f0 ae eb fe
D (3162) I2C UINT8 BUFFER: f3 f0 fc 90 f4 b0 e8 60 ec 70 07 d0 f4 40 eb b0
D (3172) I2C UINT8 BUFFER: e3 80 00 60 ff ff e7 80 e7 7e ff ff ef 6e ec 10
D (3182) I2C UINT8 BUFFER: ef 90 ff f0 ee ce 0b 90 ef 40 ff ff e7 0e 0b b0
D (3182) I2C UINT8 BUFFER: f8 30 04 0e eb be 0b a0 ff f0 07 9e f0 8e 13 e0
D (3192) I2C UINT8 BUFFER: 17 c2 ff ff f4 8e 1c 60 10 52 ff ff f8 2e 1f a0
D (3202) I2C UINT8 BUFFER: 0f 50 14 5e 07 7e 17 60 17 40 23 1e 07 3e 23 f0
D (3202) RECONSTRUCTED UINT16 DATA:: 0x3ffb5870 a4 00 9f 69 00 00 61 20 04 00 20 03 e0 03 26 16 |...i..a .. ...&.|
D (3212) RECONSTRUCTED UINT16 DATA:: 0x3ffb5880 25 b2 86 61 99 04 00 00 ff ff 00 00 00 00 33 be |%..a..........3.|
D (3232) RECONSTRUCTED UINT16 DATA:: 0x3ffb5890 20 43 b1 ff 01 01 01 01 01 01 f1 f1 f1 e0 e0 c0 | C..............|
D (3242) RECONSTRUCTED UINT16 DATA:: 0x3ffb58a0 01 00 02 01 02 01 02 f1 f2 f1 f2 f1 e2 e0 d1 c0 |................|
D (3252) RECONSTRUCTED UINT16 DATA:: 0x3ffb58b0 95 88 70 37 a9 dd ff ff 22 33 33 33 22 11 ff dd |..p7...."333"...|
D (3262) RECONSTRUCTED UINT16 DATA:: 0x3ffb58c0 bb dd ff 00 11 22 33 32 33 22 22 11 01 ff ee bc |....."323"".....|
D (3272) RECONSTRUCTED UINT16 DATA:: 0x3ffb58d0 72 17 ac 2f 57 25 7d a0 56 76 8c f1 3d 41 3b 3c |r../W%}.Vv..=A;<|
D (3282) RECONSTRUCTED UINT16 DATA:: 0x3ffb58e0 52 24 7f f8 ff ff 2a 06 00 ec 97 97 97 97 fb 2a |R$....*........*|
D (3292) RECONSTRUCTED UINT16 DATA:: 0x3ffb58f0 40 08 30 05 e0 23 5e f8 fe fb 90 00 30 10 ff ff |@.0..#^.....0...|
D (3302) RECONSTRUCTED UINT16 DATA:: 0x3ffb5900 60 00 ff ff 2e 10 fe f3 0e f8 e0 ff 0e 11 ee f7 |`...............|
D (3312) RECONSTRUCTED UINT16 DATA:: 0x3ffb5910 00 04 ff ff be 0c 8e ec 00 f5 60 f8 60 08 1e e4 |..........`.`...|
D (3322) RECONSTRUCTED UINT16 DATA:: 0x3ffb5920 70 03 60 f8 40 0c 70 eb 1e f4 90 ff 12 08 7e e4 |p.`[email protected].......~.|
D (3332) RECONSTRUCTED UINT16 DATA:: 0x3ffb5930 32 0c 1e 05 be 07 30 14 c2 03 8e 00 2e f0 10 10 |2.....0.........|
D (3342) RECONSTRUCTED UINT16 DATA:: 0x3ffb5940 ff ff ff ff 0e f4 d0 0f c2 03 ae 03 be f8 a0 17 |................|
D (3352) RECONSTRUCTED UINT16 DATA:: 0x3ffb5950 d2 0f de 0f 9e f4 70 0c d2 00 4e 00 5e f4 00 04 |......p...N.^...|
D (3362) RECONSTRUCTED UINT16 DATA:: 0x3ffb5960 52 0f 50 04 1e fc 42 0f e2 03 7e 0b f0 fb ff ff |R.P...B...~.....|
D (3382) RECONSTRUCTED UINT16 DATA:: 0x3ffb5970 ff ff 20 0c ff ff b0 ff 5e ff 20 04 ff ff ce f7 |.. .....^. .....|
D (3392) RECONSTRUCTED UINT16 DATA:: 0x3ffb5980 2e 00 40 04 a0 17 be f3 8e ff 90 ff 70 10 2e fb |[email protected]...|
D (3402) RECONSTRUCTED UINT16 DATA:: 0x3ffb5990 a0 07 60 07 e0 13 0e f0 3e fc 30 f8 ff ff de e7 |..`.....>.0.....|
D (3412) RECONSTRUCTED UINT16 DATA:: 0x3ffb59a0 ff ff 02 00 d0 13 a0 e7 b0 f7 20 ff 52 13 fe e7 |.......... .R...|
D (3422) RECONSTRUCTED UINT16 DATA:: 0x3ffb59b0 22 08 70 0c de 07 12 14 a2 07 80 08 1e f4 40 10 |".p...........@.|
D (3432) RECONSTRUCTED UINT16 DATA:: 0x3ffb59c0 70 04 80 04 de fb f0 0f c2 03 ff ff ae f8 ff ff |p...............|
D (3442) RECONSTRUCTED UINT16 DATA:: 0x3ffb59d0 e2 0f a0 0f 3e f8 50 10 72 04 70 00 0e f8 30 04 |....>.P.r.p...0.|
D (3452) RECONSTRUCTED UINT16 DATA:: 0x3ffb59e0 92 0b 60 08 20 00 f0 07 02 00 ff ff a0 ff 40 04 |..`. .........@.|
D (3462) RECONSTRUCTED UINT16 DATA:: 0x3ffb59f0 d0 13 50 0c 40 27 ff ff ff ff f0 0f 40 1f ff ff |..P.@'......@...|
D (3472) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a00 70 08 70 04 c0 17 ce f7 ae 07 40 07 80 14 40 03 |p.p.......@...@.|
D (3482) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a10 a0 13 90 0f 90 1f e0 fb d0 0b 40 00 30 10 80 f3 |[email protected]...|
D (3492) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a20 c0 03 10 04 e0 17 ff ff b0 ff 60 03 70 13 ff ff |..........`.p...|
D (3502) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a30 12 10 a0 08 8e 07 d0 17 e2 0b 50 0c 8e 03 90 0c |..........P.....|
D (3522) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a40 b2 08 be 04 fe fb e0 0f f2 07 90 ff de f4 80 1b |................|
D (3532) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a50 d2 17 ee 0f ff ff 10 14 04 0c 70 00 5e f4 ff ff |..........p.^...|
D (3542) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a60 ff ff 50 08 10 00 f2 0b f2 07 b0 0b b0 ff 70 04 |..P...........p.|
D (3552) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a70 ff ff 60 0c 60 27 b0 03 90 03 40 0c c0 1b 2e f8 |..`.`'....@.....|
D (3562) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a80 60 00 ff ff b0 1b ce f7 40 07 d0 ff 10 18 ff ff |`.......@.......|
D (3572) RECONSTRUCTED UINT16 DATA:: 0x3ffb5a90 c2 0f 90 0f 20 14 de fb e2 07 02 00 20 0c 6e f3 |.... ....... .n.|
D (3582) RECONSTRUCTED UINT16 DATA:: 0x3ffb5aa0 c2 0a 00 08 82 23 80 f3 80 03 60 07 12 1b 00 f0 |.....#....`.....|
D (3592) RECONSTRUCTED UINT16 DATA:: 0x3ffb5ab0 ff ff b0 00 9e 03 f2 13 d2 ff 80 04 ee f7 ff ff |................|
D (3602) RECONSTRUCTED UINT16 DATA:: 0x3ffb5ac0 80 fc 90 00 de f7 f0 07 72 03 0e f8 4e f8 a2 13 |........r...N...|
D (3612) RECONSTRUCTED UINT16 DATA:: 0x3ffb5ad0 e4 0f d0 0b 4e f0 ff ff 02 04 40 00 50 f0 ff ff |[email protected]...|
D (3622) RECONSTRUCTED UINT16 DATA:: 0x3ffb5ae0 f4 12 40 08 c0 07 b2 0f b2 0b ff ff 50 ff ff ff |[email protected]...|
D (3632) RECONSTRUCTED UINT16 DATA:: 0x3ffb5af0 f0 07 92 0c c0 23 20 fc c0 03 30 10 00 14 60 f8 |.....# ...0...`.|
D (3642) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b00 90 00 50 08 80 1b a0 f7 70 07 82 07 ff ff de 02 |..P.....p.......|
D (3662) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b10 a0 0b f0 0b 12 10 00 f4 f2 07 10 00 60 0c ff ff |............`...|
D (3672) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b20 22 0b 72 0c 12 18 d0 ef 90 03 62 0b d2 13 f0 f3 |".r.......b.....|
D (3682) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b30 22 fc d0 f8 fe f7 42 08 e2 fb ff ff 3e ec 92 04 |".....B.....>...|
D (3692) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b40 b2 f8 60 fc ae f3 c2 07 82 ff b0 fb ff ff ff ff |..`.............|
D (3702) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b50 d2 07 20 00 3e f0 32 08 34 00 50 fc 8e e8 60 fc |.. .>.2.4.P...`.|
D (3712) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b60 34 0b b0 fc ff ff e0 07 ff ff b0 07 00 f0 20 08 |4............. .|
D (3722) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b70 e0 0f 90 0c 70 27 30 fc 52 13 60 0c b0 17 ff ff |....p'0.R.`.....|
D (3732) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b80 70 00 c2 0b 50 17 80 f7 50 0b a0 ff f2 17 b0 fb |p...P...P.......|
D (3742) RECONSTRUCTED UINT16 DATA:: 0x3ffb5b90 a2 0f f0 0b d0 17 ff ff 32 00 d0 07 02 0c e0 ef |........2.......|
D (3752) RECONSTRUCTED UINT16 DATA:: 0x3ffb5ba0 42 03 82 04 c0 17 20 e8 20 f4 d0 03 ff ff 00 ec |B..... . .......|
Hi,
we are working in one project with your library with dev board from ublox (u-blox c030) and we are trying to run the terminal camera library provided by you on git.
we can't make this library to work.
we are logging out som data and the data are:
irData[764] = 0, kv= 0.437500, kta= 0.007812, offset= ffffff9d, alpha= nan
irData[765] = 3f80, kv= 0.375000, kta= 0.007080, offset= ffffff96, alpha= nan
irData[766] = 0, kv= 0.437500, kta= 0.007324, offset= ffffff97, alpha= nan
irData[767] = 3f80, kv= 0.375000, kta= 0.007568, offset= ffffff94, alpha= -340279649078051570000000000000000000000.000000
let us know if you have an idea what is the issue or didi you have any hello world app for this specific MCU
I'm currently having issues trying to get the basic example from the SparkFun MLX90640 Arduino examples available on GitHub which is based on the mlx90640-library with an esp32. I'm having an issue with getting meaningful sensor readings and I'm wondering if it's because of the MLX90640_ExtractParameters is returning and error code of -4.
I traced where the -4 error code came from and it was in the ExtractDeviatingPixels function which has the following check and sets warn = -4:
else if (outlierPixCnt > 4) { warn = -4; }
I'm assuming this has to successfully complete for accurate results?
After this, the code continues to run MLX90640_GetFrameData which then is returned a status of -8 which I've read the driver.pdf document where it says that "the most probable reason is that the I2C frequency is too low" but altering the i2c frequency doesn't seem to have any effect.
Here is an example of the output that I'm getting:
I'm sure I'm doing something wrong but I'm stuck and am not sure where to go from here. I've verified that an i2c scanning sketch can find the device at 0x33 and I've verified that the input voltage seems to be a steady 3.3v.
Any help would be greatly appreciated, and please forgive me for any silly questions, I'm quite new to the hardware side of things!
I have the Sparkfun MLX90640 sensor connected to Teensy 3.6 over I2C. I can not connect to the sensor. The message I get is "MLX90640 not detected at default I2C address". I am running the basic example from the supplied code. The I2C scanner does also not detect the device.
Any suggestions?
Hello sir,
First off, thank you for providing such a successful repository :)
I am trying to read the data from my MLX90640 sensor (which I have on a prototyping breadboard with pull-up resistors and decoupling capacitors) onto my Raspberry Pi. I am confused about steps needed to do in order to take the files which you have provided, and read the data from my MLX90640 sensor and perhaps visualize the individual pixel values.
From a high level, what steps are needed in order to take the files which you have provided here in this repository, and then read the data from the MLX90640 using my Raspberry Pi? I have the sensor successfully connected to my Raspberry Pi using the i2cdetect command, and I successfully see it at address 0x33.
I cloned your github repository; but I am unsure what my next steps should be. For example, do I need to create a Makefile, compile the project in Geany? How do I get to a point where I can visualize the data coming in from the sensor?
Any information or support is gratefully appreciated!
Hi,
I have been trying to get the MLX90640 to work on the up-board Linux based.
I keep getting NAN and non valid values from the sensor.
I have tested all functions according to the excel document and they seem to be working.
I have tested the hardware by using a Python code and that also worked fine.
I have tried to minimize the buffer size in the I2C and only sample 32 characters at each read and that didn't change anything.
I am attaching the EEPROM data which I think looks fine and follows by that the frame data which is not ok.
paramResults.txt
Would really appreciate some ideas on how to solve this..
Thanks
I am trying to read back the image data from the MLX90640 to an MSP430 TI MCU over I2C
The problem that I have is that the chip always replies the same data, even after resetting it (although I should be reading from RAM)
Even when I change the readback address, the data is always the same.
Therefore, I think the chip doesn't get the readback address, en responds with a page from its ROM.
Can somebody have a look at the traces in attachment?
Might the problem be that there is a stop condition after the requested address, instead of restart?
Hello,
I am Multiplexing a few MLX90640, trying to incorporate them into a few different projects,
I have noticed that the frame rate I get is very limited (less than 3Hz) compared to what I read online and the MLX specs, but it gets better if I cancel the following loop, and only run the content of it one time instead of twice
for (byte x = 0 ; x < 2 ; x++) {
uint16_t mlx90640Frame[834];
int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);
float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640);
float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
}
If I don't run the loop twice I have noticed that I get errors in the images,
Do I have to run this twice to get precise results?
I have tried this both with the Teensy3.2(96MHz) and ESP32(240MHz) and got similar results.
This also happens When I don't multiplex, that tells me that it is related to the time it takes the API's in the loop to run
Thanks for your help
The MLX90640_BadPixelsCorrection
function uses abs
on this line:
https://github.com/melexis/mlx90640-library/blob/master/functions/MLX90640_API.cpp#L634
Unfortunately, depending on the C++ compiler, including math.h
and using abs
can lead to different results: some compilers would use the float abs(float)
version, some the int abs(int)
, some would just not declare abs
and lead to compilation errors.
Example: https://wandbox.org/permlink/CaEOR8V3iQJSbyjt (try changing the gcc
version on the top left, for example to 5.x.y
)
A safe alternative is to use fabs
instead.
I am writing regarding the SparkFun MLX90640 Arduino examples available on GitHub which are based on the mlx90640-library. I have successfully uploaded the Example2_OutputToProcessing sketch to an ESP32 board ("ESP32 Dev Module" from Arduino boards) and it works (parameters: 8Hz, Chess mode, 19 bit), but the frames coming from the ESP32 are striped (see example attached). I have read the documentation and analyzed the driver source code, but I have no clue why it is happening. The same sensor with the Melexis Evaluation board produces perfect frames without stripes on the PC software provided by Melexis (MLxCIRT 90640 3).
I tried the sketch with different parameters (changing the refresh rate, resolution, mode, timing between subpage readings), but I am now I have no ideas how to fix it. Could you please give me any advice?
I am using MLX90640 evaluation board (https://www.melexis.com/en/product/EVB90640-41/Evaluation-Board-MLX90640-41) and Teensy 3.2. I have connected SCL of sensor to Pin 19 of Teensy and SDA to Pin 18. Teensy 3.2 I have powered by connecting it to my computer. VDD and GND of sensor are connected to 3.3V (Pin 24) and AGND (Pin 25) on Teensy respectively. When I am uploading this code (https://github.com/sparkfun/SparkFun_MLX90640_Arduino_Example/tree/master/Firmware/Example1_BasicReadings), I am getting following error and the code is not working.
In function 'void loop()':
55: warning: unused variable 'vdd'
float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640);
What is wrong here? something with code or pin connections I made. Please guide.
I received these compiler warnings while using the esp-idf toolchain to perform the tests.
In function 'ExtractGainParameters':
mlx90640_api.c:613:15: warning: comparison is always false due to limited range of data type [-Wtype-limits]
if(gainEE > 32767)
^
mlx90640_api.c:785:19: warning: comparison is always false due to limited range of data type [-Wtype-limits]
if (offsetRef > 32767)
^
mlx90640_api.c: In function 'ExtractKtaPixelParameters':
mlx90640_api.c:855:17: warning: comparison is always false due to limited range of data type [-Wtype-limits]
if (KtaRoCo > 127)
Are the limited ranges of the datatypes used intended? I haven't yet analyzed the effect of this with reference to the datasheet but I thought I may raise it here first.
Hi @slavysis
Thanks for your excellent library, which is very helpful for me to test and understand the sensor.
In current library, it is only identifying the defective pixels from the EEPROM datas and checking their adjacent pixels. Do you have the plan to add the defective pixels processing in the library?
I remember you mentioned that max I2C clock freq. is 400KHz for reading Mlx90640's EEPROM info. and 1MHz for reading RAM info. It is not found in MLX90640's specification. Why does it need to limit
the communication rate for EEPROM reading?
Thanks.
Hey,
I am looking through the api trying to understand it and looking for places I can speed it up and whatnot. I noticed that in this section the api reads from the camera 4x. I reduced it to 1 time on my end and it still functions normally. Is there a reason for these extra reads?
Thanks
Hello! I am using the MLX90640-BAA with ESP32. Everytime I power on the ESP32, the first few frames shows 0s for subpage 0 pixels. After a couple of frames, all pixels show temperature values. I2C frequency is set to 100kHz and refresh rate is set to 64Hz.
When I2C frequency is set to 999990Hz and refresh rate is set to 32Hz, the problem only occurs for the very first frame then resumes normal operation. Why does the problem persist longer with the initial settings? And is this normal behaviour?
I'm moving the API to java, and somehow my temperature calculated using sample data is not correct. I can verify some values like kVdd, vdd25, cpKv are correct. But for alpha/kta/kv, non-scaled data is given only. And I'm not sure whether I process them correctly.
So question is, how can I verify the value I saved to paramsMLX90640 is correct, for alpha/kta/kv ?
I am running tests on an ESP32, the following is my debug output:
Reference kVdd: -12544 , Obtained kVdd: -12544
Reference vdd25: -12544 , Obtained vdd25: -12544
Reference KvPTAT: 0.002197 , Obtained KvPTAT: 0.002197
Reference KtPTAT: 42.625000 , Obtained KtPTAT: 42.625000
Reference vPTAT25: 12196 , Obtained vPTAT25: 12196
Reference alphaPTAT: 9.000000 , Obtained alphaPTAT: 9.000000
Reference gainEE: 5580 , Obtained gainEE: 5580
Reference tgc: 0.000000 , Obtained tgc: 0.000000
Reference cpKv: 0.375000 , Obtained cpKv: 0.375000
Reference cpKta: 0.004272 , Obtained cpKta: 0.004272
Reference resolutionEE: 2 , Obtained resolutionEE: 2
Reference calibrationModeEE: 128 , Obtained calibrationModeEE: 128
Reference KsTa: -0.002441 , Obtained KsTa: -0.002441
Testing ksTo parameter
Reference data and obtained data length in bytes are 16 and 16 respectively
Reference data SHA-256 Hash:8cfafaac5f40bf62634c1ca30708ad6353c8f16d54e2fce6181c785510ca667a
Calculated data SHA-256 Hash:c499c76c4146a8ccfe27d26b83abec524db04da49b6a70874a4de82c97b1943a
Testing ct parameter
Reference data and obtained data length in bytes are 8 and 8 respectively
Reference data SHA-256 Hash:e0e64878111d6910f46b7b8fe2676f8963ec070519ed3aba06aa67ce144ba448
Calculated data SHA-256 Hash:e0e64878111d6910f46b7b8fe2676f8963ec070519ed3aba06aa67ce144ba448
Testing alpha parameter
Reference data and obtained data length in bytes are 3072 and 3072 respectively
Reference data SHA-256 Hash:eb3097ded2ee5036ac301e36fc59c74f592d2e1703185863ea2293c10ed76171
Calculated data SHA-256 Hash:eb3097ded2ee5036ac301e36fc59c74f592d2e1703185863ea2293c10ed76171
Testing offset parameter
Reference data and obtained data length in bytes are 1536 and 1536 respectively
Reference data SHA-256 Hash:d6de8ba01e71a4ec70ac12c00b492324b30881e4a574bf5f13ad3489f3c0acf5
Calculated data SHA-256 Hash:d6de8ba01e71a4ec70ac12c00b492324b30881e4a574bf5f13ad3489f3c0acf5
Testing kta parameter
Reference data and obtained data length in bytes are 3072 and 3072 respectively
Reference data SHA-256 Hash:f67290788c83f970ffd26c0d250f178f3249fa1bd1f588a69d737175a643a0e4
Calculated data SHA-256 Hash:4360f19c17e53bb428dae3fb08f7c3a4b6631eedec0b3ef2dd60554fe74eed81
Testing kv parameter
Reference data and obtained data length in bytes are 3072 and 3072 respectively
Reference data SHA-256 Hash:b6aa4cc6470b620ad35f6e022851b033bd1f1d4a8e5194c221d34b1e1b341f43
Calculated data SHA-256 Hash:b6aa4cc6470b620ad35f6e022851b033bd1f1d4a8e5194c221d34b1e1b341f43
Testing cpAlpha parameter
Reference data and obtained data length in bytes are 8 and 8 respectively
Reference data SHA-256 Hash:3df4b35114b21dd91d1a357393f3f3f4c80de15b4d84baeea76849ab711712d5
Calculated data SHA-256 Hash:3df4b35114b21dd91d1a357393f3f3f4c80de15b4d84baeea76849ab711712d5
Testing cpOffset parameter
Reference data and obtained data length in bytes are 4 and 4 respectively
Reference data SHA-256 Hash:819e2da745ae956f9f6c6db7e5d10988c72f3464efe929f775055591974f7cf3
Calculated data SHA-256 Hash:819e2da745ae956f9f6c6db7e5d10988c72f3464efe929f775055591974f7cf3
Testing ilchessC parameter
Reference data and obtained data length in bytes are 12 and 12 respectively
Reference data SHA-256 Hash:5724fe22e49a6ff07f4170cfdb6ecca86e3def15072215d4575d35043bc03fd0
Calculated data SHA-256 Hash:5724fe22e49a6ff07f4170cfdb6ecca86e3def15072215d4575d35043bc03fd0
Testing brokenPixels parameter
Reference data and obtained data length in bytes are 10 and 10 respectively
Reference data SHA-256 Hash:0083af118d18a63c6bb552f21d0c4ee78741f988ecd319d3cd06cb6c85a68a63
Calculated data SHA-256 Hash:0083af118d18a63c6bb552f21d0c4ee78741f988ecd319d3cd06cb6c85a68a63
Testing outlierPixels parameter
Reference data and obtained data length in bytes are 10 and 10 respectively
Reference data SHA-256 Hash:0083af118d18a63c6bb552f21d0c4ee78741f988ecd319d3cd06cb6c85a68a63
Calculated data SHA-256 Hash:0083af118d18a63c6bb552f21d0c4ee78741f988ecd319d3cd06cb6c85a68a63
Hi,
I tried this driver to communicate MLX90640 thermopile sensor with a Raspberry Pi. Can this driver operate with an I2C clock speed of 10 kHz?
Struct paramsMLX90640 is very big. Do you really need all those float arrays inside?
Many STM32 MCUs have 20KB of RAM and it is very challenging accommodating such a big structure along with other variables.
Furthermore, it would be useful to use the const modifier when passing pointer to paramsMLX90640 because gives the user the info that a function cannot modify it and makes the struct eligible for being stored in flash.
Using C++ code is nice but why using constructs like the following?
int a = int(c/2);
Using a normal cast would make it portable to platforms without C++ compilers.
I am trying to develop a python application that can take the temperature data from the sensor like a thermometer. I do not need the thermal image I just need the temperature reading.
I used the fork of this library "pimoroni/mlx90640-library" but the hotspot.cpp code does not get compiled when running make and the python code examples do not work due to an error with the wrapper code I think. ImportError: dynamic module does not define init function (init_MLX90640)
Any help with the issues or advice on how to do what I'm asking would be greatly appreciated
Hi, I'm a developer to try use MLX90640 on STM32F767ZI Nucleo Board
I'm using STM32CubeIDE to use stm board and MLX90640.
With mlx90640-libarary of this git, I made a code for I2C Operation as below:
uint16_t user_i2c_read_Word(uint8_t id, uint16_t reg_addr)
{
uint8_t data[2];
uint8_t cmd[2];
cmd[0] = (reg_addr & 0xFF00) >> 8;
cmd[1] = reg_addr & 0x00FF;
if(HAL_I2C_Master_Transmit(&hi2c2, (id << 1), cmd, 2, HAL_MAX_DELAY)!= HAL_OK) return -1;
if(HAL_I2C_Master_Receive(&hi2c2, (id << 1) | 0x01, data, 2, HAL_MAX_DELAY)!= HAL_OK) return -1;
return ((uint16_t) (data[0] << 8)) | ((uint16_t)((data[1]) & 0x00FF));
}
int MLX90640_I2CRead(uint8_t slaveAddr, uint16_t startAddress,uint16_t nMemAddressRead, uint16_t *data)
{
uint16_t temp_address = startAddress;
uint16_t temp_data;
if(HAL_I2C_IsDeviceReady(&hi2c2, (slaveAddr << 1), 1, 2) != HAL_OK) return -1;
for(int i=0; i < nMemAddressRead; i++){
temp_data = user_i2c_read_Word(slaveAddr,temp_address);
if(temp_data == -1) return -1;
temp_address++;
*(data + i) = temp_data;
}
return 0;
}
int MLX90640_I2CWrite(uint8_t slaveAddr, uint16_t writeAddress, uint16_t data)
{
uint8_t reg_m,reg_l,dat_m,dat_l;
reg_m = (uint8_t) ((writeAddress & 0xFF00) >> 8); //Address MSB
reg_l = (uint8_t) (writeAddress & 0x00FF); //Address LSB
dat_m = (uint8_t) ((data & 0xFF00) >> 8); // Data MSB
dat_l = (uint8_t) (data & 0x00FF); //Data LSB
uint8_t Byte4[4]={0};
Byte4[0]=reg_m;
Byte4[1]=reg_l;
Byte4[2]=dat_m;
Byte4[3]=dat_l;
static uint16_t dataCheck;
HAL_I2C_IsDeviceReady(&hi2c2, (slaveAddr << 1), 1, 2);
if(HAL_I2C_Master_Transmit(&hi2c2, (slaveAddr << 1), Byte4, 4, HAL_MAX_DELAY) != HAL_OK) return -1;
return 0;
}
But, when I use
MLX90640_Error=MLX90640_SetRefreshRate(MLX_I2C_ADDR, RefreshRate); printf("MLX90640_SetRefreshRate Error: %d\r\n",MLX90640_Error); MLX90640_Error=MLX90640_SetChessMode(MLX_I2C_ADDR); printf("MLX90640_SetChessMode Error: %d\r\n",MLX90640_Error);
paramsMLX90640 mlx90640;
MLX90640_Error=MLX90640_DumpEE(MLX_I2C_ADDR, eeMLX90640);
printf("MLX90640_DumpEE Error: %d\r\n",MLX90640_Error);
MLX90640_Error=MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
printf("MLX90640_ExtractParameters Error: %d\r\n",MLX90640_Error);
for(i=0;i<3;i++)//Lose the start frame
{
MLX90640_Error=MLX90640_GetFrameData(MLX_I2C_ADDR, frame);
printf("MLX90640_GetFrameData Error: %d\r\n",MLX90640_Error);
HAL_Delay(500);
}
it works well with return MLX90640_Error value with 0.
However, frame from MLX90640_GetFrameData(MLX_I2C_ADDR, frame) has all value with 16 always.
Could you give me any advice to solve this problem?
I've already check: #12
At that issue, he use LL code for stm32f4, and LL structure of it with that of stm32f7 is differ.
Thus, I want to check first if the HAL code is alright or not.
Thank you for reading this issue.
Hi,
I am trying to use MLX90640 with ESP8266 and run Example1_BasicReadings.
But, I have not been able to get I2C communication to work.
Call to MLX90640_DumpEE > MLX90640_I2CRead > Wire.endTransmission(false) returns 2 or 3. Sometimes call to MLX90640_DumpEE hangs.
I am using frequency 100KHz. I have seen issue sparkfun/SparkFun_MLX90640_Arduino_Example#2 and #13.
Below is the output I get.
MLX90640 online!
No ack read
Pixel 0: 884.73C
Pixel 1: 0.00C
Pixel 2: 573.09C
Pixel 3: 0.00C
Pixel 4: nanC
Pixel 5: 0.00C
Pixel 6: nanC
Pixel 7: 0.00C
Pixel 8: nanC
Pixel 9: 0.00C
No ack read
No ack read
I have also modified core_esp8266_si2c.cpp > twi_readFrom function to handle len=0
unsigned char twi_readFrom(unsigned char address, unsigned char* buf,
unsigned int len, unsigned char sendStop){
...
for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false);
buf[len-1] = twi_read_byte(true); //original
....
}
to
unsigned char twi_readFrom(unsigned char address, unsigned char* buf,
unsigned int len, unsigned char sendStop){
...
if (len > 0) {
for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false);
buf[len-1] = twi_read_byte(true);
}
....
}
Please let me know if you have any pointers to solve this.
Thanks in advance.
Regards,
Vishal Kothari
I tried to change the I2C address of my MLX90640 by the following steps, using methods from the mlx90640-library:
Addressing the device at 0x33,
Write 0x0000 to register 0x240F
Sleep 10 ms or longer
Write 0xBE32 to register 0x240F
Sleep
power-off
Upon power-on, the device only responds with ACK to I2C address 0x00, returning either 0x008 or 0x009. NACK from all other addresses 0x01 through 0x7F. Repeating the above steps to 0x00 doesn't change anything.
Question 1: Have I ruined the device?
Question 2: Could someone please provide a working example that changes the I2C address so I don't repeat my mistake on another device?
Thank you -
in API in function
void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result){..}
shouldn't mode be determined instead
l.308: mode = (frameData[832] & 0x1000) >> 5;
as
l.308: mode = (frameData[832] & 0x1000) >> 12;
I apologize for being thick, but could someone please tell me whether the following is correct? I think that a frame is the entire 32*24 field of pixels, and a sub-page (in Chess mode) is the "even" or "odd" pixels within the frame. The "even" or "odd" sub-pages are updated in RAM alternately. If I use MLX90640_GetFrameData() to read RAM, I get the whole frame (both sub-pages at once), correct? I understand that the pixels in the two sub-pages are calibrated separately and their pixel temperatures are calculated separately, too.
BUT... The MLX90640 32x24 IR array Datasheet, Figure 7 "Recommended measurement flow" shows each each sub-page (sub-frame?) being read separately. Why would you do this if MLX90640_GetFrameData() returns the whole frame in one operation? Also, the example data spreadsheet includes two frames with 832 values in each. Are these supposed to be sub-pages or just two full example frames? Am I misunderstanding the nature of frames and sub-pages?
do you have the micropython driver for mlx90640? pls
Hi there
I want to read out different sensors with a raspberry pi 3 and store the data. One of this sensors is a MLX90640 which is mounted on an evaluation Board from melexis. To minimize the calculation load on the raspberry, i want the STM32 on the eval board to do all the necessary calculations.
Is there also a library (which runs on a Linux System) or a Documentation of the USB Interface of the Evaluation Board?
Thanks in advance for your support.
Best regards
See pimoroni#22 for context.
The long and short of it is that if MLX90640_BadPixelsCorrection
gets a list of {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}
it will fail since it doesn't check to see if the brokenPixels
or outlierPixels
arrays passed to it actually contain valid pixel indices.
I've fixed this rather ham-fistedly with a check against the first index for 0xFFFF
(see pimoroni@93bb625#diff-26f614063f9bb2756155e3e26d51b772R120) but I believe this is something that MLX90640_BadPixelsCorrection
should check.
Hi,
Iโm making a library for the MLX90640 myself, but I noticed the0x2432 EEPROM address always returns 0xFFFF whilst others, do not (used logic analyzer aswell). Iโve read on the internet that EEPROM registers with value 0xFFFF in it, are factory default and not reset. I'm a bit desperate for help, that's why I'm asking here. Is there a default value in this EEPROM address that I can write to it? Because if I calculate Ta at this time, KTPtat and KVptat become -1, bringing my Ta up to -2000 or something around that value.
In reference to the following code snippet:
static uint16_t eeMLX90640[832];
static uint16_t mlx90640Frame[834];
paramsMLX90640 mlx90640;
static float mlx90640To[768];
MLX90640_DumpEE (slaveAddress, eeMLX90640);
MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
MLX90640_GetFrameData (0x33, mlx90640Frame);
tr = MLX90640_GetTa(mlx90640Frame, &mlx90640) โ TA_SHIFT;
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
It would be really nice if you could upload a file with the eeMLX90640, mlx90640Frame, mlx90640, mlx90640To and tr
Just as test to prove that the API are doing their job.
I have noticed that in a lot of functions, for example: ExtractAlphaParameters math library pow function is used.
Nothing wrong but for a small system like STM32L072, RAM is precious and the pow function is very slow and uses a lot of stack.
I would replace all pow(2, x) with something like this (1 << x) that is way more efficient.
Doing this change I fixed a number of stack overflows.
At least it would be fine to replace the pow(2, x) with a define POW2(x), then someone could set:
#define POW2(x) pow(2, (double) X)
while someone else like me:
#define POW2(x) ((double) (1 << x))
I saw in the code that there are calculations involving big numbers like pow(2, 34) then it is better to deinfe POW2 like this:
#define POW2(x) ((double) ((long long)1 << x))
pi@raspberrypi:~/mlx90640-library $ ./thermalCam
Segmentation fault
Hello!
Thanks for the API, I'm trying to get it work together with our boards.
After the driver settings, I'm able to read data from the eeprom but it is inconsistent with your example data xlsx.
My test code is only calls MLX90640_DumpEE() and MLX90640_ExtractParameters() methods after i2c init. I attached the picture of the analyser's output, and the first 12 extracted parameters and the data from the eeprom.
The i2c driver's clock is about 375kHz.
Can you help me please, what i do wrong?
params.txt
eeprom.txt
Hi,
I have question how I can use this library with a custom pin for SDA and SCL on STM with mbed. We connected the camera on some arbitrary pins for SDA and SCL and when we are trying to print the EEPROM we are getting the 0x0000 values for all memory locations.
Let me know if you have any idea what is happening?
With respect,
Nusret
I seem to be running into an issue where any slight variance in the amount of time I delay between reads will cause the camera to output erroneous readings.
I am trying to use step mode to get data for subpage 0 and 1, which I can get to run successfully, but only under certain circumstances which I can't seem to pin down or recreate.
The datasheet mentions flags that should be polled for step mode:
2.By polling the flags (configuration IO at 0x92, bits 8 and 9)
But 0x92
is not a valid register address- these are 16-bit registers- and there's no "configuration IO" to my knowledge?
I have also tried polling the status register (0x8000
) and checking bit b3
(0x08
) but despite this being the "A new data is available in RAM" register, a read right after it's set seldom results in any valid sensor data.
Is the datasheet simply wrong, or am I missing something here? This library doesn't seem to support reading both subpages, and your own MLX90640_GetFrameData
appears to start a measurement up to 9 times and return an error if it exceeds 4 attempts?
mlx90640-library/functions/MLX90640_API.cpp
Lines 44 to 101 in 388d005
Looking at GetFrameData
since the first thing it does is check the status register for a "data ready" condition, then the first call to GetFrameData
will always fail in "step mode" since no reading will have been triggered?
MLX90640_GetFrameData() sets the statusRegister with MLX90640_I2CWrite(0x8000, 0x0030); If I read the register immediately, shouldn't its new value be 0x0030? Mine seems to be stuck at either 0x0008 or 0x0009. What could cause this?
Thank you -
Dear MLX90640 experts!
Currently we face some issues while we connect multiple MLX90640-device (actually via a Qwiic eval board) to one RPI. The goal is to connect 4 different devices to one master. We tested in different setups:
So finally, this boils down to our questions:
Has anybody seen such kind of stability problems when working with the RPI 3/4 and multiple MLX90640?
Is there any known issue for the I2C implementation of Raspbian which might lead to such a strange behaviour?
Is there any known issue in connecting multiple MLX90640 (maybe for other masters than RPI) to the I2C?
Are there better ways to acquire pictures with about 2-3 Hz max from four MLX90640 at the same time?
Thank you in advance for your help!
mario
I have 3 BAA 120 degree and 3 BAB 60 degree devices. Using this library I have no problems using the BAA devices. However the BAB devices failed to extract the EEPROM parameters.
After closer investigation it seems that the function
mlx90640-library/functions/MLX90640_API.cpp
Line 1277 in 0b76a54
BAA 0x240A: 0x48D - 10010001101
BAB 0x240A: 0x4D9 - 10011011001
If I alter the EEPROM validity check to reflect this all else works like expected.
I can not find any reference of this discrepancy between BAA and BAB devices in the datasheet, this library or errata. Is this a recent change, a fluke or some undocumented difference?
Hello!
I have an interesting problem. I tried to port the driver onto STM32 board. I rewrote the mlx90640_i2c_driver.
With my code, I can dump calibration data, then extract the parameters, and them seem correct. But the "MLX90640_GetFrameData" always stuck in a while loop, because the status register's data ready bit will never be 1.
paramsMLX90640 sensor_params;
static uint16_t eeData[832];
static uint16_t mlx90640Frame[834];
static float32_t pixels[768];
HAL_Delay(5000);
//Tried with another resolution, refresh-rate too
MLX90640_DumpEE(MLX90640_ADDR,eeData);
MLX90640_ExtractParameters(eeData,&sensor_params);
MLX90640_GetFrameData(MLX90640_ADDR,mlx90640Frame); // stuck here
MLX90640_CalculateTo(mlx90640Frame,&sensor_params,1,1,pixels);
In debug mode I can clearly see that the status register is always 0x0900.
I tried to solve it with direct register writings:
//initializations etc...
if(StartMeasTempSensor() != 0){
Error_Handler();
}
HAL_Delay(5000);
while(!CheckTempSensor()){ } // stuck here
int StartMeasTempSensor(){
uint16_t status_register;
uint16_t control_register;
int error = 0;
//Set control register
error += MLX90640_I2CRead(MLX90640_ADDR,0x800D,1,&control_register);
control_register = (control_register & 0xE000) | 0x1901;
error += MLX90640_I2CWrite(MLX90640_ADDR,0x800D,control_register);
//Set status register
error += MLX90640_I2CRead(MLX90640_ADDR,0x8000,1,&status_register);
status_register = (status_register & 0xFFC0) | 0x0030;
MLX90640_I2CWrite(MLX90640_ADDR,0x8000,status_register);
return error;
}
int CheckTempSensor(){
uint16_t status_register;
uint16_t control_register;
MLX90640_I2CRead(MLX90640_ADDR,0x800D,1,&control_register);
MLX90640_I2CRead(MLX90640_ADDR,0x8000,1,&status_register);
//Data ready
if((status_register & 0x0008) > 0){
return 1;
}
else{
if((status_register & 0x0020) == 0){
status_register = (status_register & 0xFFC0) | 0x0020;
MLX90640_I2CWrite(MLX90640_ADDR,0x8000,status_register);
}
return 0;
}
}
I noticed another interesting thing, if I write the control register, I can read back the correct value (e.g. 0x1901), so I think I2C communication is OK. But if I write the status register (e.g. 0x0930), I always read back 0x0900.
I have two senors, but both produce this (error).
Do you have any idea?
Thanks
Edit:
If I write 0x0901 to control register, i read out 0x0800 from the status register, I don't write to the status register, but new data never comes.
Hi,
I have the MLX90640 outputting data but have not yet gotten the driver to work.
I have read over the driver doc and the datasheet for the MLX90640 and found many typos and confusing errors. I would like to improve the documents. If I propose fixes, will you be able to correct the doc? How would you like typo fixes versus technical change recommendations?
A trivial example: page 10
MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
is correct but every following page
MLX90640_ExtractParameters(eeMLX90640,mlx90640);
Another, page 11:
vdd = GetVddMLX90640(mlx90640Frame, &mlx90640); //vdd = 3.3
should be
vdd = MLX90640_GetVddMLX90640(mlx90640Frame, &mlx90640); //vdd = 3.3
Cheers,
-Nathan
Hi:
When I tested, I found that the measured object was far away from the sensor, and the temperature dropped a lot. So I was wondering if there is any way to make the data correct.
Change emissivity or sensitivity? I don't know how to set it up.What is the maximum measurement distance of the MLX90640 (the distance of the sensor from the measured object)?
Have a nice day!
IAMLIUBO
The question has confused my for a long time. After I read data frames, the temperature values see a strong chessboard-pattern style. See images below (raw temperature data)
I marked some obviouslly abnormal points.
And here is my core measuring code :
int expectFrame = 0;
int subPagesRead = 0;
while (subPagesRead < 2) {
vTaskDelay(250 / portTICK_RATE_MS);
status = MLX90640_GetFrameData(0x33, mlx90640Frame);
if (status != expectFrame) {
continue;
}
expectFrame = 1 - expectFrame;
subPagesRead++;
float tr = MLX90640_GetTa(mlx90640Frame, &mlx90640) - TA_SHIFT;
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
}
// output mlx90640To
memset(mlx90640Frame, 0, sizeof(mlx90640Frame));
memset(mlx90640To, 0, sizeof(mlx90640To));
subPagesRead = 0;
}
Am I measuing in a wrong way? Or any other possible reasons?
(This frame is calculated at 4Hz refresh rate on a esp32 chip)
The following code within the function as title will always return -8.
cnt is incremented till value 5, and outside the loop, it will fail the check if(cnt > 4) return -8
while(dataReady != 0 && cnt < 5)
{
error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
if(error == -1)
{
return error;
}
error = MLX90640_I2CRead(slaveAddr, 0x0400, 832, frameData);
if(error != 0)
{
return error;
}
error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
if(error != 0)
{
return error;
}
dataReady = statusRegister & 0x0008;
cnt = cnt + 1;
}
if(cnt > 4)
{
return -8;
}
Another hiccup I hit implementing the driver: On many I2C sensors the read pointer is auto-incrementing between blocks of reads. I don't believe the MLX90640 auto increments the address pointer so you need to write the address before every read.
I don't believe this is documented in the datasheet or the driver. A note about this in the datasheet (or driver) would be helpful for those who are writing drivers for other platforms.
For example: You cannot read 50 bytes like this
I2C_read()
{
write address of the location to read
stop
read 32 bytes (max buffer size on many arduino implementations)
read 18 bytes (fails because address pointer has reset to 0x00)
}
This is how I implemented it for a Teensy 3.5:
//Read a number of words from startAddress. Store into Data array.
//Returns 0 if successful, -1 if error
int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data)
{
//Caller passes number of 'unsigned ints to read', increase this to 'bytes to read'
uint16_t bytesRemaining = nWordsRead * 2;
//It doesn't look like sequential read works. We need to re-issue the address command each time
uint16_t dataSpot = 0; //Start at beginning of array
//Setup a series of chunked I2C_BUFFER_LENGTH byte reads
while (bytesRemaining > 0)
{
Wire.beginTransmission(_deviceAddress);
Wire.write(startAddress >> 8); //MSB
Wire.write(startAddress & 0xFF); //LSB
if (Wire.endTransmission(false) != 0) //Do not release bus
{
Serial.println("No ack read");
return (0); //Sensor did not ACK
}
uint16_t numberOfBytesToRead = bytesRemaining;
if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH;
Wire.requestFrom((uint8_t)_deviceAddress, numberOfBytesToRead);
if (Wire.available())
{
for (uint16_t x = 0 ; x < numberOfBytesToRead / 2; x++)
{
//Store data into array
data[dataSpot] = Wire.read() << 8; //MSB
data[dataSpot] |= Wire.read(); //LSB
dataSpot++;
}
}
bytesRemaining -= numberOfBytesToRead;
startAddress += numberOfBytesToRead / 2;
}
return (0); //Success
}
CheckEEPROMValid() does the following check:
deviceSelect = eeData[10] & 0x0040;
which fails, but the data in the EEPROM is actually correct when parameters are extracted. I have this verified by checking the extracted parameters. As noted on the endianness issue in #31 , My data for eeData[10] in both big and little endian is 0x9904 and 0x0499 non-respectively, but this check will always fail.
Without documentation of this EEPROM for address 0x240A in the datasheet, it is difficult to know the cause of the failure. Maybe it is meant to be:
deviceSelect = eeData[10] & 0x0004
?
0x0499 is also present within the EEPROM data in the xlsx file in this repository, meaning the same check would fail when extracting sample parameters.
Hi everyone:
Today I try use STM32 HAL library to do this,but I found that I wasted a day.I thought it wouldn't be difficult, but I saw a lot of people have encountered similar problems, so I would like to ask if you finally solved it.
I tried this one: #12 ,I think this will make me successful, but the problem remains.
I notice this one: #42 ,then I think maybe many people meet the same problrm.
So if anyone have the same problem with me,We can solve it together.We can put any idea of here untill we solved it.
Is it possible to frame-synchronize two MLX90640 sensors so that they take a reading (image) exactly at the same time? Is it possible to have a synchronized "video stream" from two sensors where the individual frames are in sync?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.