記事

Arduinoで肉を美味しく調理する(5)テスト・プログラム

■各モジュールのためにプログラムを作る

 今回は、次に示す調理のための温度コントローラの各モジュールのプログラムを考えます。I2CインターフェースのLCDキャラクタ・ディスプレイ・モジュールへの表示方法は、

  「ArduinoにLCDキャラクタ・ディスプレイ・モジュールを接続する(9)Wire ライブラリ

に説明しているプログラムのモジュールをそのまま利用しているので、そちらを参照してください。

 その他の警告用のLEDの点滅処理、ソリッド・ステート・リレーによる温度制御のプログラムなどを今回説明します。
 熱電対の温度センサは、

  「ArduinoにLCDキャラクタ・ディスプレイ・モジュールを接続する(7)K型熱電対で温度を測定

の記述を参照してください。


LEDの点滅
 警告用のLEDの点滅はディジタル・ポート8番のD8ポートで行います。ポートの変数はARMです。点滅の間隔は何種類か用意できるようにします。また、警告のため点滅の開始、終了の制御は変数の値の設定で行います。点滅の周期を示す値の設定も、所定の変数に書き込むことによって行います。

int ARMSW;   1にすると警告用のLED ON
int ITIME;   点滅の点灯時間、単位ms、消灯時間も同じ 

 ポートを出力に設定します。

pinMode(ARM,OUTPUT);
digitalWrite(ARM,LOW);  出力設定後実際の処理が始まるまでソリッド・ステート・リレーを
            ;   OFFにするためLOWを出力する

 動作状態を確認するために、ITIMEの値をITI.=で、ARMSWをA.=で次に示すように表示しています。

点滅の処理

digitalWrite(ARM,ARMSW*((millis()/ITIME) % 2));

 メインのloop()繰り返しの中で、毎回この点滅処理を行っています。任意の場所でARMSW、ITIMEの値を設定するだけで、LEDの点滅を制御できます。ARMSWを’0’にすると点滅を停止して消灯ARMSWを’1’にするとLEDが点灯し、点滅の周期はITIMEの値で決まります。このITIMEの値も任意の場所で変更できます。ITIMEの値を10くらいに設定すると、見かけ上連続点灯となります。

ソリッド・ステート・リレー(SSR)の制御方針
 ソリッド・ステート・リレー・モジュール(秋月電子通商)はArduinoのディジタル出力で直接駆動できます。モジュール内に、マイコンからのON/OFF信号でリレーをONにするのと併せて、インジケータのLEDを点灯させるトランジスタが入力段に用意されています。
 また、このトランジスタのベースはGNDにプルダウンされています。そのため、電源投入時にArduinoが初期化処理中で出力ポートの設定途中で状態が定まらないハイ・インピーダンスであっても ソリッド・ステート・リレー・モジュール側の入力段でプルダウンされているのでOFF状態です。Arduinoの初期化処理が終わりディジタル・ポートが設定されHighになるまでモジュールはOFF状態で、ONにはならず不用意に通電しないので安全です。
 このモジュールの詳細は、次のWebページに用意されているので参照してください。
  http://akizukidenshi.com/download/ds/akizuki/ae-sh-ssr-kit.pdf
 このモジュールに対しては、ディジタル・ポート5番D5で制御します。

Arduino によるSSRの制御
 ディジタル・ポートD5をソリッド・ステート・リレーの制御ポートとしています。ポート番号は、dp5の変数にセットします。変数を5で初期化し、このディジタル・ポートをsetup()関数の中で出力ポートに設定し、LOWを出力しておきます。
 その後、リレーの制御部でセンサの出力と設定値の比較の結果に基づき定められたHIGH、LOWの出力を行います。
 変数dp5の定義です。

int dp5=5;ディジタル・ポート

 setup()関数内での出力の設定です。

pinMode(dp5,OUTPUT);
digitalWrite(dp5,LOW);

制御部

設定値 tmp アナログ入力ポート A0に接続された半固定抵抗から得た値を処理し設定する
測定温度 t 熱電対温度計などで得た温度 


 設定温度(tmp)より測定温度(t)が低ければHIGHを出力、条件を満たさない場合はLOWを出力します。

if ( tmp > t ) {
digitalWrite(dp5, HIGH);
}
else {
digitalWrite(dp5,LOW);
}

LEDの点灯制御と合わせて点滅の速度を設定する方法
 測定値t設定値tmpを超えたらLEDの点灯をOFFにし、測定値t設定値tmpを超えていなかったらLEDの点灯をONにします。その中で、測定値tが設定値tmp2℃以内に近づいたら点滅の点灯にする方法をプログラムします。

if ( tmp > t ) {
  ARMSW=0;
}
else {
ARMSW=1;
  if ((tmp-2)>t){
ITIME=10;
}
else {
ITIME=300;
}
digitalWrite(dp5,LOW);
}

 点滅の速度はITIMEの値で調整します。10に設定すると点滅の周期が短く連続点灯に見えます。
 リレーの制御部と併わせると次のようになります。

if ( tmp > t ) {
  ARMSW=0;
digitalWrite(dp5, HIGH);
}
else {
ARMSW=1;
digitalWrite(dp5,LOW);
   if ((tmp-2)>t){
ITIME=10;
}
else {
ITIME=300;
}
digitalWrite(dp5,LOW);
}

 コンセントに加熱用のヒータの電源プラグを挿し込み、設定温度70度に設定して、ゆで豚もしくはロースト・ビーフを作るための設定にしてあります。

 実際に調理する場合、センサの設置場所、湯煎のためのお湯の温度を均一にするための方法などいろいろ課題があります。それらについては実際に利用する器具に応じてそれぞれ工夫が必要になります。それらについてもおいおい確認していきます。
 このテストに利用したプログラムを次に示します。

#include <SPI.h>
#include <Wire.h>
unsigned char lcd_address = 0x50; int data1 = 1;
int ARM = 8;
int aind, rdata;
float aindv;
float t;
float tmp;
int SS1 = 10;
int dp5 = 5; ディジタル・ポート
int n = 0;
int ARMSW, ITIME;
int i2cwritecmd(byte cmd) {
Wire.beginTransmission(lcd_address);
Wire.write(0x00); Wire.write(cmd);
return Wire.endTransmission();
}
int i2cwritedata(byte data) {
Wire.beginTransmission(lcd_address);
Wire.write(0x80); Wire.write(data);
return Wire.endTransmission();
}
void lcdcu_set(int x, int y) {
byte ca = (x + y * 0x40) | (0x80);
i2cwritecmd(ca);
}
void lcdclear() {
i2cwritecmd(0x01); delay(1);
}
void lcdhome() {
i2cwritecmd(0x02); delay(1);
}
void dsift_l() {
i2cwritecmd(0x1C);
}
void dsift_r() {
i2cwritecmd(0x18);
}
void init_lcd() {
delay(145);
i2cwritecmd(0x38); delay(1);
i2cwritecmd(0x38); delay(1);
i2cwritecmd(0x0E); delay(1);
i2cwritecmd(0x06); delay(1);
i2cwritecmd(0x01); delay(2);
}
void i2cprint( String pdata) {
int n = pdata.length();
for (int i = 0; i < n; i = i + 1) {
i2cwritedata(pdata.charAt(i));
}
}
void setup() {
pinMode(SS1, OUTPUT);
digitalWrite(SS1, HIGH);
pinMode(ARM, OUTPUT);
digitalWrite(ARM, LOW);
SPI.begin();
Serial.begin(9600);
Wire.begin();
init_lcd();
pinMode(dp5, OUTPUT);
digitalWrite(dp5, LOW);
ARMSW = 1;
ITIME = 20;
}
void loop() {
digitalWrite(ARM, ARMSW * ((millis() / ITIME) % 2));
if ((millis() % 200) == 0) {
digitalWrite(SS1, LOW);
rdata = SPI.transfer(0xFF) << 8;
rdata = rdata + SPI.transfer(0xFF);
t = (rdata >> 3) * 0.25;
digitalWrite(SS1, HIGH);
aind = analogRead(A0);
aindv = aind * 5000.0 / 1024;
tmp = 2 * aindv / 100;
if ( tmp > t ) {
ARMSW = 1;
digitalWrite(dp5, HIGH);
if ((tmp - 2) > t) {
ITIME = 10;
}
else {
ITIME = 300;
}
}
else {
ARMSW = 0;
digitalWrite(dp5, LOW);
}
lcdclear();
i2cprint(String("T="));
i2cprint(String(t));
lcdcu_set(8, 0);
i2cprint("ITI.=");
i2cprint(String(ITIME));
lcdcu_set(0, 1);
i2cprint("tmp=");
i2cprint(String(tmp));
i2cprint(" A.=");
i2cprint(String(ARMSW));
}
}

(2017/5/12 V1.0)

<神崎康宏>

Arduinoで肉を美味しく調理する

(1) 温度センサは熱電対

(2) データ・ロガーMCR-4TC

(3) 熱電対センサ・モジュール

(4) ArduinoのSPI通信のピン配置がボードによって異なる

(5) テスト・プログラム