Ранее в статье http://rcl-radio.ru/?p=110938 был показан пример терморегулятора на основе цифрового датчика DS18B20, на этой странице показан аналогичный пример создания терморегулятора, но на базе преобразователя (АЦП) MAX6675 (http://rcl-radio.ru/?p=45839).
При помощи MAX6675 (модуль) можно измерить ТЭДС термопары типа К (ХА), результат измерения выводится в градусах Цельсия и Фаренгейта, так же микросхема MAX6675 содержит встроенный датчик температуры окружающей среды.
MAX6675 в комплекте с термопарой типа К рассчитан на измерение температуры в диапазоне от 0 до 1024 ºС, с разрешением 0.25 ºС (точность 12 бит). Для передачи данных используется SPI интерфейс.
Используя преобразователь температуры MAX6675, можно собрать простой регулятор температуры. MAX6675 имеет диапазон измерения температуры от 0 до + 999 °C (программно ограничено до 999 °C), показания датчика температуры выводятся на дисплей LCD1602 + I2C (I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.) Органы управления состоят из энкодера KY-040 и двух кнопок.
Терморегулятор может содержать до 10 программ, в каждой программе можно задать температуру регулирования и время (в минутах) поддержания заданной температуры. Так же можно установить гистерезис. Все данные программ и значение гистерезиса сохраняются в энергонезависимой памяти.
Терморегулятор содержит основное меню, меню активации программ и настройки гистерезиса, а так же меню установки параметров (температуры и времени) программ.
Основное меню
На основном меню выводятся:
- данные от текущей температуре (от 0 до 999 °С)
- номер программы
- индикатор работы нагревательного элемента
- температура регулирования заданная в данной программе (0…999 °С)
- оставшееся время работы в заданной программе программы (в минутах от 0 до 255)
При нажатии на кнопку энкодера (в основном меню) происходит переход в меню активации программ и установки гистерезиса.
В меню активации программ, при установки параметра «ON» происходит запуск таймера, который отсчитывает время от установленного в программе.
Запуск таймера
Остановка таймера
Настройка гистерезиса от 0.0 до 5.0 °С
При запуске таймера происходит отсчет времени исполнения программы P_0 и поддержание заданной в этой программе температуры регулирования, как только время программы P_0 закончится, активируется программа P_1 со своим значение времени и температуры регулирования.
Терморегулятор будет поддерживать температуру по времени заданной в каждой программе до завершения времени работы программы P_9, после чего выход D13 (выход управления нагревательным элементом) становится не активным, происходит переход на программу P_0, которая будет неактивна (отсчет таймера приостанавливается).
Меню установки температуры и времени
На настройки температуры и времени исполнения программ используются кнопки «PROG» и «TEMP / TIMES». При нажатии на кнопку «PROG» происходит переход в меню настройки программ, кнопка энкодера позволяет пролистывать программы P_0…P_9. Кнопка «TEMP / TIMES» позволяет переключать настройки времени и температуры. Параметр меняется при помощи ручки энкодера, температуру можно установить от 0 до 999 °С, время от 0 до 255 минут.
Если время исполнения программы установить на 0 минут (OFF), то эта программа будет неактивна. Например если Вам нужно только 2 программы, то нужно установить в программах P_0 и P_1 время и температуру, а в остальных программа P_2…P_9 время установить на 0 минут (OFF).
Для выхода из режима программирования нужно нажать кнопку «PROG» или подождать 10 секунд для выхода в основное меню.
#include <EEPROM.h> #include <max6675.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/max6675.zip #include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 #include <Wire.h> #include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip #include <EEPROM.h> #include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip LiquidCrystal_I2C lcd(0x27,16,2); Encoder myEnc(8, 9);// DT, CLK MAX6675 thermocouple(4, 3, 2);// CLK, CS, DO byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}; byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C}; byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C}; byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07}; byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}; byte d1,d2,d3,d4,d5,d6,e1,e2,e3; int a[6],x,i_reg,temp_time; int reg_t[10],reg_time[10],reg_t0,reg_time0; bool prog,w; unsigned long times,times1,times_baza,times_cur,oldPosition = -999,newPosition; int i,tic,tac,power,menu,gis=1,nagrev; int t_c,t_sum,t_iz; void setup(){ Wire.begin();lcd.init();lcd.backlight(); MsTimer2::set(1, to_Timer);MsTimer2::start(); if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4); lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8); Serial.begin(9600); pinMode(10,INPUT); // button SW ENCODER pinMode(5,INPUT_PULLUP); // button PROG pinMode(6,INPUT_PULLUP); // button PROG_TEMP_TIME pinMode(13,OUTPUT); // OUTPUT REG TEMP for(int i=0;i<10;i++){reg_t[i] = EEPROM.read(i)*10+EEPROM.read(i+10);} for(int i=20;i<30;i++){reg_time[i-20] = EEPROM.read(i);}if(reg_time[0]==0){reg_time[0]=1;} gis = EEPROM.read(30); digitalWrite(13,LOW); } void loop(){ ////// BUTTON ///////////////////////////////////////////////////////// if(digitalRead(5)==LOW&&prog==0){prog=1;menu=0;temp_time=0;times1=millis();w=1;lcd.clear();delay(300);} if(digitalRead(5)==LOW&&prog==1){prog=0;i_reg=0;temp_time=0;times1=millis();w=1;lcd.clear();delay(300);} if(digitalRead(6)==LOW&&prog==1){temp_time++;if(temp_time>1){temp_time=0;}times1=millis();w=1;delay(300);lcd.clear();} if(digitalRead(10)==LOW&&prog==1){i_reg++;temp_time=0;if(i_reg>9){i_reg=0;}times1=millis();w=1;lcd.clear();delay(300);} if(digitalRead(10)==LOW&&prog==0){menu++;times1=millis();w=1;lcd.clear();delay(300);if(menu>2){menu=0;}} ///////// REG_TEMP /////////////////////////////// if(prog==1&&temp_time==0){ switch(i_reg){ case 0: reg_t0 = reg_t[0];break; case 1: reg_t0 = reg_t[1];break; case 2: reg_t0 = reg_t[2];break; case 3: reg_t0 = reg_t[3];break; case 4: reg_t0 = reg_t[4];break; case 5: reg_t0 = reg_t[5];break; case 6: reg_t0 = reg_t[6];break; case 7: reg_t0 = reg_t[7];break; case 8: reg_t0 = reg_t[8];break; case 9: reg_t0 = reg_t[9];break;} if(newPosition != oldPosition){oldPosition = newPosition;reg_t0=reg_t0+newPosition;myEnc.write(0);newPosition=0;times1=millis();;w=1;temp_func();} switch(i_reg){ case 0: reg_t[0] = reg_t0;break; case 1: reg_t[1] = reg_t0;break; case 2: reg_t[2] = reg_t0;break; case 3: reg_t[3] = reg_t0;break; case 4: reg_t[4] = reg_t0;break; case 5: reg_t[5] = reg_t0;break; case 6: reg_t[6] = reg_t0;break; case 7: reg_t[7] = reg_t0;break; case 8: reg_t[8] = reg_t0;break; case 9: reg_t[9] = reg_t0;break;} } /////// REG_TIME ////////////////////////////////////////////// if(prog==1&&temp_time==1){ switch(i_reg){ case 0: reg_time0 = reg_time[0];break; case 1: reg_time0 = reg_time[1];break; case 2: reg_time0 = reg_time[2];break; case 3: reg_time0 = reg_time[3];break; case 4: reg_time0 = reg_time[4];break; case 5: reg_time0 = reg_time[5];break; case 6: reg_time0 = reg_time[6];break; case 7: reg_time0 = reg_time[7];break; case 8: reg_time0 = reg_time[8];break; case 9: reg_time0 = reg_time[9];break;} if(newPosition != oldPosition){oldPosition = newPosition;reg_time0=reg_time0+newPosition;myEnc.write(0);newPosition=0;times1=millis();;w=1;time_func();} switch(i_reg){ case 0: reg_time[0] = reg_time0;break; case 1: reg_time[1] = reg_time0;break; case 2: reg_time[2] = reg_time0;break; case 3: reg_time[3] = reg_time0;break; case 4: reg_time[4] = reg_time0;break; case 5: reg_time[5] = reg_time0;break; case 6: reg_time[6] = reg_time0;break; case 7: reg_time[7] = reg_time0;break; case 8: reg_time[8] = reg_time0;break; case 9: reg_time[9] = reg_time0;break;} } if(prog==1&&menu==0){ lcd.setCursor(0,0);if(temp_time==0){lcd.print("*REG_TEMP");}else{lcd.print(" REG_TEMP");}lcd.print(i_reg); lcd.print(" ");lcd.print(reg_t[i_reg]);lcd.print(" ");lcd.setCursor(15,0);;lcd.print("C"); lcd.setCursor(0,1);if(temp_time==1){lcd.print("*REG_TIME");}else{lcd.print(" REG_TIME");}lcd.print(i_reg); if(reg_time[i_reg]>0){lcd.print(" ");lcd.print(reg_time[i_reg]);lcd.print(" ");lcd.setCursor(15,1);lcd.print("M");} else{lcd.print(" ");lcd.print("OFF ");} } ///////// READ TEMP ///////////////////////////////////////////// if(millis()-times>300){times=millis();i++;t_c=thermocouple.readCelsius();t_sum=t_sum+t_c;} if(i>4){i=0;t_iz=t_sum/5;t_sum=0;} if(t_iz>999){t_iz=999;}if(t_iz<0){t_iz=0;} ///////// LCD BIG /////////////////////////////////////////////// if(prog==0&&menu==0){ a[0]=t_iz/100; a[1]=t_iz/10%10; a[2]=t_iz%10; if(t_iz<100){a[0]=10;} if(t_iz<10){a[1]=10;} for(x=0;x<3;x++){ switch(x){ case 0: e1=0;e2=1,e3=2;break; case 1: e1=3,e2=4,e3=5;break; case 2: e1=6,e2=7,e3=8;break; }digit();} lcd.setCursor(9,1);lcd.print(char(223)); lcd.print("C"); if(power==1){lcd.setCursor(13,1);lcd.print((reg_time[tac]-tic)/100);lcd.print((reg_time[tac]-tic)/10);lcd.print((reg_time[tac]-tic)%10);} else{lcd.setCursor(13,1);lcd.print("OFF");} lcd.setCursor(10,0);lcd.print("P");lcd.print(tac); lcd.setCursor(13,0);lcd.print(reg_t[tac]/100);lcd.print(reg_t[tac]/10%10);lcd.print(reg_t[tac]%10);} ////////////////////////////////////////////////////////////////// ////////// MENU ///////////////// if(prog==0&&menu==1){ if(newPosition != oldPosition){oldPosition = newPosition;power=power+newPosition;myEnc.write(0);newPosition=0;times1=millis();w=1;if(power>1){power=0;}if(power<0){power=1;}} lcd.setCursor(3,0);lcd.print("heating"); if(power==1){lcd.print(" ON ");} if(power==0){lcd.print(" OFF");tac=0;tic=0;} } if(prog==0&&menu==2){ if(newPosition != oldPosition){oldPosition = newPosition;gis=gis+newPosition;myEnc.write(0);newPosition=0;times1=millis();w=1;gis_fun();} lcd.setCursor(3,0);lcd.print("hysteresis "); lcd.setCursor(6,1);lcd.print((float)gis/10,1); lcd.print(char(223)); lcd.print("C"); } ///////// EEPROM //////////////////////////////////////////////// if(millis()-times1>10000 && w==1){ for(int i=0;i<10;i++){EEPROM.update(i,reg_t[i]/10);EEPROM.update(i+10,reg_t[i]%10);} for(int i=20;i<30;i++){EEPROM.update(i,reg_time[i-20]);} EEPROM.update(30,gis); menu=0;prog=0;i_reg=0;w=0;temp_time=0;lcd.clear();} //////// AVTO REG TIMER ///////////////////////////////////////////// if(millis()-times_baza>60000 && power==1){tic++;times_baza=millis();} if(reg_time[tac]==0){tac++;} if(tic>reg_time[tac]-1){tic=0;tac++; if(tac>9){tac=0;tic=0;power=0;}} if(power==0){times_baza=millis();digitalWrite(13,LOW);} if(power==1){ if(reg_t[tac]*10 >= t_iz*10 + gis){digitalWrite(13,HIGH);nagrev=1;} if(reg_t[tac]*10 <= t_iz*10 - gis){digitalWrite(13,LOW);nagrev=0;} } if(nagrev==1&&menu==0&&prog==0){lcd.setCursor(12,0);lcd.print("*");} if(nagrev==0&&menu==0&&prog==0){lcd.setCursor(12,0);lcd.print(" ");} Serial.print(reg_t[tac]*10);Serial.print(" ");Serial.print(t_iz*10);Serial.print(" ");Serial.println(gis); }// LOOP END void gis_fun(){if(gis<0){gis=0;}if(gis>50){gis=50;}} void time_func(){if(reg_time0>255){reg_time0=255;}if(reg_time0<0){reg_time0=0;}} void temp_func(){if(reg_t0>999){reg_t0=999;}if(reg_t0<0){reg_t0=0;}} void to_Timer(){newPosition = myEnc.read()/4;} void digit(){ switch(a[x]){ case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break; case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break; case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break; case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break; case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break; case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break; case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break; case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break; case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break; } lcd.setCursor(e1,0);lcd.write((uint8_t)d1); lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);lcd.setCursor(e1,1); lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}
Спасибо за ответы.
Собрал схему , работает на Ура! Могли бы Вы расширить диапазон регулировки от 0 до 1372 градусов.
1024°C максимум
This converter resolves temperatures to 0.25°C, allows
readings as high as +1024°C, and exhibits thermocouple
accuracy of 8LSBs for temperatures ranging from 0°C to
+700°C.
Могли бы вы написать скетч для +1024°C, ну конечно если еще с 2-х канальным выходом на MAX 6675, было бы прекрасно!!! Заранее спасибо!