ブラウザのお気に入りはバックアップしてなくて復旧できませんでした。ArduinoIDEのライブラリもまだ全てはインストールできていません。また、これまでにビデオエディターで編集した動画のプロジェクトファイルが消えました。素材と編集結果の動画は残っていますが、プロジェクトが無くなったので再編集はできません。
このトラブルでアップが遅れてしまった、オーブントースタやホットプレート用の温度コントローラの動画をアップしました。基板のリフロー半田付けなどに使えないかと思っています。
設定温度でリレーのオンオフを行う単純制御です。動画の白熱電球は熱容量が小さいので、それなりに一定の温度になりますが、ホットプレートなどはもう少しオーバシュートが起こるかも知れません。しかし、PID制御はパラメータの調整が大変そうなので保留中です。
以下、回路図とスケッチです。バグがあるかも知れません。無保証です。また、著作権は留保しますが、改造などご自由にどうぞ。
//-------------------------------------------------------------------------
// 2021.1.8 naka
// オーブントースタ・ホットプレートの温度コントローラ
//
// ・設定温度を境にON/OFFする単純制御
// ・温度設定はロータリエンコーダで10℃刻みに上下
// ・設定温度と測定温度はそれぞれ7セグ3桁のLED表示
// ・温度測定は約1秒毎に行い、即時表示
// ・稼働中はいつでも設定温度を変更できる
// ・設定温度はEEPROMに保存され、次回起動時に反映される
// ・温度が高くなるとオーブントースタのサーモスタットが効いて強制的にOFFになることがある
//-------------------------------------------------------------------------
#include <MsTimer2.h>
#include <max6675.h>
#include <EEPROM.h>
// 熱電対関係
int thermoCS = A0;
int thermoDO = A1;
int thermoCLK = A2;
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
static int temp,settemp;
// 7セグLED関係
#define DIGIT_ON HIGH
#define DIGIT_OFF LOW
#define SEG_ON LOW
#define SEG_OFF HIGH
const int digitPin[] = {9,10,11,12,13};
const int segmentPin[] = {2,3,4,5,6,7,8};
const uint8_t segmentPattern[] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00100111, // 7
0b01111111, // 8
0b01101111, // 9
0b00000000 // 10: 消灯(ゼロサプレス用)
};
static uint8_t idigit = 0;
static uint8_t digits_buff[6]; // 6桁
// ロータリエンコーダ
#define RT0 A3
#define RT1 A4
// ON/OFF出力のリレー
#define RLpin A5
#define RL_ON HIGH
#define RL_OFF LOW
// 数字nをm桁目に表示する(n=10は消灯)
void displayDigit(int n,int m) {
static int pm = 0; // 前回点灯digit
digitalWrite(digitPin[pm], DIGIT_OFF); // 直前のdigitを消灯
for (int i=0;i<7;i++) {
digitalWrite(segmentPin[i], segmentPattern[n] & (0x01 << i) ? SEG_ON : SEG_OFF);
}
if (m!=0) { // 1桁目のときは全てのdigitpinをoffなのでOFFのまま
digitalWrite(digitPin[m-1], DIGIT_ON);
pm = m - 1;
}
}
// 7セグLEDのダイナミック表示と温度測定(3ms毎の割り込みで呼ばれる)
void dynamicDisp() {
static int seccount = 0;
displayDigit(digits_buff[idigit],idigit);
idigit++;
if (idigit>=6) idigit = 0;
seccount++;
if (seccount>333) { // 3ms * 333 = 約1秒毎に温度測定
seccount = 0;
temp = (int)(thermocouple.readCelsius()+0.5); // 四捨五入
Serial.println(temp);
upperBCD(temp);
}
}
void toBCD(int a,uint8_t &a1,uint8_t &a2,uint8_t &a3) {
a = abs(a);
if (a>=1000) a = a % 1000;
if (a>=100) a3 = a / 100; // 3桁目
else a3 = 10; // ゼロサプレス
if (a>=10) a2 = (a / 10) % 10; // 2桁目
else a2 = 10; // ゼロサプレス
a1 = (a % 10) % 10; // 1桁目
}
void upperBCD(int a) {
toBCD(a,digits_buff[3],digits_buff[4],digits_buff[5]);
}
void lowerBCD(int a) {
toBCD(a,digits_buff[0],digits_buff[1],digits_buff[2]);
}
// ロータリエンコーダのサンプリング
int sample_coder()
{
static int code = 0;
int code_val,code_pin0,code_pin1;
code_val = (PINC >> 3) & 3; // RT0,RT1=3,4 なので 3bitシフトして 0b00000011 とAND
code = ((code << 2) | code_val) & 15; //
switch (code) { // デテンド位置=3
case 0xE:
return(1);
case 0xD:
return(-1);
default:
return(0);
}
delay(10);
}
void setup() {
Serial.begin(115200);
for (int i=0;i<5;i++)
pinMode(digitPin[i], OUTPUT);
for (int i=0;i<7;i++)
pinMode(segmentPin[i], OUTPUT);
// ロータリエンコーダi/oピン設定
pinMode(RT0,INPUT_PULLUP);
pinMode(RT1,INPUT_PULLUP);
// リレーi/oピン設定
pinMode(RLpin,OUTPUT);
MsTimer2::set(3, dynamicDisp); // 3ms毎にdynamic表示
MsTimer2::start();
digitalWrite(RLpin, RL_OFF);
int readtemp = (int)EEPROM.read(0); // 前回設定温度
settemp = (readtemp / 10) * 10; // もし10℃刻みでない値が入っていた時に10℃単位にする
}
void loop() {
lowerBCD(settemp); // 設定温度表示
while (1) {
int dir = sample_coder();
if (dir>0) {
settemp += 10;
if (settemp>250) settemp = 250;
break;
}
else if(dir<0){
settemp -= 10;
if (settemp<10) settemp = 10;
break;
}
if (temp>=settemp) {
// 設定温度以上なのでリレーoff
digitalWrite(RLpin, RL_OFF);
}
else {
// 設定温度未満なのでリレーon
digitalWrite(RLpin, RL_ON);
}
}
EEPROM.write(0, settemp);
delay(100);
}

0 件のコメント:
コメントを投稿