Manual

do

Maker

.

com

Sensor de toque para acender lâmpadas

Sensor de toque para acender lâmpadas

Já há alguns anos que eu acho arcaico a utilização de interruptores para acender lâmpadas. Um dispositivo funcional, mas analógico, sem vida, feio. E pra achar no escuro? Se não for fluorescente ou não tiver uma luzinha, é difícil. E ainda mais difícil se for igual a do meu banheiro, que é preta e não tem janelas (porque há um exaustor de teto). Bem, consegui enfim uma razão para fazer o projeto com sensor de toque capacitivo e substituir os interruptores, mas "acho" que pode não ser viável para todas as casas.

Sensor de toque capacitivo

sensor_de_toque-destaque-300x175.webp

Dá pra fazer sensor capacitivo apenas com 2 pinos do Arduino e um resistor de entrada e um de saída, mas aí o coil tem que ficar exposto. Então optei por uma solução mais "cara". Um minúsculo sensor capacitivo que tem uma boa sensibilidade sem contato.

O sensor é simples, você encontra fácil no mercado livre. Para interagir com ele, basta conectá-lo ao GND e VCC, então conectar o pino de saída a um pino analógico da sua MCU. Na leitura, basta ver qual é o valor médio retornado ao contato com o espelho (que será de acrílico e substituirá o tradicional espelho e interruptor). Tendo esse valor, é só trocar o limítrofe no define.

Relé

"Alguém vai ter que fechar o circuito para acender a lâmpada, hum? Por isso que acho que não servirá para qualquer casa, pois eu estou pegando o fio do conduite que vai para a tomada e alimentando a microcontroladora com ele. Quando acontece a "interrupção" do sensor de toque, o estado do relé será modificado para seu estado oposto, fazendo assim com que a lâmpada seja ligada ou desligada.

PCF8574

Só um acrílico fumê não seria nada bonito, certo? Ainda mais que só pioraria a situação de acender a lâmpada no escuro. Por isso eu fiz um conjunto de LEDs pulsantes, esmaecendo gradativamente. Desse modo, será fácil encontrar esse moderno interruptor no escuro.

Quando o interruptor é tocado e o sensor de toque enviar um sinal, uma função extra fará com que os LEDs circulem por um período, evitando assim interrupções consecutivas sem causar a impressão de que o processo está travado; é um feedback para o usuário.

Utilizei o PCF8574 para fazer as animações do LED. Infelizmente eu inverti a ordem pretendida e o PCF8574 está alimentando os LEDs invés de aterrá-los, que acredito ser o ideal, mas de qualquer modo, a prova de conceito está funcional e vou implementá-la em um projeto de home automation que estou fazendo. Quando finalizar (daqui a alguns mêses) mostro a casa toda como ficou.

Prova de conceito

interruptor-300x225.webp

Eu nem ia escrever artigo a respeito antes de toda a casa pronta, mas achei que valia a pena. Como não tinha intenção de escrever artigo, não caprichei na prova de conceito. Os LEDs foram presos a um pedaço de papelão e fixados com cola quente. Como não tenho o espelho de acrílico agora (vamos mandar cortar sob medida), utilizei um material que nem sei o nome, só pra testar o esmaecimento dos LEDs. O sensor de toque ficará no meio dos LEDs e o alinhamento correto será feito com uma placa de protótipo, então, não reparem a feiura agora e tenham em mente que é uma prova de conceito, nada mais além disso.

Ainda não defini a MCU, para o teste eu utilizei um Arduino Nano (o que aparece na imagem.

Código

O código para esse projeto (ainda sem a implementação do relay) é esse abaixo. Utilizei a biblioteca TimerOne para gerar um timer sem interromper o fluxo principal do código. O PCF controla a animação dos LEDs através dos estados escritos em cada um dos pinos. A função chamada pela TimerOne não tem loop, só algumas condicionais para tratar o incremento e o decremento  do PWM. A função de acendimento circular dos LEDs trava o fluxo, e é o pretendido para dar tempo do usuário afastar o dedo do interruptor sem gerar uma nova interrupção na leitura do sensor de toque.

#include <Wire.h>
#include <TimerOne.h>

#define PCF_ADDR 0x24
#define SMOOTH_UP   true
#define SMOOTH_DOWN false
#define SMOOTH_PIN 3
#define LIMIT 500

volatile int smooth = 0;
bool goUp = SMOOTH_UP;

byte leds[8] = {1, 2, 4, 8, 16, 32, 64, 128};

void getsOn() {

}
//TODO: adicionar 1 volta incrementando os bits para ON
void smoothing() {
  if (goUp) {
    if (smooth < 255) {
      smooth++;
    }
    else {
      goUp = SMOOTH_DOWN;
    }
  }
  else {
    if (smooth > 0) {
      smooth--;
    }
    else {
      goUp = SMOOTH_UP;
    }
  }
  analogWrite(SMOOTH_PIN, smooth);

}

void circle() {
  Timer1.detachInterrupt();
  for (byte i = 0; i < 3; i++) {
    for (byte pos = 0; pos < 8; pos++) {
      Wire.begin();
      Wire.beginTransmission(PCF_ADDR);
      Wire.write(leds[pos]);
      Wire.endTransmission();
      delay(50);
    }
  }
  Wire.begin();
  Wire.beginTransmission(PCF_ADDR);
  Wire.write(0b11111111);
  Wire.endTransmission();
  Timer1.attachInterrupt(smoothing);
}
void setup() {
  pinMode(SMOOTH_PIN, OUTPUT);
  digitalWrite(SMOOTH_PIN, LOW);
  Wire.begin();
  Wire.beginTransmission(PCF_ADDR);
  Wire.write(0b11111111);
  Wire.endTransmission();
  Timer1.initialize(5000);
  Timer1.attachInterrupt(smoothing);
}

void loop() {
  int val = analogRead(0);
  if (val > LIMIT) {
    circle();
    delay(500);
  }
  delay(100);

}

Video

Não tenho dúvidas que esse é o pior video do canal DobitAoByteBrasil até hoje, mas não poderia deixar de mostrar o resultado (lembre-se: prova de conceito). O video não está listado no canal, por isso coloquei o link diretamente para ele aqui.

https://youtu.be/GnNWWVnzefo

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.