MLX90640 for C/C++

The C-based API for our MLX90640 driver allows your C or C++ application to use the device.

The demonstration application reports temperature readings in degrees celcius.

      
#include "ids_mlx90640.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, const char * argv[] )
{
    if( argc != 2 )
    {
        fprintf( stderr, "usage %s <i2c-device>\n", argv[0] );
        return EXIT_FAILURE;
    }

    // The temperature calculation is affected by some environmental
    // constants.  We provide typical values in this case.
    const ids_mlx90640_constants_t K
    = {
        .T_a0       = 25.,
        .V_dd0      = 3.3,
        .T_base     = 273.15,
        .emissivity = 1.
    };

    // Open a connection to the MLX90640 device using the specified
    // I2C bus.
    ids_mlx90640_hdl_t mlx90640 = ids_mlx90640_open( argv[1], &K );
    if( mlx90640 == ids_mlx90640_NoHdl )
    {
        fprintf( stderr, "unable to open MLX90640 at:%s\n", argv[1] );
        return EXIT_FAILURE;
    }

    ids_mlx90640_pixels_t pixels;
    memset( &pixels, 0, sizeof( pixels ) );
    while( true )
    {
        // Block the application until a new page is available.
        ids_mlx90640_page_e page = ids_mlx90640_read_next_page( mlx90640 );
        if( page >= ids_page_num )
        {
            fprintf( stderr, "read error\n" );
            return EXIT_FAILURE;
        }

        // After reading values, the application triggers calculation of
        // calibrated temperatures.
        bool rc = ids_mlx90640_update_page( mlx90640, page, &pixels );
        if( ! rc )
        {
            fprintf( stderr, "calculation error\n" );
            return EXIT_FAILURE;
        }

        // Draw a grid of the calibrated temperatures.  The driver reads the
        // full 32 columns.  For display here we limit to showing only the
        // first half.
        for( int r = 0; r < 24; ++r )
        {
            for( int c = 0; c < 16; ++c )
                printf( "%4.1f ", pixels.To[r][c] );
            printf( "... \n" );
        }

        printf( "\n" );
    }

    // Close the driver connection before exiting the script.  This application
    // does not actually run this far.
    ids_mlx90640_close( mlx90640 );
    return EXIT_SUCCESS;
}
      
    

The following sample output is from a test run on a Jetson Nano. This is a 64-bit device running on an ARM A57 core.

      
ae@jetson:~$ ./example03 /dev/i2c-0
21.8 19.7 24.2 21.4 22.2 20.7 24.3 22.5 21.9 21.1 24.0 22.0 22.3 21.4 24.5 22.6  ...
19.8 22.0 22.9 22.9 21.1 21.8 23.2 22.2 21.3 21.7 23.7 22.5 21.6 22.5 23.8 22.9  ...
22.6 20.3 24.3 21.7 22.2 21.1 23.9 21.9 22.4 21.5 24.1 22.3 22.4 21.9 24.4 22.6  ...
20.6 22.5 23.4 22.5 21.3 21.8 23.5 22.6 21.4 22.6 23.6 23.2 21.9 22.4 23.6 23.1  ...
22.3 20.7 23.3 21.7 22.0 21.0 23.4 22.2 22.0 21.2 23.7 22.2 22.8 22.0 24.1 22.9  ...
21.2 22.4 22.6 22.4 21.6 21.5 22.8 22.6 21.3 22.3 23.3 22.6 21.9 22.7 23.4 23.1  ...
22.6 20.9 24.1 22.0 22.2 21.2 24.0 21.8 21.9 21.3 23.6 21.5 22.3 21.5 23.5 22.2  ...
20.8 22.3 23.7 22.7 21.6 22.1 23.2 22.1 21.0 22.1 22.7 22.0 21.6 21.9 23.2 22.8  ...
22.4 20.9 24.0 21.7 21.6 21.2 23.5 21.7 22.0 20.8 23.4 21.7 21.8 21.3 23.5 21.9  ...
21.1 21.7 23.2 22.5 21.0 22.0 22.9 22.8 21.3 21.8 22.7 22.5 21.3 21.9 22.7 22.3  ...
21.6 20.6 23.7 21.4 21.7 21.0 23.7 21.6 22.1 21.4 23.6 22.0 22.3 21.5 23.3 21.9  ...
20.2 21.5 22.5 22.0 21.5 21.8 23.1 22.3 21.4 21.9 22.8 22.5 21.8 22.0 23.0 22.2  ...
21.7 20.5 23.8 20.8 21.4 21.3 23.4 22.0 22.0 21.4 23.6 21.8 22.0 21.6 23.2 21.5  ...
20.6 21.3 22.5 22.2 21.1 22.1 22.8 22.1 21.1 21.9 22.9 22.4 21.7 21.9 22.5 22.2  ...
21.2 20.6 22.9 21.1 21.4 21.0 23.5 21.8 21.8 21.2 23.6 22.2 22.4 21.5 23.6 22.2  ...
20.5 20.8 22.5 21.9 20.9 21.0 22.5 21.9 21.1 21.4 22.8 22.2 21.8 22.0 23.0 22.8  ...
21.5 20.4 23.6 21.3 21.5 20.6 23.2 21.4 21.9 21.0 23.1 21.5 22.2 21.6 23.6 22.5  ...
20.8 21.4 22.7 21.9 20.7 21.6 22.5 22.4 21.2 21.8 22.9 21.8 21.5 21.8 23.0 22.9  ...
21.5 20.0 22.9 20.9 21.7 20.3 23.2 21.5 21.7 21.3 23.2 21.4 22.1 21.3 23.2 22.1  ...
20.4 21.2 22.9 22.1 20.8 21.7 22.5 21.9 20.9 21.5 22.8 22.1 21.5 21.6 22.7 22.3  ...
21.3 19.9 23.7 21.0 21.1 20.5 23.5 21.4 22.0 21.1 23.4 21.4 21.7 21.1 23.4 21.6  ...
20.5 20.8 22.6 21.8 20.3 21.6 23.1 21.6 21.1 21.7 22.8 21.9 21.5 21.7 23.0 22.1  ...
20.9 19.4 23.4 21.2 21.4 20.8 23.1 21.0 21.3 20.6 23.3 21.5 21.8 21.0 23.3 21.7  ...
20.1 21.3 23.5 22.4 20.7 21.4 22.6 22.1 21.0 21.0 22.5 22.0 21.0 21.6 22.6 22.0  ...
             
    

Device Configuration

Our driver interface also supports reading and modifying the device configuration. These are values that are written to the non-persistent storage of the MLX90640, the settings are used until the device is restarted.

      
#include "ids_mlx90640.h"
#include <stdio.h>
#include <stdlib.h>

int main( int argc, const char * argv[] )
{
    if( argc != 2 )
    {
        fprintf( stderr, "usage %s <i2c-device>\n", argv[0] );
        return EXIT_FAILURE;
    }

    // This example opens the driver without providing values for the
    // environmental constants because this application does not read
    // temperatures.
    ids_mlx90640_hdl_t mlx90640 = ids_mlx90640_open( argv[1], NULL );
    if( mlx90640 == ids_mlx90640_NoHdl )
    {
        fprintf( stderr, "unable to open MLX90640 at:%s\n",
                    argv[1] );
        return EXIT_FAILURE;
    }

    ids_mlx90640_set_mode(         mlx90640, ids_mode_interleave );
    ids_mlx90640_set_refresh_rate( mlx90640, ids_hz_4 );
    ids_mlx90640_set_resolution(   mlx90640, ids_bits_18 );

    // Read the configuration and decode to strings.
    const char * mode_str = "invalid";
    switch( ids_mlx90640_get_mode( mlx90640 ) )
    {
    case ids_mode_chess:
        mode_str = "chess";
        break;
    case ids_mode_interleave:
        mode_str = "interleave";
        break;
    }

    const char * rate_str = "invalid";
    switch( ids_mlx90640_get_refresh_rate( mlx90640 ) )
    {
    case ids_hz_half: rate_str = "0.5 Hz"; break;
    case ids_hz_1:  rate_str =  "1 Hz"; break;
    case ids_hz_2:  rate_str =  "2 Hz"; break;
    case ids_hz_4:  rate_str =  "4 Hz"; break;
    case ids_hz_8:  rate_str =  "8 Hz"; break;
    case ids_hz_16: rate_str = "16 Hz"; break;
    case ids_hz_32: rate_str = "32 Hz"; break;
    case ids_hz_64: rate_str = "64 Hz"; break;
    }

    const char * res_str = "invalid";
    switch( ids_mlx90640_get_resolution( mlx90640 ) )
    {
    case ids_bits_16: res_str = "16 bits"; break;
    case ids_bits_17: res_str = "17 bits"; break;
    case ids_bits_18: res_str = "18 bits"; break;
    case ids_bits_19: res_str = "19 bits"; break;
    }

    printf( "          Mode:%s\n", mode_str );
    printf( "  Refresh Rate:%s\n", rate_str );
    printf( "ADC Resolution:%s\n", res_str );

    // Close the driver connection before exiting.
    ids_mlx90640_close( mlx90640 );
    return EXIT_SUCCESS;
}
      
    

The following sample output is from a test run on a Raspberry Pi 4. This is a 32-bit build running on an ARM Cortex-A72 core.

      
pi@pi9:~ $ ./example02 /dev/i2c-1 
          Mode:interleave
  Refresh Rate:4 Hz
ADC Resolution:18 bits
    
    

Ordering

More detail, including a pricing sheet, is available upon request.

Thanks for your interest! The pricing sheet for the driver has been sent to .