MAX31865 抵抗ーデジタル変換 Arduino | zweisteinjpのブログ

zweisteinjpのブログ

組込み関係の自作や趣味の音楽関係についてが主体に気ままに書いていきたいと考えています。
好きなミュージシャンはアランホールズワースで、音色やフレージング含めて気に入ってます。

RTD (Resistance Temperature Detector)はサーミスターとは特性は異なりますが、温度センサとして使われているデバイスです。PT100とかはその例になります。プラチナ(PT)で100Ωの時に0degCの特性を持ちます。PT100の温度ー抵抗特性はネットでググるなり何なり検索して頂ければ幾らでも出てきます。

 

マイコンでRTDの値を取得するのに便利なチップが存在しており、その一つがMAX31865です。

 

 

https://www.analog.com/jp/products/max31865.html

 

AdafruitやMikroElektronika社がこのチップを使ったボードを販売していますし、中華系だと1/10くらいの値段で同じチップがのったボードを出しています。中華系は保証が何もなくどこからパクってきたのか分からないネタでコピーしまくってくるので、値段があり得ないくらい安いのですが、個人でリスク管理してダメ元で買ってトライするか、10倍のコストでまともなやつを買うかのすごい状態になっています。

 

 

 

 

 

MAX31865を使って温度計測をする場合のインターフェースはSPIになります。

またとにかく試すのはArduinoがやはりお手軽なので、Arduinoを使います。

 

ライブラリマネージャーで31865と入力するとAdafruit MAX31865 libraryが見つかります。

 

 

インストールが完了するとスケッチ例のところでAdafruit MAX31865 library -> max31865と辿るとサンプルが見つかります。

 

 

max31865が動いていることが分かれば良いだけならPT100とか別に用意する必要はなくて、可変抵抗とかで抵抗を読ませれば抵抗に応じた変換した結果を確かめることが出来ます。

 

参考までにお試しに作ったガジェットのソースコードを載せておきます。

 

Adafuruit のMAX31865ボードとRTD Clickですとライブラリ的には使えるのですが、回路定数が一部異なっており、

Reference抵抗の値がAdafuruitのボードでは430Ωなのが、RTD Clickですと470Ωの為、ライブラリの部分を変更

する必要はありませんが、メインソース側で定義する抵抗値を変更しています。

 

 

// RTD Measurement and Display sample for RTD Click using OLED and 7SEG

/*************************************************** 
  This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865

  Designed specifically to work with the Adafruit RTD Sensor
  ----> https://www.adafruit.com/products/3328

  This sensor uses SPI to communicate, 4 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Adafruit_MAX31865.h>
#include <SPI.h>
#include <Wire.h> // for OLED
#include <Adafruit_GFX.h>    // for OLED
#include <Adafruit_SSD1306.h>  // for OLED
#include "TM1637.h"   // For 7SEG

// Pins definitions for TM1637 and can be changed to other ports
const int CLK = 6;
const int DIO = 7;
TM1637 tm1637(CLK, DIO);
float number = 777;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(10);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
//#define RREF      430.0   // Adafruit version
#define RREF  470.0  // RTD Click Version

// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");

  thermo.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary

   

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

   display.display();
   delay(2000); // Pause for 2 seconds
   display.clearDisplay();
   display.setTextSize(1);      // Normal 1:1 pixel scale
   display.setTextColor(SSD1306_WHITE); // Draw white text
   display.setTextColor(WHITE);

    tm1637.init();
    tm1637.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
    float num = 000.00;

    // Without specifying decimal pointt it displays int
    tm1637.displayNum(num);    // -123
    
    delay(1000);



}


void loop() {



  
  uint16_t rtd = thermo.readRTD();

  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
  }
  Serial.println();
  
   display.clearDisplay();
   display.setCursor(0, 0);
   display.print("RTD Value:");
   display.setCursor(80, 0);
   display.print(rtd);

   //display.setCursor(0, 10);
   //display.print("Ratio:");
   //display.setCursor(80, 10);
   //display.print(ratio);

   display.setCursor(0, 10);
   display.print("Resistance:");
   display.setCursor(80, 10);
   display.print(RREF*ratio);

   display.setCursor(0, 20);
   display.print("Temperature:");
   display.setCursor(80, 20);
   display.print(thermo.temperature(RNOMINAL, RREF));

   display.display(); 

   number = thermo.temperature(RNOMINAL, RREF);

   tm1637.displayNum(number);

 
  delay(1000);
}