borgThermo > 방사 온도계 > 제1회: STM32L476과 MLX90632의 통신(I2C)

동작환경
Ubuntu 18.04 LTS
ボード: STM32L476 Nucleo_64 (以下、STM32L476)
Zephyr 2.1.0-rc1
放射温度計センサー: MLX90632 (CLICK-IRThermo)
ロジック確認: Analog Discovery 2 (AD2)

방사 온도계 센서 개발



Zephyr의 공부도 겸해 borgThermo라는 프로젝트를 시작했다.
본 프로젝트의 최종 제품으로서 방사 온도계를 검토하고 있다.
개발은 2020년 7월까지는 걸릴 것이다.

제1회



방사 온도계 센서와의 I2C 통신의 구현까지를 했다.
EEPROM versiono 및 I2C slave address >> 1의 값을 읽을 때까지.

마인드 맵


  • 구성품 검토
  • 포트 검토
  • 기판 배치

  • 방사 온도계 센서 MLX90632 (CLICK-IRThermo)


  • MLX90632 방사 온도계 센서 클릭 보드 [CLICK-IRThermo]

  • 풀업 저항은 기판상에 실장 완료.

    연결


  • STM32L476 <--> MLX90632 [CLICK-IRThermo]
  • CN5:10 (SCL) <--> SCL
  • CN5:9 (SDA) <--> SDA
  • CN6:4 (3V3) <--> 3V3
  • CN6:6 (GND) <--> GND


  • CLICK-IRThermo 쪽은 실크 인쇄로 기능이 기재되어 있다.
    어느 핀이 1번인지 명시적이지 않다.
    기능에 따라 연결을 했다.

    구현



    프로젝트 위치



    프로젝트는 samples/drivers/wrk_MLX90632_200201 이하에 준비했다.
    Zephyr의 i2c_scanner라는 프로젝트가 과거에 있었고 그 프로젝트를 복사하여 변경했습니다.
    i2c_scanner는 최신판 Zephyr에는 없는 것 같다.

    prj.conf



    prj.conf
    CONFIG_PRINTK=y
    CONFIG_I2C=y
    CONFIG_SERIAL=y
    

    libMLX90632



    libMLX96032.h
    #ifndef LIB_MLX90632_H
    #define LIB_MLX90632_H
    
    //#include <stdint.h>
    
    /*
    for MLX90632 FIR sensor
    */
    
    uint16_t MLX90632_readEEPROMversion();
    uint16_t MLX90632_readI2CSlaveSddress();
    
    #endif
    

    libMLX96032.c
    #include <stdint.h>
    #include <stdlib.h>
    #include <zephyr.h>
    #include <device.h>
    #include <drivers/i2c.h>
    #include <sys/printk.h>
    
    /*
    for MLX90632 FIR sensor
    */
    
    /*
    v2020.Feb.01
        - add MLX90632_readI2CSlaveSddress()
        - add MLX90632_readEEPROMversion()
        - add writeReadDevice()
    */
    
    #ifdef ARDUINO_I2C_LABEL
    #define I2C_DEV ARDUINO_I2C_LABEL
    #else
    #define I2C_DEV "I2C_1" // Nov. 25, 2019 for STM32F769I_disco
    #endif
    
    #define ADDR_EE_VERSION (0x240B)  // EEPROM version
    #define ADDR_I2C_SLAVE_ADDR (0x24D5) // I2C slave address >> 1
    
    static const uint8_t kDeviceAddr = 0x3A; // MLX90632
    
    //------------------------------------------------------------------------------------------
    // private function
    //
    static void writeReadDevice(uint8_t *cmdByte, int cmdlen, uint8_t *dataByte, int datalen) 
    {
        struct device *i2c_dev;
        i2c_dev = device_get_binding(I2C_DEV);
        i2c_write_read(i2c_dev, kDeviceAddr, cmdByte, cmdlen, dataByte, datalen);
    //    k_usleep(27); // 26.3us // TODO: this is for AQM0802 not for MLX90632
    }
    
    //------------------------------------------------------------------------------------------
    // public function
    //
    uint16_t MLX90632_readEEPROMversion()
    {
        uint8_t wrlist[] = {ADDR_EE_VERSION >> 8, ADDR_EE_VERSION & 0xFF};
        uint8_t rdlist[10];
        writeReadDevice(wrlist, 2, rdlist, 2); 
        uint16_t res = rdlist[0] << 8 | rdlist[1];
        printk("0x%04x\r\n", res);
    }
    
    uint16_t MLX90632_readI2CSlaveSddress()
    {
        uint8_t wrlist[] = {ADDR_I2C_SLAVE_ADDR >> 8, ADDR_I2C_SLAVE_ADDR & 0xFF};
        uint8_t rdlist[10];
        writeReadDevice(wrlist, 2, rdlist, 2); 
        uint16_t res = rdlist[0] << 8 | rdlist[1];
        printk("0x%04x\r\n", res);
    }
    

    main.c



    main.c
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/i2c.h>
    
    #include <stdint.h>
    #include "libMLX90632.h"
    
    #ifdef ARDUINO_I2C_LABEL
    #define I2C_DEV ARDUINO_I2C_LABEL
    #else
    //#define I2C_DEV "I2C_0"
    #define I2C_DEV "I2C_1" // Nov. 25, 2019 for STM32F769I_disco (also for STM32L476)
    #endif
    
    void main(void)
    {
        MLX90632_readEEPROMversion();
        MLX90632_readI2CSlaveSddress();
    }
    

    빌드 및 실행


    $ west build -p auto -b nucleo_l476rg samples/drivers/wrk_MLX90632_200201
    $ west flash
    $ west flash
    

    west flash는 1회째에 실패하는 일이 있어, 2회 실행하기로 하고 있다.

    하나의 터미널에서 다음을 실행하여 디버그 출력을 표시하는 상태로 둡니다.
    (종료는 Ctrl+a,k)
    $ sudo screen /dev/ttyACM0 115200
    

    다른 터미널에서 실행한다.
    $ west debug
    ...
    (gdb) c
    

    디버그 출력의 터미널은 다음과 같다.
    *** Booting Zephyr OS build zephyr-v2.1.0-866-ga80987836542  ***
    0x0205
    0x001d
    

    흠집


  • i2c_transfer ()에서 통신을 시도했지만 실패하고 i2c_write_read로 성공했음을 Analog Discovery 2에서 확인했습니다.

    로직



    Analog Discovery 2의 로직 모니터.



  • 좋은 웹페이지 즐겨찾기