Interruptor para até 8 lampadas - Versão 2 Alpha [Versão Alpha 2.1 disponível]
Qua Out 31, 2018 10:48 am
Este interruptor serve para 1 ou até 8 lampada. A questão de servir para até 8 lampadas é que o hardware (componentes eletrônicos utilizados) permite até 8 conexões para os reles, é possível adicionar mais se necessário, mas seria um caso bem particular controlar mais do que três luminárias por ambiente, geralmente temos no máximo 3 interruptores.
O código do interruptor segue abaixo, e para o próximo mês pretendo colocar todo o esquema elétrico. Não estou postando frequentemente pois estou em semanas de provas.
Nota: A parte que faz a checagem do estado do interruptor ainda esta sendo desenvolvida, portanto não esta funcionando adequadamente.
Podem conferir o funcionamento neste vídeo
aqui também, desta vez usando interruptor em paralelo e conexão 3G
O código do interruptor segue abaixo, e para o próximo mês pretendo colocar todo o esquema elétrico. Não estou postando frequentemente pois estou em semanas de provas.
Nota: A parte que faz a checagem do estado do interruptor ainda esta sendo desenvolvida, portanto não esta funcionando adequadamente.
- Código:
//----------------------------------------------------------- BIBLIOTECAS ----- ||
#include <ESP8266WiFi.h> //lib do wifi para o ESP8266
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h> //lib do ArduinoOTA
#include <PubSubClient.h>
//#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <Ticker.h>// Watcdog bibl
//---------------------------------------- IP FIXO TELNET ----------------------||
IPAddress ip(192,168,0,XXXX);
IPAddress geteway(192,168,0,XXX);
IPAddress subnet(255,255,255,0);
/*
WiFiServer TelnetServer(23);
WiFiClient Telnet;
void handleTelnet(){
if(TelnetServer.hasClient()){
//Cliente esta conectado
if(!Telnet || !Telnet.connected()){
if(Telnet) Telnet.stop();
Telnet = TelnetServer.available();
}else{
TelnetServer.available().stop();
}
}
}*/
// ---------------------------------------------------------------------- MQTT --------------- ||
#define MQTT_AUTH true //Ativa a autenticação
#define MQTT_USERNAME "XXXXXXXXXXXXX" // Login do MQTT
#define MQTT_PASSWORD "XXXXXXXXXXXXX" // Senha do MQTT
#define RELAY 4 //D2
const String HOSTNAME = "Luz Quarto"; // Nome do dispositivo, este nome tambem é utilizado apra criar o Access Point para configuração
const char * MQTT_STATE_TOPIC = "casa/quarto/luz/state"; //Topico onde o dispositivo publica (por exemplo o estado da lâmpada ON ou OFF)
const char * MQTT_COMMAND_TOPIC = "casa/quarto/luz/set"; //Topico onde o dispositivo subscreve (por exemplo controlar uma lâmpada)
const char* servidorMQTT = "192.168.0.XXXXXXXXXXXXXX"; //IP ou DNS do servidor, neste caso do HassIO
// ------------------------------------------------------------------- WIFI ------------------------||
const char* ssid = "XXXXXXXXXXXXXXXX"; //nome da rede
const char* password = "XXXXXXXXXXXXXXXXXXXX"; //senha da rede
WiFiClient wclient;
PubSubClient client(servidorMQTT,1883,wclient);
//------------------------------- Multiplexer -------------------- ||
int MUXPinS0 = D3;
int MUXPinS1 = D4;
int MUXPinS2 = D5;
int MUXPinS3 = D6;
//---------------------------------------------------------------------------------------- Botão, multiportas
#define pinSH_CP D0 //Pino Clock
#define pinST_CP D1 //Pino Latch
#define pinDS D2 //Pino Data
#define qtdeCI 1
void ci74HC595Write(byte pino, bool estado);
int pinLDR = 0; //luz apagada valor baixo, luz acesa valor alto
int C1 = 0;
int X = 0;
bool estadoluz;
//---------------------------------------------------
#define quantidadeBotao 5
struct Rele{
char nome[20];
const char * ONs =""; //Estado do botão ligado para o MQTT
const char * OFFs = "";//Estado do botão desligado para o MQTT
int Pino;
bool Estado; // Estado do botão ligado/desligado para o programa no ESP
unsigned long Delay;
};
struct Rele Botao[quantidadeBotao];
//----------------------------------------------------------------
unsigned long delayLed;
unsigned long delayLamp = 0;
int temporizador = 0;
int tam = 0; //tamanho da mensagem mqtt.
//============================================================================================================================
// ------------------------------------------------< VOID SETUP >-------------------------------------------------------------
//============================================================================================================================
void setup(){
Serial.begin(115200);
pinMode(pinSH_CP, OUTPUT);
pinMode(pinST_CP, OUTPUT);
pinMode(pinDS, OUTPUT);
WiFiManager wifiManager;
pinMode(RELAY,OUTPUT);
//wifiManager.resetSettings(); //Limpa a configuração anterior do Wi-Fi SSID e Password, procedimento, 1º descomentar a linha, 2º Fazer Upload do código para o ESP e deixar o ESP arrancar, 3º Voltar a comentar a linha e enviar novamente o código para o ESP
/*define o tempo limite até o portal de configuração ficar novamente inátivo,
útil para quando alteramos a password do AP*/
wifiManager.setTimeout(180);
wifiManager.autoConnect(HOSTNAME.c_str());
client.setCallback(callback); //Registo da função que vai responder ás mensagens vindos do MQTT
//-------------------------------- DEMUX - 16CANAIS - ANALOGICO SWITCH --------||
pinMode(MUXPinS0, OUTPUT);
pinMode(MUXPinS1, OUTPUT);
pinMode(MUXPinS2, OUTPUT);
pinMode(MUXPinS3, OUTPUT);
/*
//------------------------------------- Iniciando servidor Telnet ---------||
TelnetServer.begin();
TelnetServer.setNoDelay(true);
*/
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
delay(5000);
ESP.restart();
}
// Identificação do
ArduinoOTA.setHostname("interruptor");
// Senha para conexão via OTA
ArduinoOTA.setPassword("32342415");
//define o que será executado quando o ArduinoOTA iniciar
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_SPIFFS
type = "filesystem";
}
});//startOTA é uma função criada para simplificar o código
//define o que será executado quando o ArduinoOTA terminar
ArduinoOTA.onEnd([]() {
//Serial.println("\nEnd");
}); //endOTA é uma função criada para simplificar o código
//define o que será executado quando o ArduinoOTA estiver gravando
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
//Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});//progressOTA é uma função criada para simplificar o código
//define o que será executado quando o ArduinoOTA encontrar um erro
ArduinoOTA.onError([](ota_error_t error) {
//Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
//Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
//Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
//Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
//Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
//Serial.println("End Failed");
}
});//errorOTA é uma função criada para simplificar o código
//inicializa ArduinoOTA
ArduinoOTA.begin();
}
//============================================================================================================================
// ------------------------------------------------> VOID SETUP <-------------------------------------------------------------
//============================================================================================================================
//--------------------------- LEITURA DOS VALORES ANALOGICOS DA PLACA 16 CANAIS -------------------||
double getAnalog(int MUXyPin) {
//MUXyPin must be 0 to 15 representing the analog pin you want to read
//MUXPinS3 to MUXPinS0 are the Arduino pins connected to the selector pins of this board.
digitalWrite(MUXPinS3, HIGH && (MUXyPin & B00001000));
digitalWrite(MUXPinS2, HIGH && (MUXyPin & B00000100));
digitalWrite(MUXPinS1, HIGH && (MUXyPin & B00000010));
digitalWrite(MUXPinS0, HIGH && (MUXyPin & B00000001));
return (double)analogRead(A0);
}
void ci74HC595Write(byte pino, bool estado) {
static byte ciBuffer[qtdeCI];
bitWrite(ciBuffer[pino / 8], pino % 8, estado);
digitalWrite(pinST_CP, LOW); //Inicia a Transmissão
digitalWrite(pinDS, LOW); //Apaga Tudo para Preparar Transmissão
digitalWrite(pinSH_CP, LOW);
for (int nC = qtdeCI-1; nC >= 0; nC--) {
for (int nB = 7; nB >= 0; nB--) {
digitalWrite(pinSH_CP, LOW); //Baixa o Clock
digitalWrite(pinDS, bitRead(ciBuffer[nC], nB) ); //Escreve o BIT
digitalWrite(pinSH_CP, HIGH); //Eleva o Clock
digitalWrite(pinDS, LOW); //Baixa o Data para Previnir Vazamento
}
}
digitalWrite(pinST_CP, HIGH); //Finaliza a Transmissão
}
//--------------------------------------------------------------------------------------- FUNÇÕES MQTT -------------------------
//Chamada de recepção de mensagem
void callback(char* topic, byte* payload, unsigned int length) { //Padrão de recebimento do MQTT
//Primeiro recebe o Topico, Mensagem do programa, tamanho da mensagem
String payloadStr = "";
tam = length;
for (int i=0; i<tam; i++) { //Abre a mensagem recebida de acordo com o tamanho informado.
payloadStr += (char)payload[i];
}
String topicStr = String(topic);
char C = payload[tam-1];//necessario excluir o último item do vetor,
//pois é lixo de memoria por não exisitir um finalizador
X = C - '0';
String CStr = String(C);
Botao[X].Pino = X;
Serial.printf("X = %d, C = %c\n\n",X,C);
//const char[4] = "";
Botao[X].ONs = ("ON"+C);
Botao[X].OFFs = ("OFF"+C);
if(topicStr.equals(MQTT_COMMAND_TOPIC)){
if(payloadStr.equals(Botao[X].ONs)){
ci74HC595Write(X, LOW);
Botao[X].Estado = true; //controle interno da luz, true acesa, false apagada.
Botao[X].Delay = millis();//Espera para que a aplicação seja aplicada no circuito e ele não reporte um falso positivo para o acionamento do interruptor.
client.publish(MQTT_STATE_TOPIC, Botao[X].ONs,true);
}else if(payloadStr.equals(Botao[X].OFFs)){
ci74HC595Write(X, HIGH);
client.publish(MQTT_STATE_TOPIC, Botao[X].OFFs,true);
Botao[X].Estado = false; //controle interno da luz, true acesa, false apagada.
Botao[X].Delay = millis();//Espera para que a aplicação seja aplicada no circuito e ele não reporte um falso positivo para o acionamento do interruptor.
}
}
}
//Verifica se o estado da ligação está ativa e se não estiver tenta conectar-se
bool checkMqttConnection(){
if (!client.connected()) {
if (MQTT_AUTH ? client.connect(HOSTNAME.c_str(),MQTT_USERNAME, MQTT_PASSWORD) : client.connect(HOSTNAME.c_str())) {
//SUBSCRIÇÃO DE TOPICOS
client.subscribe(MQTT_COMMAND_TOPIC);
}
}
return client.connected();
}
//============================================================================================================================
// ------------------------------------------------( VOID LOOP )--------------------------------------------------------------
//============================================================================================================================
void loop(){
//----------------- medidor de tensão
for(int i = 0; i < 1000; i++){
X = getAnalog(1);
if(C1 < X){
C1 = X;
}
delayMicroseconds(16);
}
/////////////////////////////////Telnet.printf("Estado da Lampada = %d", C1);
if((millis() - delayLamp) >= 1000){
for(int P = 0; P<=quantidadeBotao; P++){
if(C1<=10 && estadoluz == true) {
client.publish(MQTT_STATE_TOPIC,"OFF",true);
estadoluz = false;
}
if(C1>=900 && estadoluz == false){
client.publish(MQTT_STATE_TOPIC,"ON",true);
estadoluz = true;
}
}
}
////////////////////////////Telnet.println("");
if(temporizador>0){
temporizador--;
}
//________________
int valorLDR = getAnalog(pinLDR);
if(valorLDR<=400 && C1>= 800){
///////////////////////////////////////////////////////////Telnet.printf("Lampada queimada!!!");
}else{
//////////////////////////////////////////////////////Telnet.printf("Intensidade da luz: %d", valorLDR);Telnet.println("");Telnet.println("");
}
C1=0;
// -------------------------------------------------------------------------------------------------------- CONEXÃO MQTT -----
if (WiFi.status() == WL_CONNECTED) {
if (checkMqttConnection()){
client.loop();
}
}
// ------------------------------------------------------------------------------------------------------ CONEXÃO TELNET -----
////////////////////////////////handleTelnet();
ArduinoOTA.handle();
/*
if((millis()- delayLed) <= 1000){
digitalWrite(ledVermelho,HIGH);
digitalWrite(ledVerde,LOW);
}else{
digitalWrite(ledVermelho,LOW);
digitalWrite(ledVerde,HIGH);
}
if((millis()- delayLed) >= 2000){
delayLed = millis();
}
*/
delay(100);
}
Podem conferir o funcionamento neste vídeo
aqui também, desta vez usando interruptor em paralelo e conexão 3G
Permissões neste sub-fórum
Não podes responder a tópicos