Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑨ 温度センサ 熱電対 MCP9601
Adafruitから入手した温度センサMCP9601(マイクロチップ)を利用します。K、J、T、N、S、E、B、Rの熱電対に対応しています。一般的にはK型が安価でよく使われ、ほかの半導体温度センサに比べて高温や低温の測定に適しています。
●AdafruitのStemma QT/Qwiicボード
Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。
コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。
●温湿度センサMCP9601のおもなスペック
- 動作電圧 2.7〜5.5V
- 温度の確度 ±2.0°C/±4.0°C (標準/最大)、K 熱電対の精度は約 ±2°C ~±6°C
- 分解能 ±0.0625 °C(これはADCの単なる分解能であり、確度ではない)
- 変換時間 320ms(18ビット)
- インターフェース I2C(10~100kHz)
<熱電対対応温度>
- K 型: -200~+1372°C
- J 型: -150~+1200°C
- T 型: -200~+400°C
- N 型: -150~+1300°C
- E 型: -200~+1000°C
- S 型: +250~+1664°C
- B 型: +1000~+1800°C
- R 型: +250~+1664°C
●使用環境
- Arduino UNO R4 Minima
- Arduino IDE 2.1.1
- Windows10 22H2
●接続
Arduino UNO R4 MinimaのI2C信号とセンサをJSTコネクタでつなぎます(Stemma QT/Qwiicボードの写真の比率は異なる)。電源は3.3Vです。
ボード上には、付属している2極のターミナルをはんだ付けします。そこに、K型熱電対をつなげました。熱電対には極性があります。どちらかわからない場合はとりあえず接続し、先端を指でつまんで温度が35,6度になるほうが正しいです。
●スレーブ・アドレスを確認
従来からよく使われているi2cScanner.inoを動かしてスレーブ・アドレスを確認します。電源は5Vです。
0x67を見つけてきました。
以降のスケッチは3.3Vで動作させます。
●ライブラリの用意
MCP9600で検索して、見つかったAdafruit MCP9600ライブラリをインストールします。
インストールを始めると次のパネルが出ました。
全てをインストールを選びました。
●スケッチ
メニューのファイル->スケッチ例から、Adafruit MCP9600 Libraryのmcp9601_test.inoを選択し、
コンパイル、実行します。
●7セグメントLED表示をつなぐ
連載の第4回目の記事を参照しながら表示器を接続します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ④ 温湿度センサSi7021の測定結果を7セグメントLEDに表示
スケッチです。
#include "Adafruit_MCP9601.h"
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#define I2C_ADDRESS (0x67)
Adafruit_MCP9601 mcp;
Adafruit_7segment matrix = Adafruit_7segment();
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit MCP9601 + 7segment LED");
/* Initialise the driver with I2C_ADDRESS and the default I2C bus. */
if (! mcp.begin(I2C_ADDRESS)) {
Serial.println("Sensor not found. Check wiring!");
while (1);
}
Serial.println("\nFound MCP9601!");
mcp.setADCresolution(MCP9600_ADCRESOLUTION_18);
mcp.setThermocoupleType(MCP9600_TYPE_K);
mcp.setFilterCoefficient(3);
Serial.print("Filter coefficient value set to: ");
Serial.println(mcp.getFilterCoefficient());
mcp.setAlertTemperature(1, 30);
Serial.print("Alert #1 temperature set to ");
Serial.println(mcp.getAlertTemperature(1));
mcp.configureAlert(1, true, true); // alert 1 enabled, rising temp
mcp.enable(true);
Serial.println(F("------------------------------"));
matrix.begin(0x70);
matrix.setBrightness(0x05); // default 0x0E
}
void loop()
{
uint8_t status = mcp.getStatus();
Serial.print("\nMCP Status: 0x");
Serial.print(status, HEX);
Serial.print(": ");
if (status & MCP9601_STATUS_OPENCIRCUIT) {
Serial.println("Thermocouple open!");
return; // don't continue, since there's no thermocouple
}
if (status & MCP9601_STATUS_SHORTCIRCUIT) {
Serial.println("Thermocouple shorted to ground!");
return; // don't continue, since the sensor is not working
}
if (status & MCP960X_STATUS_ALERT1) { Serial.print("Alert 1, "); }
if (status & MCP960X_STATUS_ALERT2) { Serial.print("Alert 2, "); }
if (status & MCP960X_STATUS_ALERT3) { Serial.print("Alert 3, "); }
if (status & MCP960X_STATUS_ALERT4) { Serial.print("Alert 4, "); }
Serial.println();
float c = mcp.readThermocouple();
Serial.print("Hot Junction: "); Serial.println(c);
Serial.print("Cold Junction: "); Serial.println(mcp.readAmbient());
matrix.print(c,2);
matrix.writeDisplay();
delay(5000);
}
実行例です。
●グラフィック・ディスプレイに表示
次の記事を参考に、グラフィック・ディスプレイに測定した温度を表示します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑤ 温湿度センサSi7021の測定結果をグラフィック・ディスプレイに表示
スケッチです。
#include "Adafruit_MCP9601.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_MCP9601 mcp;
#define MCP9601_I2C_ADDRESS 0x67
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit MCP9601 + SSD1306");
/* Initialise the driver with I2C_ADDRESS and the default I2C bus. */
if (! mcp.begin(MCP9601_I2C_ADDRESS)) {
Serial.println("Sensor not found. Check wiring!");
while (1);
}
Serial.println("\nFound MCP9601!");
mcp.setADCresolution(MCP9600_ADCRESOLUTION_18);
mcp.setThermocoupleType(MCP9600_TYPE_K);
mcp.setFilterCoefficient(3);
Serial.print("Filter coefficient value set to: ");
Serial.println(mcp.getFilterCoefficient());
mcp.setAlertTemperature(1, 30);
Serial.print("Alert #1 temperature set to ");
Serial.println(mcp.getAlertTemperature(1));
mcp.configureAlert(1, true, true); // alert 1 enabled, rising temp
mcp.enable(true);
Serial.println(F("------------------------------"));
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.drawRect(0, 0, display.width(), display.height(), SSD1306_WHITE);
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(4,3);
display.println("Temperature:");
display.display();
delay(200);
}
void loop()
{
uint8_t status = mcp.getStatus();
Serial.print("\nMCP Status: 0x");
Serial.print(status, HEX);
Serial.print(": ");
if (status & MCP9601_STATUS_OPENCIRCUIT) {
Serial.println("Thermocouple open!");
return; // don't continue, since there's no thermocouple
}
if (status & MCP9601_STATUS_SHORTCIRCUIT) {
Serial.println("Thermocouple shorted to ground!");
return; // don't continue, since the sensor is not working
}
if (status & MCP960X_STATUS_ALERT1) { Serial.print("Alert 1, "); }
if (status & MCP960X_STATUS_ALERT2) { Serial.print("Alert 2, "); }
if (status & MCP960X_STATUS_ALERT3) { Serial.print("Alert 3, "); }
if (status & MCP960X_STATUS_ALERT4) { Serial.print("Alert 4, "); }
Serial.println();
float Temperature = mcp.readThermocouple();
Serial.print("Hot Junction: "); Serial.println(Temperature);
Serial.print("Cold Junction: "); Serial.println(mcp.readAmbient());
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(10,17);
display.fillRect(10, 17, 70, 16, SSD1306_BLACK);
display.println(Temperature);
display.display();
delay(5000);
}
実行例です。