Automatizar determinadas tarefas simples do dia a dia pode ser bem vantajoso. E uma coisa que fazemos diariamente é acender e apagar a luz do quarto por exemplo. Seria muito melhor se isto fosse feito automaticamente, certo?
Tendo em vista esse pensamento, neste post, veremos como projetar um sistema para controlar a luz de um cômodo automaticamente.
A versão 2 deste projeto pode ser acessada aqui. Ela está bem mais profissional, então recomendo vê-la.
Discutindo a ideia
Obs.: Este projeto demanda tempo e não e nada simples , então leia o post com calma para entender tudo. Eu levei 3 dias para conseguir terminá-lo (gastando diversas horas em cada dia).
Objetivo e características
O objetivo do projeto é acender a luz de um cômodo automaticamente. Mas a ideia é ampla e ainda é preciso definir algumas especificações, como o que será levado em conta para acender ou apagar a luz.
Bem, a forma que pensei para fazer o sistema é considerar o número de pessoas dentro do ambiente. Se houver no mínimo uma pessoa, ele acende a luz. Senão, a luz é apagada.
Além disso, é interessante que o sistema só acenda a luz caso o cômodo esteja escuro. E, caso ele esteja bem iluminado, a luz deve permanecer apagada mesmo que haja uma pessoa dentro dele.
Essa definição de “escuro” e “bem iluminado” vai depender da sua necessidade, do quanto de luz você considera suficiente para o ambiente estar “bem iluminado”. Portanto, este será um parâmetro ajustável.
Detecção de pessoas no cômodo
Em relação à necessidade de reconhecer quantas pessoas entraram no cômodo, ela pode ser feita de algumas formas diferentes. Entretanto, a forma que escolhi é colocar dois sensores de obstáculo perto da porta. Esta é a forma que considero a mais barata, a mais fácil de implementar e que garante melhores resultados.
A ideia central é que o sensor de obstáculo seja capaz de informar se algo passou na frente dele. Como ele ficará próximo à porta, ele indicará se alguém passou pela porta (entrou ou saiu).
E, para identificar se a pessoa saiu ou entrou, basta utilizar dois sensores de obstáculos, um próximo ao outro. Quando alguém entrar no cômodo, o sensor que está mais perto da entrada vai detectar primeiro que o outro sensor. Com isto, o sistema é capaz de saber que a pessoa entrou.
E a mesma lógica se aplica ao sentido contrário. Se a pessoa está saindo, o sensor mais afastado da entrada vai detectar primeiro que o outro sensor.
Veja a imagem abaixo para entender (não se preocupe em saber o que é o sensor de obstáculo por enquanto).
Detecção da iluminação
Por fim, precisamos pensar em como detectar se o ambiente está escuro ou bem iluminado. Para isto, bastará utilizar um sensor de intensidade luminosa.
E, a partir deste sensor, regularemos o nível adequado que o sistema considerará o ambiente como escuro. Mais adiante veremos como isto será feito.
Implementação
Circuito
Sensor de obstáculo
Para fazer o sensor de obstáculo, resolvi utilizar um sensor ultrassônico. Pode parecer um pouco contra-intuitivo fazer isto, mas vamos entender os porquês:
O sensor de obstáculo comumente encontrado é o infravermelho. Mas o sensor infravermelho tem a desvantagem de sofrer interferência da radiação infravermelha do ambiente. Isso impossibilita ele de ser utilizado durante o dia, já que seria capaz de detectar obstáculos apenas em distâncias muito pequenas quando está sofrendo interferência da radiação infravermelha solar.
Portanto, outro sensor que pode substituí-lo é o ultrassônico. E basta seguir o mesmo princípio do sensor de obstáculo infravermelho: se o sensor ultrassônico detectou uma distância menor que um certo valor, ele informa que há um obstáculo em sua frente.
Um detalhe a ser adicionado é que utilizarei o sensor ultrassônico HC-SR04, que utiliza um pino para iniciar a medição e outro para leitura da distância. E, adiantando um pouco o desenvolvimento, irei utilizar o microcontrolador ATtiny85, que possui poucos pinos.
A quantidade de pinos dele será insuficiente para ligar os dois pinos do sensor ultrassônico em dois pinos separados do microcontrolador. Portanto, terei que interligar os pinos do sensor ultrassônico e lidar com a leitura de forma diferente na programação. Desta forma, os dois sensores vão precisar de 1 pino cada, o que deixa livre 4 pinos do ATtiny85.
Adiantando: a leitura será feita da igual ocorre no sensor da Parallax, que utiliza apenas um pino para todo o processo de leitura da distância.
Detecção da iluminação
Para a parte de detectar se o ambiente está escuro ou não, basta utilizar um LDR, que é um sensor de intensidade luminosa. Para ter leituras significativas do LDR, utilizaremos ele em um divisor de tensão:
Antes de seguir com o projeto, é importante montar o circuito acima para conseguirmos obter qual é o valor lido pelo LDR que informará se o ambiente está escuro ou bem iluminado.
Para isto, com o circuito acima, basta fazer um programa para ler a porta analógica A0 e exibir seu valor no monitor serial. Caso você tenha dificuldade nesta parte, recomendo ler o post sobre leitura analógica.
Com o circuito montado e a programação funcionando, basta colocar o LDR no local onde o sistema ficará e verificar o valor lido. No meu caso, analisei os valores com a janela fechada (quarto escuro) durante o dia e durante a noite. E, em ambos os casos, o quarto estava escuro (em minha concepção) para valores menores que 8.
Acendimento da lâmpada
Para acender a lâmpada, será necessário criar um circuito com transistor e relé. Não pretendo entrar nos detalhes deste circuito aqui, pois existe um post inteiramente dedicado à isto.
Botão de emergência
Caso ocorra algum erro com os sensores, resolvi adicionar um botão ao circuito para acender a lâmpada independente das condições do ambiente. É como se fosse um botão de emergência, que acenderá a lâmpada não importa o que aconteça.
Fonte externa
Para alimentar o circuito todo (sensores e microcontrolador) é necessário uma fonte externa de 5v. A solução que encontrei foi pegar uma fonte de 5v, parecida com as fontes de carregar celular, e desmontar a carcaça dela. Veja imagem abaixo da fonte desmontada (fiz uma pequena caixinha para ela – mais detalhes disso no fim do post).
A entrada desta fonte (fase e neutro indicado pelo número 3 da imagem) serão conectados atrás do interruptor da luz. Para isso, tive que passar uma fase e um neutro até a parte de trás do interruptor. Ambos vieram da conexão da tomada que fica “embaixo” do interruptor, como mostra a imagem abaixo.
O desenho em amarelo mostra o caminho do eletroduto que sai da tomada e vai ao interruptor.
Na imagem da fonte, o número 1 era um LED que havia na placa que decidi remover, já que a fonte ficará escondida. E, onde está indicado pelo número 2, havia um conector USB, que decidi remover também, pois não será utilizado.
Dentro da indicação do número 2, há dois pontos marcados por circunferências, que são os dois pontos onde soldei fios para ligar o 5v do circuito. No seu caso, você pode ligar a fonte e medir a saída com o multímetro para saber onde soldar os fios do 5v.
Isso tudo que fiz acima pode ser evitado se você não desmontar a fonte externa e ligá-la direto na tomada. Mas lembrando de soldar dois fios na saída dela para alimentar o circuito. Decidi fazer os passos acima para tentar deixar a fonte o escondida.
Esquemático
Conforme disse, para este projeto, resolvi utilizar o microcontrolador ATtiny85. Você pode escolher qualquer outro microcontrolador, desde que a quantidade de pinos dele seja maior ou igual a do ATtiny85. Resolvi escolhe-lo, pois ele é compacto e relativamente fácil de achar para comprar.
Veja o esquemático do circuito abaixo. Gaste um tempo para analisar o circuito com calma e entender cada parte. E releia os tópicos acima para entender o que é cada elemento.
Os pinos do sensor ultrassônico se referem ao pino Trig e Echo que foram interligados. Veja imagem abaixo para entender.
O “Sensor Saindo” é o pino do sensor ultrassônico mais afastado da entrada. E o “Sensor Entrando” é o pino do sensor mais próximo à entrada do cômodo.
O esquemático pode ser seguido sem problemas, você só deve modificar o circuito do relé, pois o seu relé pode ser diferente do meu. Portanto, não deixe de ver este post para saber calcular o resistor de base do transistor.
Ligação do relé com a lâmpada
No esquemático anterior, ficou faltando falar sobre como o relé é interligado à lâmpada. Como esta é uma parte importante, resolvi colocá-la separadamente.
A ligação basicamente vai obedecer a ligação do seu interruptor. Quando você abrir a tampa do interruptor, irá se deparar com o “circuito da lâmpada”.
Se a sua lâmpada for comandada por apenas um apagador, o interruptor estará com apenas dois fios ligados. Para este caso, basta ligar um dos fios no terminal central do relé e outro na extremidade normalmente aberta do relé. Para descobrir qual é a extremidade normalmente aberta, faça um teste de continuidade.
Veja a ligação abaixo:
Agora, se sua lâmpada for comandada por mais de um apagador (three way), o interruptor estará com 3 fios ligados a ele. Neste caso, é só ligar os 3 fios, um em cada terminal do relé. Veja imagem abaixo:
Pode ser que, para o caso acima, quando o sistema for acender a luz, ela na verdade se apague e vice-versa. Se isto ocorrer, basta ir no outro interruptor (o que você não mexeu) e trocar o estado dele. Assim, a lógica do acendimento da lâmpada ficará normal.
Opcional
Uma etapa opcional do circuito que você pode fazer é:
Depois da etapa anterior, não deve ter nada mais conectado ao interruptor. Portanto, você pode utilizar o interruptor para ligar/desligar o sistema. Isto é feito passando a fase (ou o neutro) da fonte externa pelo interruptor.
Sendo assim, se o interruptor estiver desligado, a fase (ou o neutro) é interrompida e a fonte deixa de alimentar o circuito. E, caso contrário, a fase alimenta a fonte e ela alimenta o circuito.
Decidi fazer isto para adicionar uma forma de resetar o microcontrolador, embora não seja a forma mais ideal. Com isso, caso ocorra algum erro na programação, basta desligar o interruptor. E, se o cômodo não for ser utilizado por um tempo, também é bom deixar o sistema desligado.
Programação
A programação será feita com a IDE do Arduino e depois os códigos serão carregados no ATtiny.
Programando o ATtiny
Uma etapa importante da programação é saber como programar o ATtiny. Não pretendo explicar como isto é feito neste post, pois já existe um post exclusivo para esta finalidade.
Lendo os sensores ultrassônicos
Como estamos interligando os pinos do sensor ultrassônico, temos que adaptar o código para fazer a leitura corretamente. Acaba que é só fazer todas as etapas da leitura com um único pino.
Para ler sobre como fazer o procedimento de leitura do sensor ultrassônico, veja este post.
Além da leitura, temos que verificar se a distância medida é menor do que um certo valor para, então, sinalizar 1 ao programa, conforme a lógica do sensor de obstáculo.
Após alguns testes que fiz, constatei que uma distância menor que 50cm é ideal para considerar que há um objeto na frente do sensor. Isto pode variar de caso para caso, já que nem toda entrada de um cômodo é igual.
Outra distância importante é quando algo está encostando no sensor (na sua frente). Quando isto ocorre, o sensor retorna uma distância muito grande (maior que 200cm pelos meus testes). Portanto, considerei que distâncias maiores que 200cm também indicam obstáculos na frente do sensor. Isso não é um problema, porque a parede que fica na frente do sensor (quando não há nada em sua frente) está a ~130cm dele.
E adicionei um parâmetro da distância ser diferente de 0cm. Isso para o caso em que o sensor não deu resposta (possivelmente algum erro de conexão).
Por fim, englobei essa lógica toda em uma função, que pode ser vista no tópico adiante.
Código de leitura dos sensores
Leia os comentários para entender o código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* * Informa se o sensor especificado detectou algum obstáculo. * Parâmetros: * sensor: pino do sensor que deve ser lido * Retorna: 1 se detectou obstáculo e 0 se não. */ bool leitura_sensor(char sensor) { // Inicia a leitura mandando um pulso de 10uS pinMode(sensor, OUTPUT); digitalWrite(sensor, HIGH); delayMicroseconds(10); digitalWrite(sensor, LOW); // Lê o sinal de resposta e converte para distância pinMode(sensor, INPUT); float dist = pulseIn(sensor, HIGH); dist = dist * 0.034 / 2.0; // Verifica se há um obstáculo na frente do sensor if (dist != 0 && (dist < 50 || dist > 200)) return true; else return false; } |
Lógica do código
Não pretendo explicar qual foi a lógica que utilizei, pois é possível entender o código pelos comentários e, também, porque existem diferentes formas de se criar a programação do sistema.
Mas, saiba que fiz a lógica me baseando na imagem que mostrei no início do post (a imagem abaixo).
É basicamente uma máquina de estados. E, no código, criei variáveis para o programa saber em qual estado ele se encontra (entrando1, entrando2, saindo1, saindo2).
O que pode causar mais confusão talvez sejam as variáveis de tempo que criei (tempoE, tempoS e tempoL). As duas primeiras são uteis no seguinte:
Se alguém entrou no primeiro sensor e resolveu voltar, deve haver um tempo limite para indicar que a pessoa desistiu de entrar. A tempoE monitora o tempo limite de entrada e a tempoS monitora o tempo limite de sáida.
Já a variável tempoL serve para monitorar um tempo de 5 segundos quando LDR detectar que escureceu. Isso é feito, porque pode passar uma sombra na frente do LDR, o que não quer dizer que escureceu. Portanto, é necessário que ele detecte que o ambiente está escuro por 5 segundos até que o sistema decida ligar a lâmpada.
Código completo
O código está bem comentado, então leia ele com calma para entender cada etapa. Ele poderia ter sido melhorado significativamente se eu tivesse usado a estrutura switch case para avaliar os estados do programa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | // Definições do programa #define rele 0 // Pino para ligar/desligar o relé #define entrada 1 // Sensor mais perto da porta #define saida 2 // Sensor mais longe da porta #define botao 3 // Botão para ligar a luz manualmente #define ldr A2 // Pino ligado ao divisor de tensao LDR + Resistencia // Macro para facilitar a leitura do LDR #define leituraLDR analogRead(ldr) // Variaveis do programa: bool entrando1 = false; // Indica que a pessoa está entrando e passou do primeiro sensor bool entrando2 = false; // Indica que a pessoa está entrando e passou do segundo sensor bool saindo1 = false; // Indica que a pessoa esta saiando e passou do segundo sensor (1º da saida) bool saindo2 = false; // Indica que a pessoa esta saiando e passou do primeiro sensor (2º da saida) bool escureceu = false; // Indica se está escuro ou nao bool acende = false; // Indica se a lampada deve ser acionada ou nao int contagem = 0; // Contar quantas pessoas tem no quarto unsigned long tempoE = 0; // Tempo de espera para aceitar se a pessoa esta entrando ou nao unsigned long tempoS = 0; // Tempo de espera para aceitar se a pessoa esta saindo ou nao unsigned long tempoL = 0; // Tempo de espera para aceitar se escureceu (tempoldr) // Funções void verifica_tempoS(void); // Manipula as variaveis de tempo bool leitura_sensor(char sensor); // Indica se alguém passou na frente do sensor ultrassônico void setup() { // Configura os pinos pinMode(rele, OUTPUT); pinMode(botao, INPUT_PULLUP); pinMode(ldr, INPUT); digitalWrite(rele, LOW); } void loop() { // Verifica se os sensores detectaram algo bool leituraE = leitura_sensor(entrada); bool leituraS = leitura_sensor(saida); // Logica da pessoa entrando if (leituraE && !leituraS && !saindo1) { // Condiçao da pessoa estar entrando (nao esta saindo e leituraE é true) entrando1 = true; tempoE = millis(); } if (!leituraE && leituraS && entrando1 ) { // Condiçao para a pessoa estar entrando no meio do caminho entrando2 = true; tempoE = millis(); } if (leituraE && !leituraS && entrando2){ // Condição para a pessoa desistir de entrar e voltar entrando2 = false; tempoE = millis(); } if (!leituraE && !leituraS && entrando2) { //Condiçao para a pessoa ter entrado (nenhum sensor le nada) contagem++; entrando1 = false; entrando2 = false; delay(500); // Delay para nao duplicar a leitura) } // Logica da pessoa saindo if (leituraS && !leituraE && !entrando1) { //Condiçao da pessoa estar saindo (nao esta entrando e leituraS é true) saindo1 = true; tempoS = millis(); } if (!leituraS && leituraE && saindo1) { //Condiçao para a pessoa estar entrando no meio do caminho saindo2 = true; tempoS = millis(); } if (!leituraE && leituraS && saindo2){ // Condição para a pessoa desistir de sair e voltar saindo2 = false; tempoS = millis(); } if (!leituraS && !leituraE && saindo2) { //Condiçao para a pessoa ter saido (nenhum sensor le nada) if (contagem > 0) { //So diminui se tiver alguem dentro do quarto contagem--; } saindo1 = false; saindo2 = false; delay(500); //delay para nao duplicar a leitura } // Logica da pessoa parada no meio do caminho if (leituraE && leituraS) { //Condiçao para a pessoa estar parada no meio do caminho if (entrando1 || entrando2) { tempoE = millis(); } if (saindo1 || saindo2) { tempoS = millis(); } } // Manipula os tempos verifica_tempos(); // Logica do acendimento da lampada if (leituraLDR < 8) { //se o ldr indicou que escureceu if (!escureceu){ escureceu = true; tempoL = millis(); // tempo para saber se nao foi apenas uma sombra } } else { //se o ldr indicou que esta claro escureceu = false; } if(digitalRead(botao)){ // Se o botão está desligado, funciona normalmente if (contagem >= 1 && acende) { digitalWrite(rele, HIGH); } else { digitalWrite(rele, LOW); acende = false; } }else{ // Senão, apenas acende o relé digitalWrite(rele, HIGH); } } /* * Verifica se os intervalos limites de tempo de entrada e saída foram ultrapassados para reiniciar as variáveis * Verifica se o LDR ficou escuro por no mínimo 5 segundos */ void verifica_tempos(void) { // Entrada if (millis() - tempoE >= 500) { entrando1 = false; entrando2 = false; } // Saida if (millis() - tempoS >= 500) { saindo1 = false; saindo2 = false; } // Espera 5 segundos para saber se está de fato escuro ou se foi uma sombra que passou no sensor if (escureceu && millis() - tempoL >= 5000) { acende = true; } } /* Informa se o sensor especificado detectou algum obstáculo. * Parâmetros: * sensor: pino do sensor que deve ser lido * Retorna: 1 se detectou obstáculo e 0 se não. */ bool leitura_sensor(char sensor) { // Inicia a leitura mandando um pulso de 10uS pinMode(sensor, OUTPUT); digitalWrite(sensor, HIGH); delayMicroseconds(10); digitalWrite(sensor, LOW); // Lê o sinal de resposta e converte para distância pinMode(sensor, INPUT); float dist = pulseIn(sensor, HIGH); dist = dist * 0.034 / 2.0; // Verifica se há um objeto na frente do sensor if (dist != 0 && (dist < 50 || dist > 200)) return true; else return false; } |
Montagem estrutural
Depois de programar o ATtiny e criar uma plaquinha, seja ela uma PCI ou uma placa ilhada (meu caso), é necessário fazer uma estrutura para que os sensores fiquem parados direcionados para a porta.
A solução que optei foi desenhar uma caixa com as corretas dimensões dos sensores e imprimi-la com uma impressora 3D. Como não tenho muita experiência com esta parte estrutural, acabou que a caixa que fiz não ficou muito adequada.
Aqui está o link para download dos arquivos de impressão. Comecei desenhando a caixa principal na escala errada (cm), por isso o desenho possui uma mudança de escala, para converter para mm.
Acabei não imprimindo a caixa depois de ter feitos alguns ajustes no desenho. Então, tive que fazer algumas adaptações na caixa impressa.
Circuito principal e sensores
Essa caixa serve para colocar os sensores (ultrassônico, LDR) e o circuito principal, incluindo o botão. Veja a imagem do desenho abaixo.
A imagem acima mostra a parte da frente da caixa, onde os sensores ultrassônicos devem ser posicionados. O ponto 1 é o furo onde deve ser encaixado o LDR. E o furo 2 é onde deve ser passado o botão.
É necessário alterar as dimensões do desenho para as dimensões do seu botão e do seu circuito principal.
Por fim, a imagem a seguir mostra o espaço onde o circuito deve ser colocado, que é a parte de trás da caixa.
E não há nenhum elemento na caixa que permita que ela seja parafusada. Isto porque, projetei ela considerando que ia fixar utilizando fita dupla face (daquelas que aguentam vários quilos). Portanto, utilize o arquivo para adicionar algum elemento para atender sua necessidade.
Fonte externa
Como disse anteriormente, para fazer a fonte externa, desmontei uma fonte de 5v e removi alguns componentes. E, para não deixar ela sem proteção, fiz uma caixa para ela.
As imagens da caixa e da tampa estão mostradas abaixo. Pode ser que a tampa não fique fixada na caixa, então use uma fita para prender os dois.
Resultados
Cheguei a gastar 3 dias para fazer o sistema. Apesar de todo o trabalho, digo que valeu muito a pena, pois o sistema funciona muito bem e é prazeroso ver a luz acendendo e apagando sozinha.
As fotos da minha montagem podem ser vistas na sequência. Repare que o botão e o LDR estão na parte de cima da caixa principal. Isto porque, foi a primeira versão da caixa.
O bom de ter essa abertura na parte de trás da caixa principal é que fica fácil acessar o circuito do sistema e retirar o ATtiny para fazer alguma modificação na programação.
Olá poderia me da uma luz, quero fazer um quarto automatizado, onde quando eu entro uma lampada normal acende, quando eu sair do quarto, essa lampada apaga, uma lampada azul acende fica por 15 segundos e apaga, porém se eu entrar no quarto de novo, antes da lampada azul apagar (passar os 15 segundos) ela tem que apagar imediatamente e a lampada normal acender.
Tentei usar delay() porém mesmo eu entrando no quarto ela continua acesa.
Olá, Johny. Não sei se o trocadilho foi intencional, mas foi bom haha. Bem, é difícil dizer ao certo qual é o problema sem analisar o seu código, mas acredito que o delay esteja “congelando” o programa e impedindo ele de verificar se a pessoa entrou de novo no quarto. Para resolver este problema, você pode seguir a abordagem deste post. Se surgir alguma dúvida no processo, me mande um e-mail, que por lá fica mais fácil de mandar arquivos e entender o problema corretamente: mundoprojetado@gmail.com
bom dia, estou tentando programar com o arduino porem nao estou conseguindo vc poderia me dar uma ajuda para programar isso com a placa arduino uno
Bom dia, Sergio. Posso sim. Qual problema está ocorrendo?