При использовании отладочной платы STM32 (базе микроконтроллера STM32F103C8T6) совместно с цифровым датчиком температуры можно сделать простой терморегулятор (-50…+125 °С). Информация об текущей температуре и температуре регулирования выводится на 4-х разрядный семисегментный дисплей на базе драйвера TM1637 (модуль). Управление терморегулятором осуществляется при помощи двух кнопок (+ и -), значение температуры регулирования сохраняется в энергонезависимой памяти.
![]() |
![]() |
#include <OneWireSTM.h> // Библиотека Arduino_STM32-master.zip #include <STM32_TM1637.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=403&download=1 #include <EEPROM.h> // Входит в состав набора библиотек Arduino_STM32-master STM32_TM1637 tm(PB0,PB1);// CLK, DIO OneWire ds(7); // A7 // CLK PB0 (TM1637) // DIO PB1 (TM1637) // OUT PA7 (DS18B20) byte i,present = 0,type_s = 0, data[12], addr[8]; float celsius; byte w; int reg; const float gis = 1.0;// гистерезис unsigned long times; void setup(){ Serial.begin(9600); tm.brig(7); // ЯРКОСТЬ 0...7 EEPROM.init(0x801F000,0x801F800,0x400);// 1024 byte pinMode(PB6,INPUT); // рег. темп. + pinMode(PB5,INPUT); // рег. темп. - pinMode(PB7,OUTPUT);// выход управления реле reg = EEPROM.read(10)-50; } void loop(){ if(millis()-times>1000){ ///////// 18b20 ////////////////////// if ( !ds.search(addr)) {ds.reset_search();delay(250);return;} ds.reset();ds.select(addr);ds.write(0x44, 1);delay(500); present = ds.reset();ds.select(addr);ds.write(0xBE); for (i = 0; i < 9; i++) {data[i] = ds.read();} int16_t raw = (data[1] << 8) | data[0];if (type_s) {raw = raw << 3;}celsius = (float)raw / 16.0; //////// end 18b20 //////////////////// } if(digitalRead(PB6)==HIGH){reg++;w=1;times = millis();if(reg>125){reg=125;}delay(200);} if(digitalRead(PB5)==HIGH){reg--;w=1;times = millis();if(reg<-50){reg=-50;}delay(200);} if(millis()-times<3000){tm.print_float(reg,0, 0b01010000,0,0,0);} else{tm.print_float(celsius,1, 0,0,0,0);} if(reg >= celsius + gis){digitalWrite(PB7,HIGH);} if(reg <= celsius - gis){digitalWrite(PB7,LOW);} if(w==1){w=0;EEPROM.update(10, reg+50);} }
Второй пример скетча позволяет использовать вместо кнопок энкодер ky-040. Для регулировки температуры регулирования достаточно повернуть ручку энкодера, при этом на дисплее будет высвечиваться температура регулирования, которая при не активности энкодера смениться через 3 секунды на текущие показания температуры.
#define pinA PB6 #define pinB PB5 #include <OneWireSTM.h> // Библиотека Arduino_STM32-master.zip #include <STM32_TM1637.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=403&download=1 #include <EEPROM.h> // Входит в состав набора библиотек Arduino_STM32-master #include <STM32_Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2020/01/STM32_Encoder.zip STM32_Encoder encoder(pinA, pinB); STM32_TM1637 tm(PB0,PB1);// CLK, DIO OneWire ds(7); // A7 // CLK PB0 (TM1637) // DIO PB1 (TM1637) // OUT PA7 (DS18B20) // CLK PB6 (ЭНКОДЕР) // DT PB5 (ЭНКОДЕР) byte i,present = 0,type_s = 0, data[12], addr[8]; float celsius; int position = -999; byte w; int reg; const float gis = 1.0;// гистерезис unsigned long times; void setup(){ Serial.begin(9600); tm.brig(7); // ЯРКОСТЬ 0...7 EEPROM.init(0x801F000,0x801F800,0x400);// 1024 byte encoder.begin(); attachInterrupt(digitalPinToInterrupt(pinA),Read,CHANGE); attachInterrupt(digitalPinToInterrupt(pinB),Read,CHANGE); pinMode(PB7,OUTPUT);// выход управления реле reg = EEPROM.read(10)-50; } void loop(){ if(millis()-times>1000){ ///////// 18b20 ////////////////////// if ( !ds.search(addr)) {ds.reset_search();delay(250);return;} ds.reset();ds.select(addr);ds.write(0x44, 1);delay(500); present = ds.reset();ds.select(addr);ds.write(0xBE); for (i = 0; i < 9; i++) {data[i] = ds.read();} int16_t raw = (data[1] << 8) | data[0];if (type_s) {raw = raw << 3;}celsius = (float)raw / 16.0; //////// end 18b20 //////////////////// } if(position != encoder.getPosition()){position = encoder.getPosition(); reg = reg + encoder.getPosition();encoder.setPosition(0);position = 0; w=1;times = millis();if(reg>125){reg=125;}if(reg<-50){reg=-50;}} if(millis()-times<3000){tm.print_float(reg,0, 0b01010000,0,0,0);} else{tm.print_float(celsius,1, 0,0,0,0);} if(reg >= celsius + gis){digitalWrite(PB7,HIGH);} if(reg <= celsius - gis){digitalWrite(PB7,LOW);} if(w==1){w=0;EEPROM.update(10, reg+50);} } void Read(){encoder.readAB();}
Перед заливкой скетча в STM32 Вам необходимо ознакомиться со следующей статьей — STM32 Arduino IDE
Привет.При включении есть индикация задания температуры + и -,почему нет отображения реальной температуры ?
Схема первая.
Датчик проверил работает.
Проверьте подключение кнопок. Кнопки имеют внешнюю подтяжку к GND через резисторы 10 К, коммутация нажатия кнопки на +5 В.
Привет. Все заработало после подключения резисторов. Пожелание. Для тех кто в танке укажи в скетче что нужно пины подключить на землю через 10к.
Спасибо.
Привет. После некоторой эксплуатации выяснилось . При данной прошивке температуру можно задать только вверх . Желательно делать установку и для понижения температуры .
У Вас что-то с кнопкой «-«.
Пример. Температура в квартире 27 градусов, я задаю 31 и на выходе pinMode(PB7,OUTPUT);// выход управления реле —появляется напряжение .При достижении пропадает.
У меня 28 градусов , задание ставлю на 22 г. Уровня на выводе управления реле Нет.
Так все верно, так и должно работать. Если установленная температуры меньше температуры окружающей среды, на выходе PB7 не должно быть напряжения.
Приветствую!
Собрал схему на энкодере.
Почему то при задании температуры энкодором прибавление значения происходит против часовой стрелки, убавление температуры по часовой, что неестевенно и неинтуиитивно. Остальное работает нормально.
Почему так?
выводы энкодера CLK и DT поменяйте местами
Спасибо, и еще вопрос.
Отключение происходит при заданной температуре +1 градус.
Для моей системы есть тепловая инерция и температура подниматеся после отключения на 12 градусов от заданной (нагреватель слишком мощный). Как сделать отключение на Тзад+0,1 градус?
if(reg <= celsius — gis){digitalWrite(PB7,LOW);}
заменить на:
if(reg <= celsius — 0.1){digitalWrite(PB7,LOW);}
?