Доброго времени суток, читатели.
Был у меня термостат для тёплого пола — TermoControl ТСL-01.11SF. Только вот работать нормально он через месяц отказался, видимо, засыпал или зависал. Дело было зимой и надо срочно было поставить что-то ему на замену. Так как живу в глубинке, до ближайшего нужного магазина примерно 150 км, дорог нет — решил сделать термостат на том, что есть в столе — ATTiny13 и прочей рассыпухе.
В качестве датчика температуры было решено использовать широко известный датчик DS18B20. Регулятором выступил переменный резистор из старого термостата. Главным требованием было — запихать обратно в тот же корпус, ну и надежная работа.
В результате родилась схема:
UART тут для отладки, в принципе, сейчас не используется, но убирать я его не стал. Для индикации режима работы используется 2 светодиода: красный — нагрев, зелёный — дежурный режим. Нагрузка включается с помощью реле. В качестве источника питания используется готовый блок питания на 12 вольт, тинька запитана через 7805. Плату рисовал в Sprint-Layout:
Делал ЛУТом:
С прошивкой пришлось поколдовать, т.к. много в 13-ю тиньку не запихнуть. Проект писал на C в CVAvr. Функции опроса датчика температуры и программный UART мне помогли написать, т.к. сам я не программист.
#include <tiny13.h>
#include <delay.h>
#include <1wire.h>
#include <stdlib.h>
#define UART_FREQ 124 //9600Hz F_CPU/TIM0_PRESCALER(8)/BAUD
#define DS_FREQ 9600 //1Hz BAUD/FREQ
#define TX_PIN PORTB.0
#define NAGREV_ON PORTB.2=1
#define NAGREV_OFF PORTB.2=0
#define DELTA 5 //разбег по срабатыванию вкл/выкл
#define ADC_INPUT 2
#define ADC_VREF_TYPE 0x20
unsigned int ds_cnt;
signed char temp; //температура в градусах
unsigned char temp_str[6]; //в строке
signed char temp_ust; //установка температуры
unsigned char p_nagrev;
unsigned char adc_data;
unsigned char tx_bit_cnt;
unsigned char tx_data;
bit temp_convert;
bit start_tx,tx;
signed char ds18b20_temperature(void)
{
unsigned char LSB,MSB;
w1_init();
w1_write(0xCC);
w1_write(0xBE);
LSB=w1_read();
MSB=w1_read();
w1_init();
w1_write(0xCC);
w1_write(0x44);
return ((MSB<<4)&0xf0) | ((LSB>>4)&0x0f);
}
void ds_init(void)
{
w1_init();
w1_write(0x4e);
w1_write(0x64);
w1_write(0xD8);
w1_write(0x1f);
w1_write(0x48);
delay_ms(15);
}
void putchar(unsigned char data)
{
while (tx||start_tx){};
delay_ms(1);
tx_data=data;
start_tx=1;
}
void puts(char *str)
{
char k;
while (k=*str++) putchar(k);
}
void putsf(char flash *str)
{
char k;
while (k=*str++) putchar(k);
}
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
{
if (start_tx==1)
{
start_tx=0;
tx=1;
TX_PIN=0;
tx_bit_cnt=0;
goto DS;
}
if (tx==1)
{
if (tx_bit_cnt<8)
{
TX_PIN = ((tx_data>>tx_bit_cnt)&0x01) ? 1 : 0;
tx_bit_cnt++;
}
else
{
TX_PIN=1;
tx=0;
}
}
DS:
ds_cnt++;
if (ds_cnt>=DS_FREQ)
{
temp_convert=1;
ds_cnt = 0;
}
}
}
interrupt [ADC_INT] void adc_isr(void)
{
adc_data=ADCH;
ADCSRA|=0x40;
}
void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTB=0x01;
DDRB=0x0D;
TCCR0A=0x02;
TCCR0B=0x02;
TCNT0=0x00;
OCR0B=0x00;
OCR0A=UART_FREQ;
TIMSK0=0x04;
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;
DIDR0&=0x03;
DIDR0|=0x10;
ADMUX=ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xEF;
ADCSRB&=0xF8;
ds_init();
#asm("sei")
p_nagrev = 0;
while (1)
{
if (temp_convert==1)
{
temp = ds18b20_temperature();
temp_convert=0;
itoa(temp,temp_str);
putsf("Temp= ");
puts(temp_str);
putsf(" xf8Crn");
itoa(temp_ust,temp_str);
putsf("Set = ");
puts(temp_str);
putsf(" xf8Crn");
}
temp_ust = (p_nagrev == 1)?(adc_data/5-DELTA):(adc_data/5); //вычисляем установку температуры (диапазон от 0 до 51 градуса)
if (temp < temp_ust){
NAGREV_ON;
p_nagrev = 0;
}
else{
NAGREV_OFF;
p_nagrev = 1;
};
}
}
Внешний вид:
За внешний вид не ругайте — стоит в бане, потому немного в саже.
Данный девайс работает без перерыва уже год.