Ubuntu 18.04 LTS
ボード: STM32L476 Nucleo_64 (以下、STM32L476)
Zephyr 2.1.0-rc1
放射温度計センサー: MLX90632 (CLICK-IRThermo)
ロジック確認: Analog Discovery 2 (AD2)
放射温度計センサーの開発
Zephyrの勉強も兼ねてborgThermoというプロジェクトを立ち上げた。
本プロジェクトの最終プロダクトとして放射温度計を検討している。
開発は2020年7月まではかかるだろう。
第一回
放射温度計センサーとのI2C通信の実装までをした。
EEPROM versionoおよびI2C slave address >> 1の値を読み取るところまで。
マインドマップ
放射温度計センサー 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
CONFIG_PRINTK=y
CONFIG_I2C=y
CONFIG_SERIAL=y
libMLX90632
# ifndef LIB_MLX90632_H
# define LIB_MLX90632_H
//#include <stdint.h>
/*
for MLX90632 FIR sensor
*/
uint16_t MLX90632_readEEPROMversion();
uint16_t MLX90632_readI2CSlaveSddress();
# endif
# 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
# 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は一回目に失敗することがあり、二回実行することにしている。
一つのターミナルで以下を実行して、デバッグ出力を表示する状態にしておく。
(終了は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でのロジックモニタ。