・最近の新型コロナの影響で非接触型の温度計を作ってみました。
 毎日の体温の目安になるのではと思っています。

■画面の説明
上から
①周囲温度
②ターゲット温度
③MIN,MAX温度
④釦Aを押したときのターゲット温度(Hold)

*釦Bを押すとリスタートし、データをクリア出来ます。


S__43614232


S__43614231


mlx90615


■使用部品
①M5StickC
③ピンヘッダ、ピンソケット(手持ちの部品)


■ライブラリは、下記のものを使いましたが、そのままではエラーが発生しましたので
ヘッダーファイルを編集しました。


下記の三つのファイルを同じフォルダに保存してコンパイルしました。
mlx90615.ino
mlx90615.h
mlx90615.cpp

■スケッチ

//mlx90615.ino

// 2020/03/06 Yoshito Hashiguchi

#include <M5StickC.h>
#include <Wire.h>
#include "mlx90615.h"

MLX90615 mlx;

float maxtemp=0.0;
float mintemp=100.0;
float hold=0.0;
float objtemp=0.0;
float ambitemp=0.0;

void setup() {

  Serial.begin(115200);
  M5.begin();
  M5.Lcd.setRotation(0);
  M5.Lcd.fillScreen(BLACK);

  Wire.begin(0, 26, 400000); //SDA, SCL
  Serial.println("Melexis MLX90615 infra-red temperature sensor");
  Serial.print("Sensor ID number = ");
  Serial.println(mlx.get_id(), HEX);
}

int ct=0;

void loop() {

  M5.update();
  if ( M5.BtnA.wasPressed() ) {
    hold=mlx.get_object_temp();
  }
  if ( M5.BtnB.wasPressed() ) {
    esp_restart();
  }
  ct++;
  if (ct>100) {
    ambitemp=mlx.get_ambient_temp();
    objtemp=mlx.get_object_temp();
    if (mintemp>objtemp) mintemp=objtemp;
    if (maxtemp<objtemp) maxtemp=objtemp;
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(0,0);
    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(GREEN); 
    M5.Lcd.printf("ambient temp\n");
    M5.Lcd.setTextSize(3);M5.Lcd.setTextColor(WHITE);   
    M5.Lcd.printf("%3.1f\n",ambitemp);
    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(GREEN); 
    M5.Lcd.printf("\nterget  temp\n");
    M5.Lcd.setTextSize(3);M5.Lcd.setTextColor(WHITE);   
    M5.Lcd.printf("%3.1f\n",objtemp);
    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(CYAN);  
    M5.Lcd.printf("\nBtnB=Restart\n");
    M5.Lcd.setTextColor(GREEN); 
    M5.Lcd.printf("Battery:%3.1fV\n", M5.Axp.GetBatVoltage());

    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(GREEN);  
    M5.Lcd.printf("\n min   max\n"); 
    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(WHITE);   
    M5.Lcd.printf(" %3.1f  %3.1f\n",mintemp,maxtemp);
    
    M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(CYAN);   
    M5.Lcd.printf("\nBtnA = hold\n");
    M5.Lcd.setTextSize(3);M5.Lcd.setTextColor(WHITE);     
    M5.Lcd.printf("%3.1f\n",hold);

 
    ct=0;
  }
  delay(10);
}

■ヘッダーファイル

//mlx90615.h

#ifndef __MLX90615_H__
#define __MLX90615_H__

#include "Wire.h"

// default MLX90615 I2C address
#define MLX90615_I2C_ADDR 0x5B

// ROM - ID number
#define MLX90615_REG_ID_LOW 0x1E
#define MLX90615_REG_ID_HIGH 0x1F
// RAM - ambient temperature register
#define MLX90615_REG_TEMP_AMBIENT 0x26
// RAM - object temperature register 
#define MLX90615_REG_TEMP_OBJECT 0x27

class MLX90615 {
 public:
  MLX90615(uint8_t i2c_addr = MLX90615_I2C_ADDR);
  void begin();
  uint32_t get_id();
  float get_object_temp();
  float get_ambient_temp();

 private:
  uint8_t i2c_addr_;
  uint16_t read_word16(uint8_t reg);
};
#endif // __MLX90615_H__

■C++ソースファイル

//mlx90615.cpp

#include "mlx90615.h"

MLX90615::MLX90615(uint8_t i2c_addr) {
  i2c_addr_ = i2c_addr;
}

void MLX90615::begin() {
  Wire.begin();
}

uint32_t MLX90615::get_id() {
uint32_t id;
id = read_word16(MLX90615_REG_ID_LOW);
id |= (uint32_t)read_word16(MLX90615_REG_ID_HIGH) << 16;
return id;
}

float MLX90615::get_ambient_temp() {
  float temp;
  temp = read_word16(MLX90615_REG_TEMP_AMBIENT) * 0.02 - 273.15;
  return temp;
}

float MLX90615::get_object_temp() {
  float temp;
  temp = read_word16(MLX90615_REG_TEMP_OBJECT) * 0.02 - 273.15;
  return temp;
}

uint16_t MLX90615::read_word16(uint8_t reg) {
  uint16_t data;
  Wire.beginTransmission(i2c_addr_);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(i2c_addr_, (uint8_t)3);
  data = Wire.read();       // read low byte
  data |= Wire.read() << 8; // read high byte
  Wire.read(); // read and discard PEC (packet error code)
  return data;
}