Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Termostato inteligente, ar e controle de luzes com Bluetooth

Componentes e suprimentos

Arduino Nano R3
× 1
Módulo Bluetooth HC-05
× 1
Maxim Integrated DS18B20 Termômetro digital de 1 fio de resolução programável com resolução programável
× 1
oled 1306 I2C bicolor
× 1
ControlEverything.com CONTROLADOR DE RELÉ DE 4 CANAIS PARA I2C
× 1

Aplicativos e serviços online

Terminal Bluetooth Serial Morich para Android
Dispositivo de controle Arduino Bluetooth para Android

Sobre este projeto





Introdução


Projeto DIY Arduino termostato simples, mas útil com Bluetooth.

Uma rotina de termostato inteligente controla a caldeira do aquecedor a gás, e o sistema liga as luzes da minha cozinha e o ventilador do banheiro com relés - pode ser controlado por botões e dispositivo Android ou computador via Bluetooth. Celsius e Fahrenheit versão também disponível! Todas as peças são feitas à mão.

Desenvolvido na placa Arduino Nano (ou superior), usa sensor de temperatura Dallas DS18B20, adaptador Bluetooth HC-05/06, display OLED bicolor I2C 128X64– você pode escolher display LCD / OLED diferente, o u8glib suporta vários tipos.





Vídeo


O vídeo mostra todas as formas de trabalho importantes e dá ideias de como construir o projeto desde o início.





Modos de funcionamento do aquecedor


1: Modo cronometrado de aquecimento único (15 minutos), útil nas noites de primavera / outono

2: Modo termostato (prioridade mais alta) , a temperatura alvo ajustada armazenada na memória EEPROM





Algoritmo de economia de caldeira


A comutação frequente e de curto prazo reduziria a vida útil da caldeira a gás do aquecedor; para evitar isso, o programa usa valores de correção - estes declaram o grau de superaquecimento e resfriamento de volta. A temperatura mais baixa exige valores de correção maiores, porque as paredes são mais frias e absorvem melhor o calor do ar recém-aquecido, de modo que o efeito descrito acima seria mais forte.





Detecção de janela aberta


O programa detecta se uma janela está aberta, portanto, a temperatura cai pelo menos -0, 2 ° C (-0, 36F) em um minuto - o aquecedor para ou não liga e o ventilador liga para ajudar a refrescar o ar. Quando o ar ficou mais quente pelo menos +0, 12 ° C (+0, 216F) devido à capacidade de calor do ambiente, o sistema voltará ao modo normal e o evento 'Alerta de janela' será descartado.





Detecção de erros


A temperatura medida abaixo de 0 ° C (32F) ou acima de 40 ° C (104F) será avaliada como mau funcionamento ou outro problema (erro, janela quebrada, incêndio, etc.) e todos os dispositivos serão desligados.





Comunicação Bluetooth


O aplicativo Android GUI tem 8 botões, envia letras maiúsculas e minúsculas para ligar ('A') ou desligar ('a') o aquecedor temporizado, 'B' e 'b' ativam a ventilação, 'C 'e' c 'as luzes ...

O outro ponto forte do meu projeto é o uso do terminal serial Bluetooth do amigo geek. Basta conversar com o sistema via Bluetooth usando um terminal serial - pode ser um aplicativo Android, mas até um PC normal serve - por exemplo, o Serial Monitor do Arduino IDE.

O controlador envia relatórios de temperatura a cada minuto automaticamente e relatórios instantâneos sobre todos os eventos, como um dispositivo conectado foi ligado / desligado, a rotina do termostato ativada e assim por diante.





Códigos de controle


Aceita códigos de controle e envia mensagens de confirmação. Minha estrutura de comando com base em números de dois dígitos como 'XY' - onde;

‘X’ é o código do dispositivo e ‘Y’ é o opcode

30, 31, 32:iluminação desligada / ligada / estado lógico invertido

40, 41, 42:estado lógico de arejamento Off / On / flip

50, 51, 52:programa de aquecimento único desligado / ligado / estado lógico invertido

10 - 24 números serão aceitos como temperatura alvo para a função do termostato

'R' - relatório sobre o estado de funcionamento de dispositivos controlados

‘W’ - desativa manualmente o evento de “alerta de janela”, se você não quiser esperar por sua desativação automática

‘A, a ... H, h’ - as letras são aceitas como o aplicativo GUI teria enviado





Versão Fahrenheit


Foram convertidas todas as variáveis ​​de correção, valores de referência e razão, para que o sistema mantivesse seu cálculo e particularidades de trabalho.

Apenas algumas modificações. Os novos códigos de dispositivo da versão Fahrenheit:

1 - Iluminação (10:desligada, 11:ligada, 12:estado invertido)

2 - Exibição

3 - Aquecedor

50 - 76 números são valores de temperatura alvo





A sequência


ATUALIZAÇÃO:um sistema de automação residencial completo com link Bluetooth interno e controle de voz!

DallasTemperature, elapsedMillis, OneWire, SoftwareSerial, olikraus / u8glib

Se você usa resistores de botão diferentes, ou precisa verificar as leituras de A0, sugiro verificar o seguinte:

http://blog.codebender.cc/2015/07/20/tutorial-multiple-buttons-on-1-analog-pin/

Código

  • Termostato v11 - versão Celsius.ino
  • Termostato v11 - versão Fahrenheit.ino
Termostato v11 - versão Celsius.ino Arduino
O código do programa se explica sozinho, útil para iniciantes. Bem comentado, descreve todas as etapas importantes; o que, por que e como. Dividido em módulos por funções, é por isso fácil de visualizar.
 // Celsius versão v1.1 // Código de programa de uma solução de termostato inteligente Arduino inteligente, // baseada na placa Arduino Nano (ou superior), sensor térmico DS18B20, Adaptador Bluetooth HC-05, display OLED bicolor I2C 128X64.// O sistema pode ser controlado por botões e smartphone Android via bluetooth.//// Cuida da caldeira a gás HEATER, do ventilador do banheiro e da cozinha ILUMINAÇÃO - acionada por relés .// O aquecedor possui duas formas de funcionamento. 1:modo cronometrado de aquecimento único (15 minutos), 2:modo termostato (prioridade mais alta). O tempr.// alvo ajustado armazenado na EEPROM. O programa detecta erros de hardware e abertura de janela - nestes casos, o aquecedor para e / ou não inicia.//// Projetado e programado por Gyula Osi.// Todos os direitos reservados.// --------- -------------------------------------------------- -------------------------------------------------- ----------------------- // ---- Exibir barramento I2C, SDA (TX) -> A4, SCL (RX) -> A5 # inclui "U8glib.h" U8GLIB_SSD1306_128X64 u8g (U8G_I2C_OPT_NONE); // exibe constructorbyte frame =0; // inicia o ponteiro do logotipo // ---- Portas e declarações relacionadasconst byte buzzer =9; // campainha para D9int btnVal; // armazena valores analógicos de botõesconst byte relayA =11; // airingbool aState =0; bool aStateByCmd; // se o "alerta de janela" desaparecer, o controle de exibição voltará ao estado original byte relayL =13; // lightingbool lState =0; const byte relayH =10; // heaterconst byte ledH =6; // As portas PWM permitem o ajuste do nível de saída usado para alterar o brilhoconst byte ledA =5; const byte ledL =3; const byte bright [3] ={0, 10, 100}; byte brightHeat =bright [2]; # define ledInterval 1000 // aquecedor led intervalo piscandounsigned long prev =0; // ---- Strings para relatórios seriais e de exibição #define STATE_ITEMS 3 // strings do indicador de estado do dispositivo para saídas // i -> 0 1 2const String state_str [STATE_ITEMS] ={"on.", "Off.", "Auto."}; String heaterState; String airingState; String lightingState; #define FUNCT_ITEMS 11 // i -> 0 1 2 3 4 5 6 7 8 9 10 String funct_str [FUNCT_ITEMS] ={"Heater is", "Airing is", "Lighting is", "Window Alerta! "," Erro de hardware! "," Pressione uma tecla>> "," ou envie um código! "," Target tempr ="," Temperature ="," * "," - "}; // - - Medição de temperatura e recursos relacionados ao aquecedor # incluem  elapsedMillis timer0; // 8 bits, cronômetro PWM, usado pela função elapsedMillis () # define sftyTmrInterval 15 * 60000 // um Tempo de aquecimento (15 minutos) intervalo de modo cronometrado [ms] bool sftyTmrEnded; // inicialização booleana, o timer0 terminou # include  byte tTarget; // temprconst alvo ajustado int addr =0; // o endereço atual da variável tTarget no memorybool EEPROM hState =0; // aquecedor booleano statebool hThermostat =0; // estado booleano do termostato # include "OneWire.h" #include "DallasTemperature.h" #define DS18B20 2 // configurar o barramento OneWire no D2OneWire temprWire (DS18B20); // configurar o DS18B20 para funcionar nos sensores OneWire busDallasTemperature (&temprWire); float tempr; // valor medidofloat temprPrev; // cópia do valor medido para análise de tendência windowAlrt =0; // grau de temperatura especificado dropbool measError =0; // o valor do tempr medido está fora do intervalo especificado como normalconst long temprInterval =60000; // intervalo de medição de tempo cíclico [ms] unsigned long temprTmrPrev =0; // o decorrido será o anterior quando temprMeas () calledfloat heatCorrVal; // declara o grau de superaquecimento e resfriamento, consulte a função tempMeas () // ---- Configuração da comunicação serial em RXD / TXD virtual # include  // Pinos RX e TX seriais SW para HC-05const int RX1 =8; const int TX1 =4; SoftwareSerial sUART (RX1, TX1); char RX [2]; // armazena o databool serial recebido errMsgSentBySys =0; inicialização bool =1; // manter evita um relatório de BT duplicado na inicializaçãoconst uint8_t frame1 [] U8G_PROGMEM ={// Mapa XBM 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF , 0x7F, 0x00, 0xFC, 0xFF, 0x7F, 0xF0, 0x3F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0xFF, 0x7F, 0xF0, 0x8F, 0xFF, 0xFF , 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF , 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C , 0x3F, 0x1E, 0xFF, 0x00, 0xFE, 0x1F, 0xFF, 0xF1, 0x00, 0x18, 0xC0, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C, 0x3F, 0x1E, 0xFF, 0x00, 0xFE, 0x1F, 0xFF, 0xF1, 0x00 , 0x18, 0xC0, 0x8F, 0xFF, 0x1F, 0x1F, 0x0C, 0x3E, 0x1E, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0x31, 0xFE, 0x7F, 0xFC, 0x8F, 0xFF, 0x1F, 0x1F, 0x0C, 0x3E, 0x1E , 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0x31, 0xFE, 0x7F, 0xFC, 0x0F, 0x0E, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0xFC, 0x00, 0xF8, 0x1F, 0x7C, 0x30, 0xFE, 0x7F, 0xF0 , 0x0F, 0x0E, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0xFC, 0x00, 0xF8, 0x1F, 0x7C, 0x30, 0xFE, 0x7F, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0x1E, 0x3C, 0x3E , 0xF8, 0x1F, 0x7C, 0xF0, 0x00, 0x7E, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x00, 0x7E, 0xF0, 0x0F, 0xFE, 0xFE , 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F , 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x3F, 0x00, 0x7E, 0x00, 0x3C, 0x80, 0x07, 0xF0, 0x00, 0xF8, 0x7F, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0x3F, 0x00, 0x7E, 0x00, 0x3C, 0x80, 0x07, 0xF0, 0x00, 0xF8, 0x7F, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x06, 0xE6, 0x3F, 0x06, 0xC6, 0x7F, 0xFE, 0xE7, 0x3F, 0x7E, 0xFE, 0xC7, 0x7F, 0x00, 0x00, 0x30, 0x30, 0x06, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x06, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3E, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0x1E, 0 xC7, 0x3F, 0x70, 0xE0, 0x3F, 0x3C, 0xFE, 0xC3, 0x3F, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0x1E, 0xC7, 0x3F, 0x70, 0xE0, 0x3F, 0x3C, 0xEFE, 0xC3, 0x3F, 0x00, 0x00, 0x3C, 0xDE, 0xE7, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x1D, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE7, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x31, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE6, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x61, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE6, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x61, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x7F, 0x1E, 0xE6, 0x3F, 0xFC, 0xE3, 0x3F, 0x70, 0xE0, 0x70, 0x61, 0x7E, 0xFE, 0xE7, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00,}; configuração vazia () {sUART.begin (9600); pinMode (relayH, OUTPUT); relayHandlerH (4); // obtém o estado de trabalho pinMode (ledH, OUTPUT); pinMode (relayA, OUTPUT); relayHandlerA (4); pinMode (ledA, OUTPUT); pinMode (relayL, OUTPUT); relayHandlerL (4); pinMode (ledL, OUTPUT); pinMode (campainha, OUTPUT); sensores.begin (); // inicia DS18B20 temprMeas (); // não espere pelo meas.timer, chame a função uma vez na inicialização tTarget =EEPROM.read (addr); // lê o valor tTarget armazenado anteriormente do endereço atual da EEPROM na inicialização startup =0; if (! measError) {sTX (8); // chama para um relatório instantâneo dos estados de trabalho após a inicialização} else {sTX (2); }} void loop () {temprTimer (); ledHandler (); btnReadings (); sRX (); safetyTmr (); u8g.firstPage (); // loop scr do {draw (); } while (u8g.nextPage ()); if (frame ==0) {delay (3000); frame =1; clrScr (); }} void btnReadings () {// --------- Leituras Btn btnVal =analogRead (A0); // ler val analógico de A0 if (btnVal> =510 &&btnVal <=516) {// btn Lighting delay (100); // btn debounce buzz (3, 1); relayHandlerL (2); // chamar a função adequada com o código de operação de mudança de estado lógico como parâmetro} else if (btnVal> =849 &&btnVal <=855) {// btn Airing if (windowAlrt ==1) {// se o sistema estiver no modo Window Alert, desative-o windowAlrt =0; zumbido (4, 3); relayHandlerA (3); } else {// else liga / desliga o atraso do ventilador de ventilação (100); zumbido (3, 1); relayHandlerA (2); }} else if (btnVal> =927 &&btnVal <=933) {// btn Aquecimento Único (15 min) atraso do modo cronometrado (100); zumbido (3, 1); relayHandlerH (2); } else if (btnVal> =767 &&btnVal <=777) {// btn diminuir tTarget delay (100); tTargetHandler (0); } else if (btnVal> =687 &&btnVal <=697) {// btn aumentar tTarget delay (100); tTargetHandler (1); } else if (btnVal> =856 &&btnVal <=862) {// inc &dec btns ao mesmo tempo tTarget =14; // <====valor inicial - pressione esses botões na primeira inicialização! }} void sRX () {// ------------- Receber dados seriais enquanto (sUART.available ()> 0) {// se os dados estiverem disponíveis para leitura (byte i =0; i <2; i ++) {RX [i] =sUART.read (); }} int iRX [2]; para (byte i =0; i <2; i ++) {iRX [i] =RX [i] - '0'; } switch (RX [0]) {// ------------ aceita um ÚNICO código de controle ALFABÉTICO caso 'A':relayHandlerH (1); // 1 =em pausa; caso 'a':relayHandlerH (0); // 0 =pausa para desligar; // Os dados seriais recebidos podem ser uma única letra alfabética do app Android "Arduino case 'B':// Bluetooth Control Device". Se for um relayHandlerA adequado em ordem alfabética (1); // o caractere chega, o código do programa não espera pelo segundo, break; // mas chama a função aplicável com um código de operação adequado. case 'b':// Casos de dados numéricos combinados podem ser vistos abaixo. relayHandlerA (0); pausa; caso 'C':relayHandlerL (1); pausa; caso 'c':relayHandlerL (0); pausa; case 'D':case 'd':tTarget =21; tTargetEEPROM (); zumbido (3, 1); pausa; case 'E':case 'e':tTarget =19; tTargetEEPROM (); zumbido (3, 1); pausa; case 'F':case 'f':tTarget =14; tTargetEEPROM (); zumbido (3, 1); pausa; case 'R':// chama para um relatório geral sobre os dispositivos controlados case 'r':sTX (8); pausa; case 'W':// desativa o estado de alerta da janela case 'w':windowAlrt =0; zumbido (4, 3); relayHandlerA (3); pausa; } // ----------------------- aceitar códigos de controle NUMÉRICOS COMBINADOS // Neste caso, um código de controle numérico de dois dígitos chega no formato char, // de um aplicativo serial de bluetooth para Android, por exemplo. Após uma conversão de caractere para inteiro // (somente se o primeiro caractere for '1' ou '2'), um processo de mesclagem se seguirá, // e o sistema de condições e instruções tomará uma decisão e a executará. // Os códigos numéricos apropriados são:// // ---------------- Temperatura alvo:// 10 - 24 valores serão aceitos como temperatura alvo para a função do termostato. // // ---------------- Códigos de controle do dispositivo:// Primeiro =código do dispositivo, Segundo =código do operador // 30, 31, 32 liga a iluminação:30 =desligado, 31 =ligado // 32 =estado lógico invertido (ligado -> desligado / desligado -> ligado) // 40, 41, 42 fará o mesmo com o ventilador de ventilação // 50, 51, 52 controla o aquecimento único (15 minutos) programa de aquecedor cronometrado como acima // // ---------------- Códigos de operador classificados:// X3, X4 são classificados, usados ​​apenas para chamadas de função por sequências de programa internas se ( RX [0] =='3') {relayHandlerL (iRX [1]); } if (RX [0] =='4') {relayHandlerA (iRX [1]); } if (RX [0] =='5') {relayHandlerH (iRX [1]); } if ((iRX [0] * 10 + iRX [1] <=24) &&(iRX [0] * 10 + iRX [1]> =10)) {// aceitar apenas valores numéricos entre 10 e 24 tTarget =iRX [0] * 10 + iRX [1]; // mesclar dois inteiros e definir tTarget tTargetEEPROM (); // depois de definido, chame a função de manipulador EEPROM, e buzz (3, 1); // escreva o valor tTarget no byte apropriado da EEPROM} if (RX [0] =='0') {// teste para (byte i =1; i <5; i ++) {buzz (5, 2); }} for (byte i =0; i <2; i ++) {// esvaziar todos os receptores de mensagem e variáveis ​​de conversão RX [i] ='Z'; }} void relayHandlerL (byte lOperator) {// Operadores de sequência do manipulador de iluminação // são:0 =desligado, 1 =ligado, 2 =inverter o estado, 4 =preencher / recarregar o estado de iluminação char var. if ((measError) &&((lOperator ==1) || (lOperator ==2))) {sTX (4); Retorna; } if ((lOperator ==2) || (lOperator ==0) &&(lState) || (lOperator ==1) &&(! lState)) {lState =! lState; digitalWrite (relayL, lState); zumbido (2, 1); } if (lOperator> =0) {// preencher o caractere do estado de trabalho com a string indicadora de estado apropriada if (lState) {lightingState =state_str [0]; } else {lightingState =state_str [1]; } if (! inicialização) {sTX (7); }}} void relayHandlerA (byte aOperator) {// Airing Handler Sequence if ((measError) &&((aOperator ==1) || (aOperator ==2))) {// operator are:0 =off, 1 =on, 2 =inverte o estado, sTX (4); // 3 =chamado por temprMeas () funct., 4 =encher / encher o estado de arejamento char var. Retorna; } aState =digitalRead (relayA); if (! windowAlrt) {if ((aOperator ==2) || (aState) &&(aOperator ==0) || (! aState) &&(aOperator ==1)) {aState =! aState; digitalWrite (relayA, aState); aStateByCmd =digitalRead (relayA); zumbido (2, 1); }} if (aOperator ==3) {// chamado pela função temprMeas (), 'windowAlrt' finalizado ou iniciado if ((! aState) &&(windowAlrt) || (aState) &&(! windowAlrt) &&(! aStateByCmd )) {digitalWrite (relayA, windowAlrt); }} aState =digitalRead (relayA); if (aOperator> =0) {if (aState) {if (windowAlrt) {airingState =state_str [2]; } else {airingState =state_str [0]; }} else {airingState =state_str [1]; }} if (! inicialização) {sTX (6); }} void relayHandlerH (byte hOperator) {// Os operadores Heater Handler Sequence // são:0 =off, 1 =on, 2 =inverter o estado, // 3 =chamado por temprMeas () funct., 4 =fill / refill o estado do aquecedor char var. if ((measError) &&((hOperator ==1) || (hOperator ==2))) {sTX (4); Retorna; } if ((! hThermostat) &&(! windowAlrt) &&(! measError)) {// liga / desliga o modo de aquecimento único (15 minutos) se ((hOperator ==2) || (hOperator ==1) ) &&(! hState) || (! hOperator) &&(hState)) {buzz (2, 1); hState =! hState; sftyTmrEnded =0; timer0 =0; digitalWrite (relayH, hState); }} if (windowAlrt) {sTX (3); } if (hOperator ==3) {// esta função chamada pela função temprMeas () (op 3) // para examinar windowAlrt &measError booleans if ((windowAlrt) &&(hState)) {// uma janela é aberto e o aquecedor está executando digitalWrite (reléH, 0); zumbido (5, 3); } if ((! windowAlrt) &&(! measError)) {if ((hThermostat) || (! hThermostat) &&(hState) &&(sftyTmrEnded)) {digitalWrite (relayH, hThermostat); // prosseguir com o comando da Rotina do Termostato}}} hState =digitalRead (relayH); if (hOperator> =0) {if (hState) {if (hThermostat) {heaterState =state_str [2]; } else {heaterState =state_str [0]; }} else {heaterState =state_str [1]; } if ((((! windowAlrt) &&(hOperator! =3)) || (hState)) &&(! inicialização)) {sTX (5); }}} void safetyTmr () {// Temporizador para o modo de aquecimento único (15 minutos cronometrados) if ((hState) &&(! sftyTmrEnded) &&(timer0> sftyTmrInterval) &&(! hThermostat)) {sftyTmrEnded =1; relayHandlerH (0); para (byte i =1; i <5; i ++) {buzz (i, 2); }}} void temprTimer () {// Cronômetro cíclico para temprMeas () unsigned long temprTmrCurr =millis (); if (temprInterval <=temprTmrCurr - temprTmrPrev) {temprTmrPrev =temprTmrCurr; temprMeas (); }} void temprMeas () {// ----------- Sequência de medição e comparação de temperatura temprPrev =tempr; // salve o valor para a próxima comparação sensores.requestTemperatures (); // atualiza as leituras do sensor tempr =sensores.getTempCByIndex (0); // leia a temperatura if ((tempr> =40) || (tempr <=0)) {// valores de medição extremos:if (! errMsgSentBySys) {// -127, -196,60 são erros de HW, +85 é tipicamente SW erro, mas sTX (4); // pode ser disparado ou uma janela quebrada} errMsgSentBySys =1; hThermostat =0; if (hState) {relayHandlerH (0); } if (aState) {relayHandlerA (0); } se (lState) {relayHandlerL (0); } measError =1; para (byte i =1; i <10; i ++) {buzz (4, 1); atraso (50); }} else {temprPrev =tempr; measError =0; errMsgSentBySys =0; } if (! measError) {// ------------ Início da sequência de análise de temperatura if (tempr <=17) {// A troca frequente e de curto prazo da caldeira de gás do aquecedor seria interrompida seu tempo de vida, o heatCorrVal =0,5; // o valor heatCorrVal ajuda a evitar isso. Declara o grau de superaquecimento e resfriamento de volta. } // A temperatura mais baixa exige maior heatCorrVal, porque as paredes são mais frias e absorvem melhor o if ((tempr> 17) &&(tempr <19)) {// calor do ar recém-aquecido, então o efeito descrito acima seria mais efetivo. heatCorrVal =0,4; } if (tempr> =19) {heatCorrVal =0,3; } if (tTarget - tempr> =heatCorrVal) {// subtrair o valor medido do alvo, se a diferença for igual ou maior que heatCorrVal sftyTmrEnded =1; // desativa o programa cronometrado Aquecimento Único (15 minutos) se ele estiver em execução hThermostat =1; // liga o buzz do termostato (1, 1); } if ((tTarget - tempr <=-1 * heatCorrVal) &&(hThermostat)) {hThermostat =0; } if ((temprPrev - tempr> =0.2) &&(! windowAlrt) &&(tempr <=20)) {// em um ciclo de medição e na estação de aquecimento, a janela de temperaturaAlrt =1; // descarta, ele será avaliado como uma janela aberta sftyTmrEnded =1; para (byte i =1; i <5; i ++) {buzz (4, 1); atraso (50); } relayHandlerA (3); // chamar a função de arejamento (opcode =3), para ajudar a refrescar o ar} if ((temprPrev - tempr <=-0,12) &&(windowAlrt)) {// o tempr. a queda acabou, o ar ficou mais quente windowAlrt =0; // devido à capacidade térmica do ambiente, buzz (4, 3); // então volte ao modo normal relayHandlerA (3); } relayHandlerH (3); // a função examinará o chamador param (3) &windowAlrt &measError booleans if (! windowAlrt) {sTX (1); }}} void tTargetHandler (bool set) {// define o tempo necessário aumentando ou diminuindo if (! set) {// incr if (tTarget <24) {// até atingir o limite superior tTarget ++; zumbido (3, 1); } else {buzz (2, 3); }} else {// decrementar if (tTarget> 10) {tTarget--; zumbido (3, 1); } else {buzz (2, 3); }} tTargetEEPROM ();} void tTargetEEPROM () {EEPROM.write (addr, tTarget); // após incr / decr / set, escreve o valor tTarget no byte apropriado do atraso EEPROM (10); sTX (2);} void draw (void) {// manipulador de logotipo if (frame ==0) {u8g.drawXBMP (0, 0, 128, 64, frame1); } else if (frame ==1) screenFunctState (); } void screenFunctState(void) { // function state screen temprWriteOut(0, 64); u8g.drawHLine(0, 46, 128); u8g.setFont(u8g_font_unifont); if (!windowAlrt) { u8g.setPrintPos( 0, 14); u8g.print(funct_str[0]); u8g.setPrintPos(84, 14); u8g.print(heaterState); } else { u8g.setPrintPos( 0, 14); u8g.print(funct_str[3]); } u8g.setPrintPos( 0, 28); u8g.print(funct_str[1]); u8g.setPrintPos(88, 28); u8g.print(airingState); u8g.setPrintPos( 0, 42); u8g.print(funct_str[2]); u8g.setPrintPos(95, 42); u8g.print(lightingState); if ((!hState) &&(!aState) &&(!lState)) { screenStndby(); // if all of controlled devices are in off, call standby screen }}void screenStndby() { // standby scr u8g.firstPage(); do { u8g.setFontRefHeightText(); u8g.setFont(u8g_font_unifont); if (!measError) { u8g.setPrintPos(33, 52); u8g.print(funct_str[5]); u8g.setPrintPos( 8, 64); u8g.print(funct_str[6]); } else { u8g.setPrintPos( 4, 48); u8g.print(funct_str[4]); } temprWriteOut(0, 16); } while( u8g.nextPage() );}void temprWriteOut (byte tX, byte tY) { // draw tempr &tTarget variables onto different coordinates u8g.setFont(u8g_font_courB14);//u8g.setFont(u8g_font_6x12); // you can save ~10% of prog.memory using this font with 2x2 scale char buftTarget[9]; sprintf (buftTarget, "%d", tTarget); // int to char//u8g.setScale2x2();//tY =tY / 2; u8g.setPrintPos(tX, tY); u8g.print(buftTarget); u8g.setPrintPos(tX+18, tY); u8g.print(funct_str[9]); u8g.setPrintPos(tX+50, tY); u8g.print(tempr); u8g.print(char(176)); u8g.print("C");//u8g.undoScale();}void clrScr(){ u8g.firstPage(); do { } while( u8g.nextPage() );}void ledHandler() { // the brightness of a led is low, if the indicated device is off, and high, if its on if (aState) { analogWrite(ledA, bright[2]); } else { analogWrite(ledA, bright[1]); } if (lState) { analogWrite(ledL, bright[2]); } else { analogWrite(ledL, bright[1]); } if (hState) { if (!hThermostat) { ledBlnk(); // the heater led blinks when the One Time Heating (15 mins) timed mode is activated, } else { brightHeat =bright[2]; // and constant bright, if the thermostat routine is active } } else { brightHeat =bright[1]; } analogWrite(ledH, brightHeat);}void ledBlnk() { unsigned long curr =millis(); if (ledInterval <=curr - prev) { // subtract prev value from current, if the difference equals or greater than ledInterval const. prev =curr; // overwrite the earlier value with the current and flip brightness level if (brightHeat ==bright[1]) { brightHeat =bright[2]; } else { brightHeat =bright[1]; } } analogWrite(ledH, brightHeat);}void buzz(byte b, byte d) { // call with frequency and delay parameters tone(buzzer, b * 1000); delay(d * 100); noTone(buzzer);}void sTX(byte reportTX) { // sending serial reports switch (reportTX) { case 0:for (byte i =0; i <9; i++) { sUART.print(funct_str[10]); } sUART.println(funct_str[10]); pausa; case 1:sUART.print(funct_str[8]); // Tempr. sUART.print(tempr); sUART.print(char(176)); sUART.println("C"); pausa; case 2:sUART.print(funct_str[7]); // TTemp sUART.print(tTarget); sUART.print(char(176)); sUART.println("C"); pausa; case 3:sUART.print(funct_str[3]); // Window Alert sUART.print(funct_str[9]); sUART.print(tempr); sUART.print(char(176)); sUART.println("C"); pausa; case 4:sUART.println(funct_str[4]); // Error report break; case 5:sUART.print(funct_str[0]); // Working state of devices sUART.println(heaterState); pausa; case 6:sUART.print(funct_str[1]); sUART.println(airingState); pausa; case 7:sUART.print(funct_str[2]); sUART.println(lightingState); pausa; case 8:// Overview report sTX(0); relayHandlerH(4); relayHandlerA(4); relayHandlerL(4); sTX(2); if (measError) { sTX(4); } pausa; }} 
Thermostat v11 - Fahrenheit version.inoArduino
The program code explains itself, useful for beginners. Well commented, describes every important steps; what, why and how. Divided into modules by functions, that’s why easy to overview.
Works in Fahrenheit, I changed only the Target temperature values (50-76), and the device codes (1, 2 and 3).
// Fahrenheit version v1.1// Program code of an intelligent Arduino smarthome thermostat solution, // based on Arduino Nano (or higher) board, DS18B20 thermo sensor, HC-05 Bluetooth adapter, I2C 128X64 bicolor OLED display.// The system can be controlled by buttons and Android smartphone via bluetooth.//// It handles the HEATER gas boiler, the bathroom AIRING ventilator and the kitchen LIGHTING - swithed with relays.// The heater has two working ways. 1:One Time Heating (15 mins) timed mode, 2:Thermostat mode (higher priority). The adjusted target tempr.// stored in EEPROM. The program detects hardware errors and window opening - in these cases the heater stops and/or will not start.//// Designed and programmed by Gyula Osi.// All rights reserved.// ------------------------------------------------------------------------------------------------------------------------------------// ---- Display I2C Bus, SDA(TX) -> A4, SCL(RX) -> A5#include "U8glib.h"U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // display constructorbyte frame =0; // start logo pointer// ---- Ports and related declarationsconst byte buzzer =9; // buzzer to D9int btnVal; // stores analog values from buttonsconst byte relayA =11; // airingbool aState =0;bool aStateByCmd; // if "window alert" is gone, the airing control goes back to the original stateconst byte relayL =13; // lightingbool lState =0;const byte relayH =10; // heaterconst byte ledH =6; // PWM ports allow output level adjustment used to change brightnessconst byte ledA =5; const byte ledL =3;const byte bright[3] ={0, 10, 100};byte brightHeat =bright[2];#define ledInterval 1000 // heater led blinking intervalunsigned long prev =0;// ---- Strings for Display and Serial Reports #define STATE_ITEMS 3 // device state indicator strings for outputs// i -> 0 1 2const String state_str[STATE_ITEMS] ={"on.", "off.", "auto."}; String heaterState; String airingState;String lightingState;#define FUNCT_ITEMS 11// i -> 0 1 2 3 4 5 6 7 8 9 10 String funct_str[FUNCT_ITEMS] ={"Heater is ", "Airing is ", "Lighting is ", "Window Alert!", "Hardware Error!", "Hit a Key>>", "or send a Code!", "Target tempr =", "Temperature =", " * ", " -"};// ---- Temperature Measurement and Heater Related Features#include  elapsedMillis timer0; // 8-bit, PWM timer, used by function elapsedMillis()#define sftyTmrInterval 15 * 60000 // one Time Heating (15 mins) timed mode interval [ms]bool sftyTmrEnded; // boolean startup, the timer0 has ended#include byte tTarget; // adjusted target temprconst int addr =0; // the current address of the tTarget variable in the EEPROM memorybool hState =0; // heater boolean statebool hThermostat =0; // thermostat boolean state#include "OneWire.h" #include "DallasTemperature.h"#define DS18B20 2 // setup the OneWire bus on D2OneWire temprWire(DS18B20); // configurar o DS18B20 para funcionar nos sensores OneWire busDallasTemperature (&temprWire); float tempr; // measured valuefloat temprPrev; // copy of measured value for trend analysisbool windowAlrt =0; // specified degree of tempr dropbool measError =0; // measured tempr value is out of the range specified as normalconst long temprInterval =60000; // cyclic tempr measurement interval [ms]unsigned long temprTmrPrev =0; // the elapsed will be the previous when temprMeas() calledfloat heatCorrVal; // declares the degree of overheating and cooling back, see tempMeas() function// ---- Configuration of Serial Communication on virtual RXD/TXD#include  // SW serial RX &TX pins for HC-05const int RX1 =8;const int TX1 =4;SoftwareSerial sUART(RX1,TX1); char RX[2]; // store received serial databool errMsgSentBySys =0; bool startup =1; // keep avoid a duplicate BT report at startupconst uint8_t frame1[] U8G_PROGMEM ={ // XBM map 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0xFF, 0x7F, 0xF0, 0x3F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0xFF, 0x7F, 0xF0, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C , 0x3F, 0x1E, 0xFF, 0x00, 0xFE, 0x1F, 0xFF, 0xF1, 0x00, 0x18, 0xC0, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C, 0x3F, 0x1E, 0xFF, 0x00, 0xFE, 0x1F, 0xFF, 0xF1, 0x00, 0x18, 0xC0, 0x8F, 0xFF, 0x1F, 0x1F, 0x0C, 0x3E, 0x1E, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0x31, 0xFE, 0x7F, 0xFC, 0x8F, 0xFF, 0x1F, 0x1F, 0x0C, 0x3E, 0x1E, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0x31, 0xFE, 0x7F, 0xFC, 0x0F, 0x0E, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0xFC, 0x00, 0xF8, 0x1F, 0x7C, 0x30, 0xFE, 0x7F, 0xF0, 0x0F, 0x0E, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0xFC, 0x00, 0xF8, 0x1F, 0x7C, 0x30, 0xFE, 0x7F, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x00, 0x7E, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x00, 0x7E, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E, 0xF8, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x3F, 0x00, 0x7E, 0x00, 0x3C, 0x80, 0x07, 0xF0, 0x00, 0xF8, 0x7F, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0x3F, 0x00, 0x7E, 0x00, 0x3C, 0x80, 0x07, 0xF0, 0x00, 0xF8, 0x7F, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x06, 0xE6, 0x3F, 0x06, 0xC6, 0x7F, 0xFE, 0xE7, 0x3F, 0x7E, 0xFE, 0xC7, 0x7F, 0x00, 0x00, 0x30, 0x06, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x06, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x3E, 0x66, 0x60, 0x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0x1E, 0 xC7, 0x3F, 0x70, 0xE0, 0x3F, 0x3C, 0xFE, 0xC3, 0x3F, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0x1E, 0xC7, 0x3F, 0x70, 0xE0, 0x3F, 0x3C, 0xFE, 0xC3, 0x3F, 0x00, 0x00, 0x3C, 0xDE, 0xE7, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x1D, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE7, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x31, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE6, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x61, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x3C, 0x1E, 0xE6, 0x61, 0x1E, 0x07, 0x70, 0x70, 0xE0, 0x61, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x7F, 0x1E, 0xE6, 0x3F, 0xFC, 0xE3, 0x3F, 0x70, 0xE0, 0x61, 0x7E, 0xFE, 0xE7, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };void setup() { sUART.begin(9600); pinMode(relayH, OUTPUT); relayHandlerH(4); // get the working state pinMode(ledH, OUTPUT); pinMode(relayA, OUTPUT); relayHandlerA(4); pinMode(ledA, OUTPUT); pinMode(relayL, OUTPUT); relayHandlerL(4); pinMode(ledL, OUTPUT); pinMode (campainha, OUTPUT); sensores.begin (); // inicia DS18B20 temprMeas (); // do not wait for the meas.timer, call the function once at startup tTarget =EEPROM.read(addr); // read the previously stored tTarget value from the current address of the EEPROM at startup startup =0; if (!measError) { sTX(8); // call for instant report of working states after startup } else { sTX(2); }}void loop() { temprTimer(); ledHandler(); btnReadings(); sRX(); safetyTmr(); u8g.firstPage (); // scr loop do { draw(); } while (u8g.nextPage ()); if (frame ==0) {delay (3000); frame =1; clrScr(); }}void btnReadings() { // --------- Btn Readings btnVal =analogRead(A0); // read analog val from A0 if (btnVal>=510 &&btnVal <=516) { // btn Lighting delay(100); // btn debounce buzz(3, 1); relayHandlerL(2); // call proper function with logical state flip opcode as parameter } else if (btnVal>=849 &&btnVal <=855){ // btn Airing if (windowAlrt ==1) { // if the system is in Window Alert mode, disable it windowAlrt =0; buzz(4, 3); relayHandlerA(3); } else { // else turn on/off the airing ventilator delay(100); buzz(3, 1); relayHandlerA(2); } } else if (btnVal>=927 &&btnVal <=933){ // btn One Time Heating (15 mins) timed mode delay(100); buzz(3, 1); relayHandlerH(2); } else if (btnVal>=767 &&btnVal <=777) { // btn decrease tTarget delay(100); tTargetHandler(0); } else if (btnVal>=687 &&btnVal <=697) { // btn increase tTarget delay(100); tTargetHandler(1); } else if (btnVal>=856 &&btnVal <=862) { // inc &dec btns at the same time tTarget =14; // <====initial value - press these buttons at the very first powerup! }}void sRX() { // ------------- Receive Serial Data while (sUART.available()> 0) { // if data is available to read for (byte i =0; i <2; i++) { RX[i] =sUART.read(); } } int iRX[2]; for (byte i =0; i <2; i++) { iRX[i] =RX[i] - '0'; } switch (RX[0]) { // ------------ accept SINGLE ALPHABETICAL control codes case 'A':relayHandlerH(1); // 1 =on break; case 'a':relayHandlerH(0); // 0 =off break; // Received serial data can be a single alphabetical letter from "Arduino case 'B':// Bluetooth Control Device" Android app. If a proper alphabetical relayHandlerA(1); // character arrives, the program code will not wait for the second one, break; // but calls the applicable function with a proper operation code. case 'b':// Cases of combined numeric data can be seen below. relayHandlerA(0); pausa; case 'C':relayHandlerL(1); pausa; case 'c':relayHandlerL(0); pausa; case 'D':case 'd':tTarget =21; tTargetEEPROM(); buzz(3, 1); pausa; case 'E':case 'e':tTarget =19; tTargetEEPROM(); buzz(3, 1); pausa; case 'F':case 'f':tTarget =14; tTargetEEPROM(); buzz(3, 1); pausa; case 'R':// call for an overview report about controlled devices case 'r':sTX(8); pausa; case 'W':// disable Window Alert state case 'w':windowAlrt =0; buzz(4, 3); relayHandlerA(3); pausa; } // ----------------------- accept COMBINED NUMERIC control codes // In this case a two-digit numeric control code arrives in char format, // from an Android bluetooth serial app for instance. After a char to integer // conversion (only if the first char is '1' or '2') a merge-process will follow, // and the system of conditions and statements will make a decision and execute it. // Appropriate numeric codes are:// // ---------------- Target Temperature:// 50 - 76 values will be accepted as a target temperature for the thermostat function. // // ---------------- Device Control Codes:// First =device code, Second =operator code // 10, 11, 12 turns the lighting:10=off, 11=on // 12=flip logical state (on -> off / off -> on) // 20, 21, 22 will do the same to the airing ventilator // 30, 31, 32 handles the One Time Heating (15 mins) timed heater program as above // // ---------------- Classified Operator Codes:// X3, X4 are classified, used only for function calls by inner program sequences if (RX[0] =='1') { relayHandlerL(iRX[1]); } if (RX[0] =='2') { relayHandlerA(iRX[1]); } if (RX[0] =='3') { relayHandlerH(iRX[1]); } if ((iRX[0] * 10 + iRX[1] <=76) &&(iRX[0] * 10 + iRX[1]>=50)) { // accept only numeric values between 50 &76 tTarget =iRX[0] * 10 + iRX[1]; // merge two integers and set tTarget tTargetEEPROM(); // after set, call the EEPROM handler function, and buzz(3, 1); // write the tTarget value to the appropriate byte of the EEPROM } if (RX[0] =='0') { // test for (byte i =1; i <5; i++) { buzz(5, 2); } } for (byte i =0; i <2; i++) { // empty all message receiver and conversion variables RX[i] ='Z'; } }void relayHandlerL(byte lOperator) { // Lighting Handler Sequence // operators are:0=off, 1=on, 2=flip the state, 4=fill/refill the lighting state char var. if ((measError) &&((lOperator ==1) || (lOperator ==2))) { sTX(4); Retorna; } if ((lOperator ==2) || (lOperator ==0) &&(lState) || (lOperator ==1) &&(!lState)) { lState =!lState; digitalWrite(relayL, lState); buzz(2, 1); } if (lOperator>=0) { // fill up the working state char with the proper state indicator string if (lState) { lightingState =state_str[0]; } else { lightingState =state_str[1]; } if (!startup) { sTX(7); } }}void relayHandlerA(byte aOperator) { // Airing Handler Sequence if ((measError) &&((aOperator ==1) || (aOperator ==2))) { // operators are:0=off, 1=on, 2=flip the state, sTX(4); // 3=called by temprMeas() funct., 4=fill/refill the airing state char var. Retorna; } aState =digitalRead(relayA); if (!windowAlrt) { if ((aOperator ==2) || (aState) &&(aOperator ==0) || (!aState) &&(aOperator ==1)) { aState =!aState; digitalWrite(relayA, aState); aStateByCmd =digitalRead(relayA); buzz(2, 1); } } if (aOperator ==3) { // called by the temprMeas() function, 'windowAlrt' ended or started if ((!aState) &&(windowAlrt) || (aState) &&(!windowAlrt) &&(!aStateByCmd)) { digitalWrite(relayA, windowAlrt); } } aState =digitalRead(relayA); if (aOperator>=0) { if (aState) { if (windowAlrt) { airingState =state_str[2]; } else { airingState =state_str[0]; } } else { airingState =state_str[1]; } } if (!startup) { sTX(6); }} void relayHandlerH(byte hOperator) { // Heater Handler Sequence // operators are:0=off, 1=on, 2=flip the state, // 3=called by temprMeas() funct., 4=fill/refill the heater state char var. if ((measError) &&((hOperator ==1) || (hOperator ==2))) { sTX(4); Retorna; } if ((!hThermostat) &&(!windowAlrt) &&(!measError)) { // turn on/off the One Time Heating (15 mins) timed mode if ((hOperator ==2) || (hOperator ==1) &&(!hState) || (!hOperator) &&(hState)) { buzz(2, 1); hState =!hState; sftyTmrEnded =0; timer0 =0; digitalWrite(relayH, hState); } } if (windowAlrt) { sTX(3); } if (hOperator ==3) { // this function called by the temprMeas() function (op 3) // in order to examine windowAlrt &measError booleans if ((windowAlrt) &&(hState)) { // a window is open and the heater is running digitalWrite(relayH, 0); buzz(5, 3); } if ((!windowAlrt) &&(!measError)) { if ((hThermostat) || (!hThermostat) &&(hState) &&(sftyTmrEnded)) { digitalWrite(relayH, hThermostat); // proceed the command of the Thermostat Routine } } } hState =digitalRead(relayH); if (hOperator>=0) { if (hState) { if (hThermostat) { heaterState =state_str[2]; } else { heaterState =state_str[0]; } } else { heaterState =state_str[1]; } if ((((!windowAlrt) &&(hOperator !=3)) || (hState)) &&(!startup)) { sTX(5); } }}void safetyTmr () { // Timer for the One Time Heating (15 mins timed) mode if ((hState) &&(!sftyTmrEnded) &&(timer0> sftyTmrInterval) &&(!hThermostat)) { sftyTmrEnded =1; relayHandlerH(0); for (byte i =1; i <5; i++) { buzz(i, 2); } }}void temprTimer() { // Cyclic Timer for temprMeas() unsigned long temprTmrCurr =millis(); if (temprInterval <=temprTmrCurr - temprTmrPrev) { temprTmrPrev =temprTmrCurr; temprMeas(); } }void temprMeas() { // ----------- Temperature Measurement &Comparison Sequence temprPrev =tempr; // save the value for next comparison sensors.requestTemperatures(); // update sensor readings tempr =sensors.getTempFByIndex(0); // read remperature if ((tempr>=104) || (tempr <=32)) { // extreme meas values:if (!errMsgSentBySys) { // -127, -196.60 are HW errors, +85 is tipically SW error, but sTX(4); // can be fire, or a broken window } errMsgSentBySys =1; hThermostat =0; if (hState) { relayHandlerH(0); } if (aState) { relayHandlerA(0); } if (lState) { relayHandlerL(0); } measError =1; for (byte i =1; i <10; i++) { buzz(4, 1); atraso (50); } } else { temprPrev =tempr; measError =0; errMsgSentBySys =0; } if (!measError) { // ------------ Start of Temperature Analysis Sequence if (tempr <=62.6) { // Frequent, short-term switching of the heater gas boiler would cut short its lifetime, the heatCorrVal =0.9; // heatCorrVal value helps to keep avoid it. Declares the degree of overheating and cooling back. } // Lower temperature demands greater heatCorrVal, because the walls are colder and adsorb better the if ((tempr> 62.6) &&(tempr <66.2)) { // warmth from the freshly heated-up air, so the above described effect would more effective. heatCorrVal =0.72; } if (tempr>=66.2) { heatCorrVal =0.54; } if (tTarget - tempr>=heatCorrVal) { // subtract measured value from target, if the difference equals or greater than heatCorrVal sftyTmrEnded =1; // deactivate the One Time Heating (15 mins) timed program if it is running hThermostat =1; // turn on the thermostat buzz(1, 1); } if ((tTarget - tempr <=-1 * heatCorrVal) &&(hThermostat)) { hThermostat =0; } if ((temprPrev - tempr>=0.36) &&(!windowAlrt) &&(tempr <=68)) { // in a measurement cycle and in heating season the temperature windowAlrt =1; // drops, it will evaluate as a window is open sftyTmrEnded =1; for (byte i =1; i <5; i++) { buzz(4, 1); atraso (50); } relayHandlerA(3); // call airing function (opcode =3), to help refresh the air } if ((temprPrev - tempr <=-0.216) &&(windowAlrt)) { // the tempr. falling is over, the air became warmer windowAlrt =0; // due to the heat capacity of the environment, buzz(4, 3); // so switch back to normal mode relayHandlerA(3); } relayHandlerH(3); // the function will examine caller param(3) &windowAlrt &measError booleans if (!windowAlrt) { sTX(1); } }}void tTargetHandler (bool set) { // set the needed tempr by increasing or decreasing if (!set) { // incr if (tTarget <76) { // until it reaches the upper limit tTarget++; buzz(3, 1); } else { buzz(2, 3); } } else { // decr if (tTarget> 50) { tTarget--; buzz(3, 1); } else { buzz(2, 3); } } tTargetEEPROM();}void tTargetEEPROM() { EEPROM.write(addr, tTarget); // after incr/decr/set, write the tTarget value to the appropriate byte of the EEPROM delay(10); sTX(2);}void draw(void) { // logo handler if (frame ==0) { u8g.drawXBMP( 0, 0, 128, 64, frame1); } else if (frame ==1) screenFunctState(); } void screenFunctState(void) { // function state screen temprWriteOut(0, 64); u8g.drawHLine(0, 46, 128); u8g.setFont(u8g_font_unifont); if (!windowAlrt) { u8g.setPrintPos( 0, 14); u8g.print(funct_str[0]); u8g.setPrintPos(84, 14); u8g.print(heaterState); } else { u8g.setPrintPos( 0, 14); u8g.print(funct_str[3]); } u8g.setPrintPos( 0, 28); u8g.print(funct_str[1]); u8g.setPrintPos(88, 28); u8g.print(airingState); u8g.setPrintPos( 0, 42); u8g.print(funct_str[2]); u8g.setPrintPos(95, 42); u8g.print(lightingState); if ((!hState) &&(!aState) &&(!lState)) { screenStndby(); // if all of controlled devices are in off, call standby screen }}void screenStndby() { // standby scr u8g.firstPage(); do { u8g.setFontRefHeightText(); u8g.setFont(u8g_font_unifont); if (!measError) { u8g.setPrintPos(33, 52); u8g.print(funct_str[5]); u8g.setPrintPos( 8, 64); u8g.print(funct_str[6]); } else { u8g.setPrintPos( 4, 48); u8g.print(funct_str[4]); } temprWriteOut(0, 16); } while( u8g.nextPage() );}void temprWriteOut (byte tX, byte tY) { // draw tempr &tTarget variables onto different coordinates u8g.setFont(u8g_font_courB14);//u8g.setFont(u8g_font_6x12); // you can save ~10% of prog.memory using this font with 2x2 scale char buftTarget[9]; sprintf (buftTarget, "%d", tTarget); // int to char//u8g.setScale2x2();//tY =tY / 2; u8g.setPrintPos(tX, tY); u8g.print(buftTarget); u8g.setPrintPos(tX+18, tY); u8g.print(funct_str[9]); u8g.setPrintPos(tX+50, tY); u8g.print(tempr); //u8g.print(char(176)); u8g.print("F");//u8g.undoScale();}void clrScr(){ u8g.firstPage(); do { } while( u8g.nextPage() );}void ledHandler() { // the brightness of a led is low, if the indicated device is off, and high, if its on if (aState) { analogWrite(ledA, bright[2]); } else { analogWrite(ledA, bright[1]); } if (lState) { analogWrite(ledL, bright[2]); } else { analogWrite(ledL, bright[1]); } if (hState) { if (!hThermostat) { ledBlnk(); // the heater led blinks when the One Time Heating (15 mins) timed mode is activated, } else { brightHeat =bright[2]; // and constant bright, if the thermostat routine is active } } else { brightHeat =bright[1]; } analogWrite(ledH, brightHeat);}void ledBlnk() { unsigned long curr =millis(); if (ledInterval <=curr - prev) { // subtract prev value from current, if the difference equals or greater than ledInterval const. prev =curr; // overwrite the earlier value with the current and flip brightness level if (brightHeat ==bright[1]) { brightHeat =bright[2]; } else { brightHeat =bright[1]; } } analogWrite(ledH, brightHeat);}void buzz(byte b, byte d) { // call with frequency and delay parameters tone(buzzer, b * 1000); delay(d * 100); noTone(buzzer);}void sTX(byte reportTX) { // sending serial reports switch (reportTX) { case 0:for (byte i =0; i <9; i++) { sUART.print(funct_str[10]); } sUART.println(funct_str[10]); pausa; case 1:sUART.print(funct_str[8]); // Tempr. sUART.print(tempr); //sUART.print(char(176)); sUART.println("F"); pausa; case 2:sUART.print(funct_str[7]); // TTemp sUART.print(tTarget); //sUART.print(char(176)); sUART.println("F"); pausa; case 3:sUART.print(funct_str[3]); // Window Alert sUART.print(funct_str[9]); sUART.print(tempr); //sUART.print(char(176)); sUART.println("F"); pausa; case 4:sUART.println(funct_str[4]); // Error report break; case 5:sUART.print(funct_str[0]); // Working state of devices sUART.println(heaterState); pausa; case 6:sUART.print(funct_str[1]); sUART.println(airingState); pausa; case 7:sUART.print(funct_str[2]); sUART.println(lightingState); pausa; case 8:// Overview report sTX(0); relayHandlerH(4); relayHandlerA(4); relayHandlerL(4); sTX(2); if (measError) { sTX(4); } pausa; }} 

Esquemas

For jumper wire test... You have to solder it

Processo de manufatura

  1. Controle de acesso com QR, RFID e verificação de temperatura
  2. Controle remoto universal usando Arduino, 1Sheeld e Android
  3. Aceitar moeda de controle com Arduino
  4. Sistema de rega automática de plantas com Arduino
  5. Arduino com Bluetooth para controlar um LED!
  6. Sapatos inteligentes (com laço automático e geração de eletricidade)
  7. Arduino Nano:Controle 2 motores de passo com joystick
  8. Controle do Servo Motor com Arduino e MPU6050
  9. Dispositivos Bluetooth controlados por voz com OK Google
  10. Controle do carro com Arduino Uno e Bluetooth