Esquema do Projeto |
A versão final do App utilizando a plataforma MIT App Inventor, agora com uma interface mais moderna e funcionalidades mais precisas está pronta. O App inicia com somente os campos de Conectividade visíveis, em uma interface mais limpa.
Para evitar alguns "bugs" mantivemos o botão de Desconectar desativado enquanto não houver nenhuma conexão realizada.
- 1 ESP 32 - 30 Pinos;
- 1 Fonte Arduino 5v;
- 1 Protoboard;
- Jumpers para conexões;
- 1 Módulo Relé para Arduino com 4 Relés;
- 1 Dispositivo Dimmer MC-8A com entrada PWM para controle digital;
- 2 bocais para lâmpadas;
- 2m de cabos 1,5mm² para energização das lâmpadas;
- 2 Lâmpadas;
- 1 Smartphone com suporte BLE;
Abaixo um breve vídeo com o funcionamento do circuito e App desenvolvido:
Para a programação da eletrônica foi utilizado o Arduino IDE utilizando o código abaixo:
Código ESP32
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLECharacteristic *characteristicTX; //através desse objeto iremos enviar dados para o client
bool deviceConnected = false; //controle de dispositivo conectado
const int rele1 = 2;
const int rele2 = 4;
const int rele3 = 5;
const int rele4 = 18;
int controle = 0;
int aux = 0;
int Busca = 0;
#define SERVICE_UUID "4FAFC201-1FB5-459E-8FCC-C5C9C331914B"
// UART service UUID não podedo ser iguais
#define CHARACTERISTIC_UUID_RX "4FAFC202-1FB5-459E-8FCC-C5C9C331914B"
#define CHARACTERISTIC_UUID_TX "4FAFC203-1FB5-459E-8FCC-C5C9C331914B"
#define PINO_DIM 26
#define PINO_ZC 27
#define maxBrightness 800 // brilho maximo em us
#define minBrightness 7500 // brilho minimo em us
#define TRIGGER_TRIAC_INTERVAL 20 // tempo quem que o triac fica acionado
#define IDLE -1
#define pino_botao_up 13 // pino quem que o botao de aumentar o brilho esta conectado
#define pino_botao_down 12 // pino que o botao de diminuir o brilho esta conectado
//callback para receber os eventos de conexão de dispositivos
class ServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
//callback para envendos das características
class CharacteristicCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *characteristic) {
//retorna ponteiro para o registrador contendo o valor atual da caracteristica
std::string rxValue = characteristic->getValue();
//verifica se existe dados (tamanho maior que zero)
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Esperando Comando ");// vai printar para mim no serial
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}
Serial.println();
// Do stuff based on the command received
if (rxValue.find("Liga1") != -1) {
Serial.print("Ligar!");// vai printar para mim no serial
digitalWrite(rele1, LOW);
aux = 1;
}
else if (rxValue.find("Desl1") != -1) {
Serial.print("Desligar");
digitalWrite(rele1, HIGH);
aux = 0;
}
else if (rxValue.find("Liga2") != -1) {
Serial.print("Ligar!");// vai printar para mim no serial
digitalWrite(rele2, LOW);
}
else if (rxValue.find("Desl2") != -1) {
Serial.print("Desligar");
digitalWrite(rele2, HIGH);
}
else if (rxValue.find("Liga3") != -1) {
Serial.print("Ligar!");// vai printar para mim no serial
digitalWrite(rele3, LOW);
}
else if (rxValue.find("Desl3") != -1) {
Serial.print("Desligar");
digitalWrite(rele3, HIGH);
}
else if (rxValue.find("Liga4") != -1) {
Serial.print("Ligar!");// vai printar para mim no serial
digitalWrite(rele4, LOW);
}
else if (rxValue.find("Desl4") != -1) {
Serial.print("Desligar");
digitalWrite(rele4, HIGH);
}
else if ((rxValue.find("0") != -1 && aux == 1)){
controle = 0;
}
else if ((rxValue.find("1") != -1) && aux == 1){
controle = 1;
}
else if ((rxValue.find("2") != -1 && aux == 1)){
controle = 2;
}
else if ((rxValue.find("3") != -1) && aux == 1){
controle = 3;
}
else if ((rxValue.find("4") != -1 && aux == 1)){
controle = 4;
}
else if ((rxValue.find("5") != -1) && aux == 1){
controle = 5;
}
}
}
};
//variaveis globais
int brilho = 100;
int brilho_convertido = 0;
unsigned long ultimo_millis1 = 0;
unsigned long ultimo_millis2 = 0;
unsigned long debounce_delay = 100;
hw_timer_t * timerToPinHigh;
hw_timer_t * timerToPinLow;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
volatile bool isPinHighEnabled = false;
volatile long currentBrightness = minBrightness;
void IRAM_ATTR ISR_turnPinLow(){ // desliga o pino dim
portENTER_CRITICAL_ISR(&mux); // desativa interrupçoes
digitalWrite(PINO_DIM, LOW);
isPinHighEnabled = false;
portEXIT_CRITICAL_ISR(&mux); // ativa as interrupçoes novamente
}
void IRAM_ATTR setTimerPinLow(){ // executa as configuracoes de pwm e aplica os valores da luminosidade ao dimmer no tempo em que ra ficar em low
timerToPinLow = timerBegin(1, 80, true);
timerAttachInterrupt(timerToPinLow, &ISR_turnPinLow, true);
timerAlarmWrite(timerToPinLow, TRIGGER_TRIAC_INTERVAL, false);
timerAlarmEnable(timerToPinLow);
}
void IRAM_ATTR ISR_turnPinHigh(){ // liga o pino dim
portENTER_CRITICAL_ISR(&mux); // desativa interrupçoes
digitalWrite(PINO_DIM, HIGH);
setTimerPinLow();
portEXIT_CRITICAL_ISR(&mux); // ativa as interrupçoes novamente
}
void IRAM_ATTR setTimerPinHigh(long brightness){ // executa as configuracoes de pwm e aplica os valores da luminosidade ao dimmer no tempo que ira ficar em high
isPinHighEnabled = true;
timerToPinHigh = timerBegin(1, 80, true);
timerAttachInterrupt(timerToPinHigh, &ISR_turnPinHigh, true);
timerAlarmWrite(timerToPinHigh, brightness, false);
timerAlarmEnable(timerToPinHigh);
}
void IRAM_ATTR ISR_zeroCross() {// funçao que é chamada ao dimmer registrar passagem por 0
if(currentBrightness == IDLE) return;
portENTER_CRITICAL_ISR(&mux); // desativa interrupçoes
if(!isPinHighEnabled){
setTimerPinHigh(currentBrightness); // define o brilho
}
portEXIT_CRITICAL_ISR(&mux); // ativa as interrupçoes novamente
}
void turnLightOn(){ // liga o dimmer no brilho maximo
portENTER_CRITICAL(&mux);// desativa interrupçoes
currentBrightness = maxBrightness;
digitalWrite(PINO_DIM, HIGH);
portEXIT_CRITICAL(&mux);// ativa as interrupçoes novamente
}
void turnLightOff(){// deliga o dimmer
portENTER_CRITICAL(&mux); // desativa interrupçoes
currentBrightness = IDLE;
digitalWrite(PINO_DIM, LOW);
portEXIT_CRITICAL(&mux); // ativa as interrupçoes novamente
}
void setup() {
Serial.begin(115200);
pinMode(rele1, OUTPUT);
pinMode(rele2, OUTPUT);
pinMode(rele3, OUTPUT);
pinMode(rele4, OUTPUT);
digitalWrite(rele1, HIGH);
digitalWrite(rele2, HIGH);
digitalWrite(rele3, HIGH);
digitalWrite(rele4, HIGH);
// Create the BLE Device
BLEDevice::init("BLE_TOPICOS"); // nome do dispositivo bluetooth
// Create the BLE Server
BLEServer *server = BLEDevice::createServer(); //cria um BLE server
server->setCallbacks(new ServerCallbacks()); //seta o callback do server
// Create the BLE Service
BLEService *service = server->createService(SERVICE_UUID);
// Create a BLE Characteristic para envio de dados
characteristicTX = service->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
characteristicTX->addDescriptor(new BLE2902());
// Create a BLE Characteristic para recebimento de dados
BLECharacteristic *characteristic = service->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
characteristic->setCallbacks(new CharacteristicCallbacks());
// Start the service
service->start();
// Start advertising (descoberta do ESP32)
server->getAdvertising()->start();
Serial.println("Esperando conexão");
currentBrightness = IDLE;
pinMode(PINO_ZC, INPUT_PULLUP);
pinMode(PINO_DIM, OUTPUT);
digitalWrite(PINO_DIM, LOW);
attachInterrupt(digitalPinToInterrupt(PINO_ZC), ISR_zeroCross, RISING);
Serial.println("Controlando dimmer com esp32");
pinMode(pino_botao_up, INPUT);
pinMode(pino_botao_down, INPUT);
}
void loop() {
//se existe algum dispositivo conectado
if (deviceConnected == false) {
Serial.print(" Aguardando Nova Conexão: ");
Serial.println(" ");
if (Busca == 1){
Busca = 0;
ESP.restart();
}
}
delay(1000);
if (deviceConnected == true) {
Serial.print(" Aguardando Comando ");
Serial.println(" ");
Busca = 1;
}
Serial.println(brilho); // mostra a quantidade de brilho atual
if (controle == 5) { // e o botao estiver precionado
brilho = 60;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
else if (controle == 4) { // e o botao estiver precionado
brilho = 48;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
else if (controle == 3) { // e o botao estiver precionado
brilho = 36;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
else if (controle == 2) { // e o botao estiver precionado
brilho = 24;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
else if (controle == 1) { // e o botao estiver precionado
brilho = 12;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
else if (controle == 0) { // e o botao estiver precionado
brilho = 0;
brilho_convertido = map(brilho, 100, 0, maxBrightness, minBrightness); //converte a luminosidade em microsegundos
portENTER_CRITICAL(&mux); //desliga as interrupçoes
currentBrightness = brilho_convertido; // altera o brilho
portEXIT_CRITICAL(&mux);// liga as interrupçoes
}
}
Esse projeto de acender e controlar a intensidade da da luz que passa na lâmpada tem com objetivo aumentar o conhecimento na área de programação em micro controlador, ver como funciona o famoso BLE que vem ganhando destaque em algumas automações no mercado, assim com base nesse projeto pode se aprofundar mais em automação residencial, atingimos o objetivo principal do projeto assim através dele pode surgir novas ideias.
Comentários
Postar um comentário