Controlador de aquecimento multizona
Componentes e suprimentos
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 |
Sobre este projeto
Construí este dispositivo porque minha cozinha era muito quente ou muito fria, com um único termostato na minha vida. Os controladores de aquecimento multi-zonas comerciais (como o EvoHome) são muito caros. Este programa captura a inteligência desses sistemas caros, hospedados em uma placa Arduino Uno simples. Isso resolveu totalmente o meu problema.
Destaques / recursos:
- Você só precisa configurar a fixação e o número de zonas
- Um simples Arduino Uno pode controlar até 5 zonas de unidade de piso
- Com um Arduino Mega, o número de zonas é quase ilimitado
Os controles de programa fornecidos:
- A bomba da unidade de chão
- Agrega todas as suas zonas como apenas um termostato para o aquecedor central
- Válvulas usadas para abrir / fechar zonas
- Um cronômetro de cão de guarda para garantir uma operação sólida
Permite aquecimento individual por zona:
- Um termostato por zona para detectar a solicitação de aquecimento
- Por zona, um relé para controlar uma ou mais válvulas para abrir / fechar os grupos de unidades de piso dessa zona
- Uma sala com vários grupos de unidades de piso pode ser considerada como uma zona de aquecimento (conecte as válvulas paralelamente ao relé de zona)
- Isso não é apenas mais conveniente, mas também economiza energia, pois os quartos não esquentam mais
Controla a bomba da unidade de chão:
- Basicamente, só funciona a bomba quando necessário para aquecimento. Isso já economiza 100-200 euros de eletricidade por ano (em comparação com operar a mesma bomba 24 horas por dia, 7 dias por semana (80 watts é 2 kW por hora por dia =0,50 euros por dia)
- Ativa a bomba da unidade de chão pelo menos uma vez a cada 36 horas, por 8 minutos se não houver qualquer solicitação de aquecimento (verão)
- Impede o funcionamento da bomba sem abrir as válvulas primeiro; Levando em consideração que essas válvulas precisam de 3-5 minutos
Opcionalmente, você também pode controlar o restante da sua casa (quartos sem aquecimento de piso):
- Aqui você normalmente terá botões de termostato em seus radiadores; então apenas os quartos que são frios irão aquecer
- Basta adicionar um termostato na (s) sala (s) que deseja controlar. Conecte esses termostatos em paralelo à entrada No_Zone
Notas finais:
Nem todas as zonas precisam ser controladas; apenas as zonas que se tornam quentes ou permanecem muito frias (caso contrário, use os botões ajustáveis manuais na unidade de piso)
Decidi explicitamente não conectar o dispositivo à internet:
- Aumentaria o risco de mau funcionamento (deve ser sólido como uma rocha)
- Você pode usar termostatos inteligentes para controlar sua casa. Este controlador não oferece nada extra para se adaptar remotamente
Código
- ProjectCV.ino
- Dispositivos.h
ProjectCV.ino C / C ++
/ * * Controlador de aquecimento da unidade de piso para vários quartos / zonas v1.0 * * Copyright:a GNU General Public License versão 3 (GPL-3.0) de Eric Kreuwels, 2017 * Créditos:Peter Kreuwels por definir todos os casos de uso que precisava ser considerado * * Embora essa configuração já funcione por mais de um ano para meu andar térreo, não sou responsável por nenhum erro no código * Ele pode ser usado como uma boa base para suas próprias necessidades, e deve ser testado antes de usar * * Destaques / recursos:* - Você só precisa configurar a fixação e o número de zonas * - Um Arduino Uno simples pode controlar até 5 zonas de unidade de piso * - Com um Arduino Mega, o número de zonas é quase ilimitado * - Os controles de programa fornecidos:* - a bomba da unidade de piso * - Agrega todas as suas zonas como apenas um termostato para o aquecedor CV * - Válvulas para abrir / fechar zonas * - Permite aquecimento individual por zona; * - Por zona, um termostato para detectar a solicitação de aquecimento * - Por zona um relé para controlar uma ou mais válvulas para abrir / fechar os grupos de unidades de piso daquela zona * - Uma sala com vários grupos de unidades de piso pode ser considerada como um aquecimento Zona (conecte as válvulas paralelamente ao relé de zona) * - Isso não só é mais conveniente, mas economiza energia, bem como os quartos não ficam mais muito quentes * - Controla a bomba da unidade de piso * - Basicamente, só aciona a bomba quando necessário para aquecimento. Isso já economiza 100-200 euros de eletricidade por ano, * em comparação com a operação da mesma bomba 24 horas por dia, 7 dias por semana (80 Watt equivale a 2 kW por dia =0,50 euros por dia) * - Ativa a bomba da unidade de piso pelo menos uma vez a cada 36 horas, por 8 minutos se não houver solicitação de aquecimento (Verão) * - Impede o Funcionamento da bomba sem abrir primeiro as válvulas; Levando em consideração que essas válvulas precisam de 3-5 minutos * - Opcionalmente, você também pode controlar o restante da sua casa (quartos sem aquecimento de piso) * - Aqui você normalmente terá botões do termostato em seus radiadores; portanto, apenas os cômodos frios aquecem * - Basta adicionar um termostato no (s) cômodo (s) que deseja controlar. Conecte esses termostatos em paralelo à entrada No_Zone * - Notas finais:* - Nem todas as zonas precisam ser controladas; apenas as zonas que se aquecem ou permanecem muito frias com * botões ajustados manualmente na unidade de piso * / # include// para Watchdog // AVISO:FAST_MODE é para fins de teste / avaliação / depuração ( o loop funciona 50 vezes mais rápido) // Tenha cuidado ao usar FAST_MODE com uma bomba de unidade de piso real, pois pode ser danificada com válvulas fechadas // As válvulas precisam de no mínimo 3 minutos para abrir. Em FAST_MODE o programa não espera o suficiente antes de iniciar a bomba // #define FAST_MODE // execução 50 vezes mais rápida; considere desconectar seu CV / Bomba real! // Em operação normal, o loop é executado 10 vezes por segundo; então 10 contagens / segundo (600 representa cerca de 1 minuto) #define VALVE_TIME 3000L // 5 minutos para abrir / fechar uma válvula (no local seguro; leva normalmente 3 a 5 minutos) #ifdef FAST_MODE # define PUMP_MAINTENANCE_TIME 108000L // Para avaliação , ativa a operação de manutenção da bomba da unidade de chão uma vez a cada 4 minutos (carimbo de tempo 3 horas) # else # define PUMP_MAINTENANCE_TIME 1300000L // Ativa a operação de manutenção da bomba da unidade de chão uma vez a cada 36 horas. Necessário para manter a bomba funcionando # endif # define PUMP_ACTIVATION_TIME 5000L // Ativa a bomba por cerca de 8 minutos (10 segundos no modo de teste) #define COOLDOWN_TIME 18000L // Quando o aquecimento for concluído, continue a circulação de água por mais 30 minutos (40 segundos em teste modo) // Isso permite uma maior dissipação do calor no chão (normalmente leva de 15 a 30 minutos) #include "./Devices.h" // válvulas, bombas, classes de termostato (use as constantes definidas acima) struct Zone {String name; Válvula de válvula; Termostato termostato;}; /////////////////////////////////////////////// ///////// BLOCO DE CONFIGURAÇÃO // Configurar / reordenar sua fixação como desejar (esta é minha fiação em um Arduino Uno); // Nota:os pinos 1 e 2 ainda estão livres para adicionar uma zona extra # define HEATER_PIN 4 // saída para um relé que está conectado com a entrada do termostato do seu sistema de aquecimento # define FU_PUMP_PIN 5 // saída para um relé que liga o Bomba da unidade de piso # define LIVING_VALVE 7 // Zona 1:saída para um relé que controla a (s) válvula (s) #define KITCHEN_VALVE 6 // Zona 2:saída para um relé que controla a (s) válvula (s) #define DINING_VALVE 3 // Zona 3:saída para um relé que controla a (s) válvula (s) #define LIVING_THERMO 8 // Zona 1; entrada ligada ao termostato na casa # define KITCHEN_THERMO 9 // Zona 2; entrada ligada ao termostato da cozinha # define DINING_THERMO 11 // Zona 3; entrada conectada ao termostato na sala de jantar # define NO_ZONE_THERMO 10 // Opcionalmente:termostatos em quartos sem piso aquecido # define HEATING_LED 12 // Ligado durante o aquecimento, Alterna durante o resfriamento, está Desligado no modo inativo # define INDICATION_LED 13 // Alterna ligado LED da placa para indicar funcionamento da placa; pode ser facilmente removido para liberar um pino IO extra !! // Configure as zonas / salas da unidade de piso. Cada zona / cômodo possui um nome, válvula e termostato:#define NR_ZONES 3Zone Zones [NR_ZONES] ={{"Living Room", Valve (LIVING_VALVE, "Living Valve"), Termostato (LIVING_THERMO, "Living Thermostat")}, { "Cozinha", Válvula (KITCHEN_VALVE, "Válvula de cozinha"), Termostato (KITCHEN_THERMO, "Termostato de cozinha")}, {"Sala de jantar", Válvula (DINING_VALVE, "Válvula de jantar"), Termostato (DINING_THERMO, "Termostato de cozinha" )}}; // END CONFIGURATION BLOCK ///////////////////////////////////////////// /////////// Alguns dispositivos fixos:LED iLED (INDICATION_LED, "LED indicador"); // pode ser removido se você ficar sem IO'sLED hLED (HEATING_LED, "Heating LED"); Manipulator CV (HEATER_PIN, "CV Heater"); Bomba FUPump (FU_PUMP_PIN, "Floor Unit Pump"); Termostato ZonelessThermo (NO_ZONE_THERMO , "Termostato sem Zonas"); // Para o resto da casa, não relacionado à unidade de piso zonevoid printConfiguration () {Serial.println ("------ Configuração da placa:---------"); iLED.Print (); hLED.Print (); CV.Print (); FUPump.Print (); ZonelessThermo.Print (); para (int i =0; i 0) {cooldownCount--; } return checkCoolDownNeeded (); } bool checkCoolDownNeeded () {return (cooldownCount> 0); } void Print () {switch (_State) {case idle:Serial.print ("idle"); pausa; caso em:Serial.print ("em"); pausa; cooldown do caso:Serial.print ("cooldown"); pausa; }}}; // O estado global machineState CVState; void setup () {// inicializações Serial.begin (115200); printTimeStamp (); Serial.print (":"); # ifdef FAST_MODE Serial.println ("CV Zone Controller iniciado em TestMode! \ N" "- O tempo da placa é cerca de 50 vezes mais rápido \ n" "- O ciclo de manutenção da bomba é executado a cada 3 horas em vez de uma vez por 36 horas "); # else Serial.println (" Controlador de zona CV iniciado. Carimbos de tempo (dd:hh:mm:ss) "); # endif Serial.println (" - Formato dos carimbos de hora (dd:hh:mm:ss) "); printConfiguration (); wdt_enable (WDTO_1S); // Watchdog:reinicia a placa após um segundo, se nenhum "pat the dog" recebido} void loop () {#ifdef FAST_MODE delay (2); // 50 vezes mais rápido, então os minutos se tornam aproximadamente segundos para fins de depuração; portanto, cada contagem de resfriamento ou inativo é 0,002 segundos # else delay (100); // Operação normal:loops aproximadamente 10 vezes por segundo; então, cada contagem para resfriamento ou inatividade é de 0,1 segundo # endif // Use o LED de indicação para mostrar que a placa está ativa iLED.Alternate (); // uma vez por loop () a bomba e as válvulas precisam opdate hteir administatrion FUPump.Update (); for (int i =0; i permanecer neste estado if (FloorPumpingAllowed ()) {FUPump.On (); } else {FUPump.Off (); }} else if (CVState.checkCoolDownNeeded ()) {// Continue no estado de resfriamento para manter a bomba funcionando por um tempo CVState (State ::cooldown); } else {// ignora o resfriamento da unidade de piso, volte para o CVState ocioso (State ::idle); }} void coolDownProcessing () {hLED.Alternate (); if (HeatingRequested ()) {// retorna verdadeiro quando um dos termostatos é fechado CVState (State ::on); } else {if (CVState.whileCoolDownNeeded ()) {if (FloorPumpingAllowed ()) {FUPump.On (); } else {FUPump.Off (); }} else {CVState (State ::idle); }}} void idleProcessing () {if (HeatingRequested ()) {// retorna verdadeiro quando um dos termostatos é fechado CVState (State ::on); } else {// Durante o período de inatividade, esta verificação ativará a bomba da unidade de chão por 8 minutos a cada 36 horas para mantê-los operáveis if (FUPump.doMaintenanceRun ()) {if (FUPump.IsOff ()) {if (allValvesOpen () ==false) {// começa a abrir apenas uma vez printTimeStamp (); Serial.println (":iniciar o ciclo diário da bomba da unidade de chão; abrir as válvulas:"); allValvesOn (); } if (FloorPumpingAllowed ()) {// leva cerca de 5 minutos após a ativação das válvulas (6 segundos no modo de teste) printTimeStamp (); Serial.println (":iniciar o ciclo diário da bomba da unidade de piso; iniciar a bomba"); FUPump.On (); }}} else if (FUPump.IsOn ()) {// nenhuma manutenção necessária. Portanto, pare a bomba se ainda estiver executando printTimeStamp (); Serial.println (":Pare o ciclo diário da bomba da unidade de chão; pare a bomba e feche as válvulas"); FUPump.Off (); allValvesOff (); }}} /////////////////////////////////////////////////// /////////////////////////// Métodos auxiliares usados pelos manipuladores de estado ////////////////////// /////////////////////// void allValvesOff () {for (int i =0; i Devices.h C / C ++
// Classes auxiliares para dispositivos IOextern void printTimeStamp (); // definido no arquivo ino principal // IODevice:classe base para todos os dispositivos IO; necessita de classe de especialização IODevice {// vars protected:bool _IsOn; int _Pin; String _Name; // construtor público:IODevice (int pin, String name) {_IsOn =false; _Pin =pin; _Nome =nome; } // métodos bool virtual IsOn () =0; // bool virtual abstrato IsOff () {// padrão para todos return! IsOn (); } void DebugPrint () {printTimeStamp (); Serial.print (":"); Imprimir(); } void Print () {Serial.print (_Name); Serial.print ("on pin ("); Serial.print (_Pin); if (_IsOn) Serial.println (") =On"); senão Serial.println (") =Desligado"); }}; // Termostato:lê uma entrada digital adicionando alguma classe de surpressão dender Termostato:public IODevice {// vars private:int _Counter; // usado para prevenir a leitura de comutação intermitente (dender) // construtor público:Thermostat (int pin, String name):IODevice (pin, name) {_Counter =0; pinMode (_Pin, INPUT_PULLUP); } // métodos bool virtual IsOn () {if (digitalRead (_Pin) ==HIGH &&_IsOn ==true) // abrir contato enquanto on {if (_Counter ++> 5) // agir somente após 5 vezes a mesma leitura { _IsOn =falso; DebugPrint (); _Contador =0; }} else if (digitalRead (_Pin) ==LOW &&_IsOn ==false) // contato fechado enquanto desligado {if (_Contador ++> 5) // age somente após 5 vezes a mesma leitura {_IsOn =true; DebugPrint (); _Contador =0; }} else {_Counter =0; } return _IsOn; }}; // Manipulador:o dispositivo de trabalho mais básico em uma classe de saída digital Manipulator:public IODevice {// vars private:// constructor public:Manipulator (int pin, String name):IODevice (pin, name) {pinMode ( _Pin, OUTPUT); digitalWrite (_Pin, HIGH); } // métodos void On () {if (_IsOn ==false) {_IsOn =true; digitalWrite (_Pin, LOW); onSwitch (); }} void Off () {if (_IsOn ==true) {_IsOn =false; digitalWrite (_Pin, HIGH); onSwitch (); }} virtual void onSwitch () {// disparar para claases filho; mudança no estado ligado / desligado DebugPrint (); } bool virtual IsOn () {return _IsOn; }}; // Válvula:controla as válvulas estáticas em uma saída digital. // Essas válvulas reagem lentamente (3-5 minutos), portanto, esta classe adiciona essa consciência de transição // loop () deve chamar Update () para manter o controle se a válvula está totalmente aberta ou fechada Valve:public Manipulator {private:long transicionCount; // construtor público:Valve (int pin, String name):Manipulator (pin, name) {transactionCount =0; } bool ValveIsOpen () {return (IsOn () &&(transitCount> =VALVE_TIME)); // pelo menos 5 minutos no estado ativo} // Executar uma vez por passagem no loop de esboço () !!! void Update () {if (IsOn ()) {if (transiçãoContagem0) transactionCount--; }}}; // Bomba:uma bomba precisa ser ativada várias vezes por semana para mantê-la funcionando. // loop () deve chamar Update () para manter o controle quando uma ativação de manutenção é necessária classe Pump:public Manipulator {// as válvulas reagem lentamente (3-5 minutos), portanto, esta classe adiciona essa percepção de transição private:long counter; bool doMaintenance; // construtor public:Pump (int pin, String name):Manipulator (pin, name) {counter =0; doMaintenance =false; } bool doMaintenanceRun () {return doMaintenance; } virtual void onSwitch () {// altera o estado ligado / desligado Manipulator ::onSwitch (); contador =0; } // executa este método a cada passagem em loop () void Update () {if (IsOn ()) {if (contador 250) #else if (counter ++> 5) #endif {/ / alternar contador de LED =0; if (IsOn ()) Off (); else On (); }}};
Esquemas
Fiação detalhada de periféricos (bomba, válvulas, termostatos, LEDs)


Processo de manufatura
- Controlador de energia PWM
- Sistema de aquecimento solar
- Monitorando minha caldeira de aquecimento central
- Fazendo a manutenção de um depurador de piso
- Controlador DMX operado pela web
- Dispositivo de automação de tarefas de videogame
- Controlador de jogo Arduino
- Unopad - Controlador Arduino MIDI com Ableton
- Controlador de display fluorescente a vácuo
- Conecte o aquecimento central ao Arduino