Я очень люблю проводить время в ванной, даже очень люблю.
Ничего нет лучше взять пивка, жареных пельмешек, айпадик и быдлокодить лежа в горячей водичке.
Но эту идилию нарушает ужасное существо, и зовут его «Газовая колонка».
Суть проблемы:
Дом у нас старый, трубопроводы соответственно тоже старые, и давление в водянном стояке просто отвратительное.
Если вы включите воду из крана и настроите колонку крутилками на 40 градусов, то она вам будет выдавать 40 градусов… но недолго. Стоит вам включить душ как температура резко взлетит до 50, а то и выше. Также взлет зависит от дня недели(в выходные график температуры воды при неизменной настройке колонки выглядит как визуализация какого-либо дабстепа).
Причина проста, при включении душа т.к. диаметр душевого шланга меньше чем диаметр трубы то через теплообменник в колонке проходит меньшее количество воды при одинаковом пламени. Соответственно вода греется сильнее. Такойже эффект наблюдается в выходные когда все принимают водные процедуры и давление в общей системе падает еще сильнее, также данный эффект может наблюдатся от чего угодно в плоть до фазы луны и положения Сатурна.
План мести я вынашивал очень давно, но поскольку я очень далек от схемотехники — то никак не решался.
Но вот час расплаты наступил и я решился.
Поехали©
Итак мне потребовалось:
— Ардуино Уно
— простенький сервопривод
— проводочки, резисторы и прочая мелочевка
— кот который постоянно утаскивает эту самую мелочевку
Колонка у меня Oasis 20RG
Что меня толкнуло на создание девайса, так это то что колонка показывает текущую температуру воды, а значит есть датчик окторый можно прочитать.
Как видно из фотки — левая ручка-крутилка отвечает за высоту пламени, ей то и рулится темпертура, её то и будем крутить.
Все добро заказал на сайте амперка.ру, да, с ебея былобы в разы дешевле и стоило бы копейки. Но жажда мести не могла ждать.
Итак сняв лицевую панель был обнаружен датчик температуры на выходе горячей воды
который представляет себе обычный термистор.
Включением его в делитель напряжения и воткнув данные в аналоговый вход я получил аналоговое значение, которое путем нехитрых манипуляций и функции map было переведено в температуру.
На самом деле тут я долго мучался потомучто напроч забыл видеоурок Джереми Блума о делителях напряжения, но посмотрев еще раз быстро все схватил, дело оставалось за малым
Температуру я получал, осталось разместить серву и придумать механику которая будет крутить ручку шпильки.
Серву разместил четко под шпилькой
думал как ее закрепить, сначала просверлил дырочки под крепление, но металл колонки оказался прочнее метала болтов на которых моментально сьелась реззьба.
Был взят незамениемый материал — нейлоновые стяжки. Зафикисровалось намертво.
дальше меня заклинило, не знаю что на меня нашло но я никак не мог придумать как механически соеденить серву со шпильеой, в голове крутилась идея про коромысло, но никак не материализовалась. Слава богу в Q&A подсказали, в итоге из текстолита было вырезано коромысло такойже длины как на серве, и наклеено на шпильку.
Тяги были сделаны из гибкой проволоки(потом заменены).
Далее я сделал так чтобы при включении колонки — включался весь процесс, незачем пытатся повысить температуру когда колонка выключена. Для этого монитрю провод питания экранчика(который работает только при включеной колонке) на предмет напряжения. И если оно есть — запускаю процесс.
Также я написал т.н. «разогрев» — контроллер ждет 10 секунд после вклюения колонки а только потом начинает работать. Сделано для того чтобы теплообменник успел нагрется.
В итоге родилась альфа-версия контроллера (извиняюсь за плохое видео, дальше — лучше):
После пары тестов были замечены следующие баги:
Ну во первых очевидный баг с тягами, они мягкие и не натянутые, соответсвенно существует люфт который мешает быстрому выставлению температуры.
В закромах был найден кусок медной проволоки и нехитрыми манипуляциями сделаны тру-тяги.
Замеряем:
Получилось:
Следующий баг был в том что датчик температуры внезпано показывал на 20 градусов меньше, но через несоклько секунд возвращался в нормальное состояние. Долго я это ловил и в итоге понял в чем дело.
Датчик я запитал от 3.3в выходна на ардуино, незнаю почему но эти самые 3.3 скакали, тем самым меняя показания датчика. Запитав датчик от 5В все стало нормально.
В итоге получился бета тест:
К сожалению незнаю как соденеить два видео в одно поэтому:
Логи ардуинки:
Серва с новыми тягами:
Ну вот в принципе и все, далее привожу листинг программы, после написания статьи программа была еще немного дотюнена дабы настроить ее на максимально бстрое выравнивание температуры.
Листинг:
#include <Servo.h>
int termalPin=A5;
int enablePin=8;
int ledPin=7;
int temp;
int lastTemp=0;
boolean enabled=false;
static int minAngle=5;
static int maxAngle=100;
static int needTemp=40;
Servo myservo;
void setup()
{
Serial.begin(9600);
pinMode(enablePin,INPUT);
pinMode(ledPin,OUTPUT);
delay(1000);
}
void loop()
{
temp = map(analogRead(termalPin),800,635,31,51);
if(digitalRead(enablePin)==HIGH)
{
if(!enabled)
{
myservo.attach(9);
myservo.write(50);
Serial.println("WARMING UP BOILER.");
delay(10000);
Serial.println("BOILER READY!");
}
enabled=true;
digitalWrite(ledPin,HIGH);
Serial.print("BOILER ONLINE. CURRENT TEMP: ");
Serial.print(temp);
Serial.println(" C");
if(temp>needTemp) decTemp();
if(temp<needTemp) incTemp();
delay(300);
}
else
{
if(enabled)
{
Serial.println("BOILER OFFLINE. GOOD LUCK!");
myservo.write(50);
myservo.detach();
enabled=false;
}
digitalWrite(ledPin,LOW);
}
}
void incTemp()
{
int p=needTemp-temp;
Serial.print("Increasing TEMP. P=");
Serial.println(p);
int pos=myservo.read();
int newpos=pos-p;
for(int i=pos;i>=newpos;i--)
{
if(i>minAngle) myservo.write(i);
if(i<minAngle) myservo.write(minAngle);
delay(50);
}
if(p>5)
{
delay(p*1000);
}
else
{
if(p<=3) delay(p*3000);
else
delay(p*2000);
}
}
void decTemp()
{
int p=temp-needTemp;
Serial.print("Decreasing TEMP. P=");
Serial.println(p);
int pos=myservo.read();
int newpos=pos+p;
for(int i=pos;i<=newpos;i++)
{
if(i<maxAngle) myservo.write(i);
if(i>maxAngle) myservo.write(maxAngle);
delay(50);
}
if(p>5)
{
delay(p*1000);
}
else
{
if(p<=3) delay(p*3000);
else
delay(p*2000);
}
}
void smartDelay(int p)
{
switch(p)
{
default:
delay(p*1000);
break;
}
}
ну вот собственно и все, ардуино была помещена в саму колонку рядом с родным блоком управления. Питание внешнее по блоку питания найденому в закромах.
Кстати родной экранчик я тоже вернул на место, и он также работает, гости частенько пугаются видя как ручка на колонке сама крутится)
Это моя первая стсатья на хабре, прошу строго не судить, понять и простить :)
С радостью отвечу на все вопросы.
Автор: SONce