Умный термостат на Digispark (ATtiny85)
 
    24.04.2018

    Собственно идея подобного устройства возникла спонтанно. Видеокарта в компьютере была обновлена на более мощную и появилась проблема - тихая система охлаждения (низкооборотистые вентиляторы) не обеспечивала достаточной эффективности. Был приобретён эффективный высокооборотистый вентилятор с PWM. Но даже на минимальных оборотах он создавал значительный шум. При отсутствии нагрузки данный вентилятор необходимо отключать полностью. Однако здесь возникает проблема. Если мерять температуру только на выходе из системного блока, то не удастся настроить работу термостата в условиях разной температуры в помещении. То есть весной, при отключенном отоплении скажем в помещении 20 градусов, а на выходе 40, то есть воздух нагревается на 20 градусов. И например летом в жару в помещении 30 градусов, а на выходе системного блока - 45 градусов. Получается, что во втором случае абсолютная температура на выходе выше, но нагрузка по факту меньше, и вентиляторы должны работать слабее. Чтобы точно определить требуемый режим работы вентиляторов, нужно мерять температуру на входе и на выходе, и скорость работы вентиляторов будет определять разница значений. Под руку подвернулся Digispark, на нём и решено было собирать умный термостат.

    Была разработана следующая схема:

Датчики температуры lm19ciz, один ставится на пути воздуха, входящего в системный блок, а второй на выходе. Управление осуществляется двумя вентиляторами. Первый - среднеоборотистый, по умолчанию запитывается через резистор-шунт сопротивлением 30-50 Ом и работает на малых оборотах, создавая минимум шума. При превышении заданной температуры, он включается на полную мощность. При дальнейшем росте температуры включается самый мощный и шумный вентилятор. При желании можно также подключить третий вентилятор к выводу p1. На оптроне PC817 реализован инвертор, управляющий p-канальным полевым транзистором. Скетч заливается такой. Возможно, вам его придётся откалибровать под свои условия:
#include <core_adc.h>

byte mode,countdown;

void setup() {
  pinMode(1, OUTPUT); //LED on Model A   
  digitalWrite(1, LOW);

  pinMode(0, OUTPUT);
  digitalWrite(0, LOW);
  pinMode(3, OUTPUT);
  digitalWrite(3, LOW);

  mode = 0;
  countdown = 5;
}

void loop() {
  switch( mode ){
   case 0:
      digitalWrite(1, HIGH);
      delay(50);
      digitalWrite(1, LOW);
      delay(950);

      digitalWrite(0, LOW);
      digitalWrite(3, LOW);      
      break;
    case 1:
      digitalWrite(1, HIGH);
      delay(100);
      digitalWrite(1, LOW);
      delay(100);
      digitalWrite(1, HIGH);
      delay(100);
      digitalWrite(1, LOW);
      delay(700);
      
      digitalWrite(0, HIGH);
      digitalWrite(3, LOW);      
      break;
    case 2:
      digitalWrite(1, HIGH);
      delay(100);
      digitalWrite(1, LOW);
      delay(100);
      digitalWrite(1, HIGH);
      delay(100);
      digitalWrite(1, LOW);
      delay(100);
      digitalWrite(1, HIGH);
      delay(100);
      digitalWrite(1, LOW);
      delay(500);

      digitalWrite(0, HIGH);
      digitalWrite(3, HIGH);
      break;
    default:
      digitalWrite(1, HIGH);
      delay(500);
      digitalWrite(1, LOW);
      delay(500);
      
      digitalWrite(0, HIGH);
      digitalWrite(3, HIGH);
  }

  int t_in, t_out, diff;
  ADC_SetInputChannel((adc_ic_t) 1);
  ADC_StartConversion();
  while( ADC_ConversionInProgress() );
  t_in = ADC_GetDataRegister();
  
  ADC_SetInputChannel((adc_ic_t) 2);
  ADC_StartConversion();
  while( ADC_ConversionInProgress() );
  t_out = ADC_GetDataRegister();

  diff = (t_in - t_out);
  if( diff > 21 ){
    mode = 2;
  }else if( diff > 15 ) {
    if( (mode == 2) && diff >= 18 ){
      ;
    }else{
      mode = 1;
    }
  }else{
    if( (mode == 1) && diff >= 12 ){
      ;
    }else{
      mode = 0;
    }
  }
  
  if( countdown > 0 ){
    countdown--;
    mode = 4;
  }
}

    Плату по традиции вырезал. Если прошивку планируется калибровать, то придётся продумать вариант освобождения вывода 3 - иначе устройство не распознаётся компьютером, мне приходилось выпаивать резистор на 330 Ом:

Для питания использовал переходник с разъёма питания SATA. Почти все компоненты куплены на AliExpress:
Датчик lm19ciz удлинён мышиным хвостиком, для изоляции обмотан высокотемпературным скотчем:
Плата Digispark припаяна к плате с транзисторами:
По утогу получился компактный контроллер:

    В принципе данное устройство может использоваться в любом месте, где необходимо регулировать температуру. И можно спокойно добавить ещё один канал управления вентилятором. Полевой транзистор выдерживает ток до 6 Ампер, то есть вентилятор может быть очень мощным. Встроенный в Digispark ШИМ я использовать не стал ввиду низкой частоты в 1 кГц, его применение для управления вентиляторами приведёт к неприятному гулу.

Фотогалерея