COFFEE 自家焙煎 タイマー付き温度計 「ROAST TIMER」 の製作
調理タイマーを利用した、家庭で手軽に楽しめるコーヒー豆の自家焙煎。
今回は、自作の「COFFEE焙煎 専用タイマー」を作成しました。

はじめに
「Artisan」試用機の紹介記事は、下記サイトからどうぞ、
今回は、単独動作で動作可能の 焙煎専用「ROAST TIMER」を 電子工作を用いて、作成する方法を紹介いたします。
安定した動作やノイズ対策など優位なように、ブレッドボードの簡易配線でなく ユニバーサル基板を使用し組上げます。
仕様
K熱電対タイプの温度センサーに対応し、関連する温度と時間を表示します。

基本動作
本体の表示部に、STARTからの時刻、温度及び 上昇率温度(RoR:Rate of Rise)を単独で表示
なお、本仕様のRoRは、焙煎温度の1分間当たりの変異温度を表します。

拡張動作
- 「Artisan」試用互換・・・PC、USB接続
 - Bluetoothをサポート:離れた場所でも、対応するAndroid端末やPCなどに時刻・温度を通知・表示 また、受信されたデータにて二次的な処理が可能
 

作成に必要なスキル
モジュールの製作
ユニバーサル基板を使用します。その特有な「はんだ付け」作業や 組上の技量が必要です。
開発環境
マイコン「ESP32」は、ARDUINO-IDE(統合開発環境アプリ上のソフトウェア)を利用します。 それらの設定方法や開発利用方法等
ハードウェア
構成する主なハードウェア構成は、
CPU
ESP32
Wi-Fi・Bluetoothを内蔵し、低コストで低消費電力の電子工作にも便利で安価なマイコン「ESP32」シリーズ。 今回はこのマイコンを使用します。
Arduino開発環境IDEが利用でき、最近では ”Iot” 開発に関する電子工作にも活用され、情報量も豊富です 
ESP32-DevKitC-32E ESP32-WROOM-32E開発ボード 4MB
 技適等の信頼性で秋月電子通商からのメーカー品を使用しました。
 注:その他、安価流通品、サードパーティー製などの使用はご注意ください。
温度モジュール
MAX31855構成、K熱電対アンプモジュール
ディスプレイ
SSD1306
128×64 有機ELディスプレイ(OLED)青 グラフィックディスプレイモジュール
IC
7414 シュミットトリガインバータ
スイッチノイズ(チャタリング)対策用
その他
ノイズ対策コンデンサー、抵抗、タクトスイッチ等
回路図

部材仕入れ
一般的な部材や備品は、センサーを除く部品の購入先は、電子部品でお馴染みの「秋月電子通商」で入手できます。

ソフトウェア
Arduino IDE
ソフトウェアの開発環境を設定、制御プログラムを作成し マイコンにそのプログラムを書込みます。
設定
- Arduino IDE ダウンロード
 - ESP32環境設定、ドライバ
 - ポート等の各種設定
 
モジュールライブラリ
- 温度モジュール
MAX31855 : Adafruit MAX31855 library - OLED(SSD1306)
https://github.com/ThingPulse/esp8266-oled-ssd1306 
プログラム(スケッチ)
#include <stdio.h>
#include <string.h>
#include <Wire.h>
#include <SPI.h>
#include "Adafruit_MAX31855.h"
#include "BluetoothSerial.h"
#include "SSD1306Wire.h"
const int startpin = 2, stoppin = 4;
unsigned long delay_cntr = 0;
unsigned int  sw_id = 0;
unsigned int sec_cntr = 0;
unsigned int min_cntr = 0;
unsigned int t_sec = 0;
unsigned int t_min = 0;
char MM_SS[] = "00:00";
char MM_work[] = "00";
char SS_work[] = "00";
double nt = 0;
double bnt = 0;
double ro = 0;
double ror = 0;
// MAX31855;
#define MAXDO   19
#define MAXCS   5
#define MAXCLK  18
Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);
//Bluetooth;
BluetoothSerial SerialBT;
// SSD1306;
SSD1306Wire display1(0x3c, SDA, SCL);
SSD1306Wire display2(0x3c, SDA, SCL);
void setup() {
  pinMode(startpin, INPUT);
  pinMode(stoppin, INPUT);
// SSD1306 Initial process;
  //  初期化
  display1.init();
  display2.init();
  //  反転
  display1.flipScreenVertically();
  display2.flipScreenVertically();
  //  フォント
  display1.setFont(ArialMT_Plain_16);
  display2.setFont(ArialMT_Plain_24);
  //  エリア+初期文字
  display1.drawString(10,2,"ROAST TIMER");
  display2.drawString(35,32,"00:00");
  // 初期表示
  display1.display();
  display1.setFont(ArialMT_Plain_24);
  display2.display();
  //  バッファクリア
  display1.clear();
  display2.clear();
// Serial Initial process;
  Serial.begin(9600);
  while (!Serial) delay(1); // wait for Serial on Leonardo/Zero, etc
  Serial.println("ROAST TIMER");
  delay(500); // wait for MAX chip to stabilize
  Serial.print("Initializing sensor...");
  if (!thermocouple.begin()) {
    Serial.println("ERROR.");
    while (1) delay(10);
  }
  Serial.println("DONE.");
  SerialBT.begin("ROAST TIMER");
}
void loop()
{
  if(delay_cntr == 1000) {
//== about 1 second(1000ms) interval
// TEMP Process
  // basic readout test, just print the current temp
  //   Serial.print("Internal Temp = ");
  //   Serial.println(thermocouple.readInternal());
   double c = thermocouple.readCelsius();
   double nt = thermocouple.readCelsius();
//   bnt = nt;
   if (isnan(c)) {
     int ktmf = 1;
     Serial.println("Thermocouple fault(s) detected!");
     uint8_t e = thermocouple.readError();
     if (e & MAX31855_FAULT_OPEN) Serial.println("FAULT: Thermocouple is open - no connections.");
     if (e & MAX31855_FAULT_SHORT_GND) Serial.println("FAULT: Thermocouple is short-circuited to GND.");
     if (e & MAX31855_FAULT_SHORT_VCC) Serial.println("FAULT: Thermocouple is short-circuited to VCC.");
   } else {
//  Routine Step.
  //  LCD "TEMP"
      display1.clear();
      display2.clear();
      display1.drawString(5,2,String(c,1)); 
      display1.display();
      ro = nt - bnt;
      ror = ro * 60;
      if (ror >= 0) {               // RoR値:正
        display1.drawString(80,2,"+");
        display1.drawString(92,2,String(ror,0)); 
        display1.display();
        }
     else {                         // RoR値:負
//      display1.drawString(80,2,"-");
      display1.drawString(80,2,String(ror,0)); 
      display1.display();
     }
      bnt = nt;
  // SERIAL "TEMP"
      Serial.println(c);
  // B/T "TIME+TEMP"
     SerialBT.print(MM_SS);
     SerialBT.print(" ");     
     SerialBT.print("Temp = ");
     SerialBT.print(c);
     SerialBT.println(" °C");
   }
// STOPWATCH Process
    delay_cntr = 0;
//  Starting Process.
    if (sw_id == 1) { 
      t_sec = t_sec + 1;
      sec_cntr = sec_cntr + 1;
   
//  MIN Info.
      if (min_cntr == 60) {
        min_cntr = 0;
        t_min = 0;
      }
//      
          
//  SEC Info.
      if (sec_cntr == 60) {
        sec_cntr = 0;
        t_sec = 0;
        min_cntr = min_cntr + 1;
        t_min = t_min + 1;
        snprintf(MM_work,4,"%02d",t_min);
        MM_SS[0] = MM_work[0];
        MM_SS[1] = MM_work[1];
      }
//
      snprintf(SS_work,4,"%02d",t_sec);
      MM_SS[3] = SS_work[0];
      MM_SS[4] = SS_work[1];
      display2.clear();
      display2.drawString(35,32,String(MM_SS)); 
      display2.display();    
      }
  }
//  SWITCH JUDGMENT
  if (digitalRead(stoppin) == HIGH) {
    //Stop
    sw_id = 0;
    min_cntr = 0;
    sec_cntr = 0;
    ESP.restart();
  }
  if (digitalRead(startpin) == HIGH && sw_id == 0) {  
    // Start
    sw_id = 1;
  }
//  TIME (time/conter setting) 
  delay(10);
  delay_cntr = delay_cntr + 10;
}動作
スタンドアローン
単独動作(要USB電源入力)にて、START後、1秒周期に温度、時間及びRoRを装置内の有機ELディスプレイ(OLED)に表示します。
エクステンション
拡張機能として、RoR未通知にて下記をサポートします。
「Artisan」試用対応
PC(USB接続)による「Artisan」試用での運用が可能です。
Bluetoothサポート
対応するAndroid端末やPCなどに時刻・温度を通知・表示 また、受信されたデータにて二次的な処理にも対応可能です。
デフォルトとして、Bluetooth名:”ROAST TIMER”と定義していますが、
変更な場合はプログラム中(84行目)の
SerialBT.begin(“ROAST TIMER“); にて名称の変更が可能です。
また、通信データのフォーマットは、1秒周期に 00:00Temp = 00.00℃
00:00➡時間 Temp = 00.0℃➡温度 にて通知します。
アンドロイド端末
Serial Bluetooth Terminal:B/T接続上のシリアル通信情報の取得
CSV Viewer : 通信情報のCSV変換・編集
EXCEL:データ編集、表・グラフ表示

まとめ
- COFFEE 自家焙煎専用タイマーの作成方法を紹介いたしました。
 - タイマーの他に、接続されたK熱温度センサーの温度及びRoRの表示
 - 単独動作(スタンドアロン)と拡張動作(エクステンション)では、
Bluetooth、Artisan試用対応の両サポートで構成 

注意
- 無線システムを使用ので、マイコン製品の技適対応性にご注意ください。
 - Arduino IDE利用に伴う、運用方法にご注意ください。
 
