Sistema de Automação Residencial com Display LCD - MakerHero
Sistema de Automação Residencial com Display LCD

Sistema de Automação Residencial com Display LCD Deixe um comentário

Neste tutorial, vamos explorar a construção de um sistema de automação residencial utilizando placas Arduino e um Display LCD TFT Touch Shield 3.5″. Automatizar a iluminação e controlar dispositivos em casa tem sido uma área de interesse crescente, oferecendo não apenas conveniência, mas também eficiência energética e segurança.

Display LCD TFT Touch Shield 3.5

Com a combinação de hardware acessível e software personalizável, podemos criar um sistema versátil e adaptável às necessidades específicas de cada ambiente. Este projeto aborda desde os materiais necessários até o código de programação, oferecendo um guia passo a passo para a implementação do sistema de automação residencial

Objetivos

O objetivo principal deste tutorial é demonstrar como criar um sistema de automação residencial utilizando placas Arduino e um Display LCD TFT Touch Shield 3.5″. Além nesse tutorial você verá:

  • Apresentação dos materiais necessários para a construção do sistema.
  • Explicação do funcionamento do Display LCD TFT Touch Shield 3.5″ para Arduino.
  • Circuito eletrônico necessário para conectar as placas Arduino e os dispositivos controlados.
  • Instruções detalhadas para o upload do código para as placas Arduino Uno R4 WiFi e Arduino Nano 33 IoT.
  • Demonstração do funcionamento do sistema, desde a inicialização até a interação com os dispositivos controlados através do Display LCD TFT Touch Shield 3.5″.

Materiais Necessários

Para seguir com este tutorial, você irá precisar dos seguintes componentes:

Materiais Necessários para Sistema de Automação com display LCD

Além dos itens mencionados acima, você também precisará ter a Arduino IDE instalada em seu computador ou uma conta cadastrada na Arduino Cloud.

Como funciona o Display LCD TFT Touch Shield 3.5″ para Arduino?

O Display LCD TFT Touch Shield 3.5″ para Arduino é um módulo de exibição que permite que você adicione uma tela de toque colorida ao seu projeto Arduino. 

  • Hardware: O Shield é montado diretamente sobre o Arduino, encaixando-se nos pinos, proporcionando uma conexão direta e fácil.
  • Tela TFT (Thin-Film Transistor): Este tipo de tela é conhecido por sua qualidade de imagem e é capaz de exibir gráficos coloridos de alta resolução. No caso deste shield, ele possui uma tela TFT de 3,5 polegadas.
  • Tela de Toque: Além da exibição, o shield também possui uma tela de toque resistiva integrada. Isso permite interações táteis com o dispositivo, como tocar e arrastar, sem a necessidade de botões físicos.
  • Controlador: O shield vem com um controlador embutido que facilita a comunicação entre o Arduino e a tela. Isso é feito através de interfaces como SPI (Serial Peripheral Interface) .
  • Bibliotecas de Software: Para controlar o display e a tela de toque, você normalmente usaria bibliotecas específicas para o modelo do shield. Essas bibliotecas simplificam a comunicação entre o Arduino e o display, permitindo que você escreva código para exibir gráficos, texto e responder a eventos de toque.
  • Alimentação: Geralmente, o shield pode ser alimentado diretamente a partir do Arduino, embora displays maiores possam exigir uma fonte de alimentação externa.

Ao usar este shield, você pode criar uma variedade de projetos interativos, desde interfaces de usuário simples até jogos e aplicativos mais complexos, tudo controlado pelo Arduino.

Circuito Eletrônico do sistema de automação residencial

O circuito principal do sistema de automação residencial é formado por apenas dois elementos: a placa Arduino Uno R4 WiFi e o Display LCD TFT Touch Shield 3.5″. Por ser um shield, o display se conecta facilmente à placa através de um simples encaixe.

Circuito Eletrônico de Sistema de Automação Residencial

Já o circuito secundário, que será controlado pelo sistema de automação residencial, é composto pelo Anel de LED RGB e a placa Arduino Nano 33 IoT. As conexões realizadas são as seguintes:

Anel de LED RGB -> Arduino Nano 33 IoT

GND -> GND
VCC -> 3V3
IN -> D2

Circuito eletrônico Anel LED RGB

Código

Para fazer o upload do código abaixo para a placa Arduino Uno R4 WiFi, siga os seguintes passos:

  • Na Arduino IDE, vá em Ferramentas > Placa > Gerenciador de Placas. Busque por “SAMD” e faça a instalação do do pacote Arduino UNO R4 Boards.
  • Vá em Ferramentas > Placa >Arduino UNO R4 Boards e selecione Arduino UNO R4 WiFi.
  • Depois vá em Ferramentas > Gerenciador de Bibliotecas. Busque por “TouchSreeen” e faça a instalação da biblioteca Adafruit TouchScreen
  • Vá novamente em Ferramentas > Gerenciador de Bibliotecas.  Busque por “GFX Library” e faça a instalação da biblioteca GFX Library for Arduino.
  • Copie e cole o código abaixo na Arduino IDE.
  • Altere as linhas  9 e 10 com as credenciais da rede WiFi em que o sistema principal estará conectado. 
  • Carregue o código para a placa. 
// Programa: Sistema de Automação Residencial - Principal
// Placa: Arduino Uno R4 WiFi
// Autor: Rosana Guse

#include "WiFiS3.h"
#include <Arduino_GFX_Library.h>
#include <TouchScreen.h>

char ssid[] = "nome-da-rede-wifi";        // SSID da sua rede Wi-Fi
char pass[] = "senha-da-rede-wifi";        // Senha da sua rede Wi-Fi

// Configurações do touchscreen
#define TS_MINX 100
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000

// Definições dos pinos do touchscreen
#define YP A3
#define XM A2
#define YM 9
#define XP 8

// Definições dos botões
#define BUTTON_WIDTH 150
#define BUTTON_HEIGHT 80
#define BUTTON_MARGIN_X 20
#define BUTTON_MARGIN_Y 20

// Cores
#define COLOR_BLACK   0x0000
#define COLOR_WHITE   0xFFFF
#define COLOR_RED     0xF800
#define COLOR_ORANGE  0xFD20
#define COLOR_YELLOW  0xFFE0
#define COLOR_GREEN   0x07E0
#define COLOR_CYAN    0x07FF
#define COLOR_BLUE    0x001F
#define COLOR_PURPLE  0xF81F  

// Criação de uma instância do barramento de dados Arduino
Arduino_DataBus *bus = new Arduino_UNOPAR8;
// Criação de uma instância da classe Arduino_GFX para controlar o display
Arduino_GFX *gfx = new Arduino_ILI9486(bus, A4, 3, false);

// Criação de uma instância do touchscreen
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

WiFiClient client;  // Inicializa um cliente Wi-Fi para comunicação com o servidor
IPAddress serverIP(192, 168, 10, 111);  // IP da placa Arduino receptora
const int serverPort = 80;  // Porta do servidor

// Variáveis para armazenar o deslocamento dos botões
int offsetX, offsetY;

// Variável para armazenar o processo executado
int process = 0;

// Variáveis para armazenar a cor selecionada
int color = 0;
int previousColor = 0;

void setup() {
  Serial.begin(9600);  // Inicializa a comunicação serial
  
  delay(1000);  // Aguarda um segundo

  connectWiFi();  // Conecta-se à rede Wi-Fi

  if (!gfx->begin()) {  // Verifica se houve erro ao iniciar o display
    Serial.println("Erro iniciar o display");  // Exibe mensagem de erro
  }

  gfx->fillScreen(COLOR_BLACK);  // Preenche a tela com a cor preta
  
  drawMainScreen();  // Desenha a tela principal
}

void loop() {
  
  switch (process) {  // Verifica o estado atual do processo
    case 0:  // Caso o estado seja 0 (tela principal)
      processMainScreenTouch();  // Processa toques na tela principal
      break;
    case 1:  // Caso o estado seja 1 (tela do dispositivo 1)
      processDeviceScreenTouch1();  // Processa toques na tela do dispositivo 1
      break;
    case 2:  // Caso o estado seja 2 (tela do dispositivo 2)
      processDeviceScreenTouch2();  // Processa toques na tela do dispositivo 2
      break;
    case 3:  // Caso o estado seja 3 (tela do dispositivo 3)
      processDeviceScreenTouch3();  // Processa toques na tela do dispositivo 3
      break;
    case 4:  // Caso o estado seja 4 (tela do dispositivo 4)
      processDeviceScreenTouch4();  // Processa toques na tela do dispositivo 4
      break;
    case 5:  // Caso o estado seja 5 (tela RGB)
      if (color != previousColor) {  // Verifica se a cor atual é diferente da cor anterior
        sendColor();  // Envia a cor se ela mudou
        previousColor = color;  // Atualiza o valor anterior da cor
      }
      else {
        processRGBScreenTouch();  // Processa toques na tela RGB
      }
      break;
  }
  delay(50);  // Pequena pausa para evitar leituras muito frequentes do touchscreen
}

void connectWiFi() {
  Serial.println("Conectando na rede WiFi...");  // Exibe mensagem de tentativa de conexão
  WiFi.begin(ssid, pass);  // Inicia a conexão com a rede Wi-Fi
  
  // Aguarda até que a conexão seja estabelecida
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("Conexão com WiFi realizada com sucesso!");  // Exibe mensagem de conexão bem-sucedida

  // Loop de tentativa de conexão com o servidor
  bool connectedToServer = false;
  while (!connectedToServer) {
    Serial.println("Conectando ao servidor...");  // Exibe mensagem de tentativa de conexão com o servidor
    if (client.connect(serverIP, serverPort)) {  // Tenta conectar ao servidor
      Serial.println("Conexão com o servidor realizada com sucesso!");  // Exibe mensagem de conexão bem-sucedida
      connectedToServer = true;  // Define que a conexão foi estabelecida com sucesso
      sendColor(); // Envie a cor inicial quando a conexão for estabelecida
    } else {
      Serial.println("Conexão com o servidor falhou");  // Exibe mensagem de falha na conexão com o servidor
      delay(1000); // Aguarda um curto período antes de tentar novamente
    }
  }
}

void sendColor() {
  Serial.print("Enviando cor para a servidor: ");  // Exibe mensagem de envio da cor
  Serial.println(color);  // Exibe o valor da cor a ser enviado
  // Envia a cor para o servidor
  client.print("GET /?color=");
  client.print(color);
  client.println(" HTTP/1.1");
  client.println("Host: arduino_receiver.local");
  client.println("Connection: close");
  client.println();
}

void drawButton(int x, int y, String label, uint16_t color, int width, int height) {
  // Desenha um botão na tela com o rótulo especificado e cor de fundo
  gfx->fillRect(x, y, width, height, color);
  gfx->setTextSize(2);
  gfx->setCursor(x + 10, y + 10);
  gfx->setTextColor(BLACK);
  gfx->println(label);
}

void drawReturnButton() {
  // Desenha um botão "VOLTAR" na tela
  gfx->fillRect(0, 0, 80, 30, COLOR_PURPLE);
  gfx->setTextSize(2);
  gfx->setCursor(5, 5);
  gfx->setTextColor(COLOR_BLACK);
  gfx->println("VOLTAR");
}

void drawMainScreen() {
  // Desenha a tela principal com os botões correspondentes aos ambientes
  gfx->fillScreen(COLOR_BLACK);
  
  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 2 * BUTTON_WIDTH - BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - BUTTON_MARGIN_Y) / 2;

  // Desenhar os botões na tela
  drawButton(offsetX, offsetY, "AMBIENTE 1", COLOR_ORANGE, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY, "AMBIENTE  2", COLOR_ORANGE, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "AMBIENTE  3", COLOR_ORANGE, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "AMBIENTE  4", COLOR_ORANGE, BUTTON_WIDTH, BUTTON_HEIGHT);
}

void drawDeviceButtons1() {
  // Desenha a tela com botões para o dispositivo 1
  gfx->fillScreen(COLOR_BLACK);
  
  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 2 * BUTTON_WIDTH - BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - BUTTON_MARGIN_Y) / 2;

  // Desenhar os botões na tela
  drawButton(offsetX, offsetY, "LUMINARIA", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);

  drawReturnButton();
}

void drawDeviceButtons2() {
  // Desenha a tela com botões para o dispositivo 2
  gfx->fillScreen(COLOR_BLACK);
  
  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 2 * BUTTON_WIDTH - BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - BUTTON_MARGIN_Y) / 2;

  // Desenhar os botões na tela
  drawButton(offsetX, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);

  drawReturnButton();
}

void drawDeviceButtons3() {
  // Desenha a tela com botões para o dispositivo 3
  gfx->fillScreen(COLOR_BLACK);
  
  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 2 * BUTTON_WIDTH - BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - BUTTON_MARGIN_Y) / 2;

  // Desenhar os botões na tela
  drawButton(offsetX, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);

  drawReturnButton();
}

void drawDeviceButtons4() {
  // Desenha a tela com botões para o dispositivo 4
  gfx->fillScreen(COLOR_BLACK);
  
  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 2 * BUTTON_WIDTH - BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - BUTTON_MARGIN_Y) / 2;

  // Desenhar os botões na tela
  drawButton(offsetX, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);
  drawButton(offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X, offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y, "DISPOSITIVO", COLOR_CYAN, BUTTON_WIDTH, BUTTON_HEIGHT);

  drawReturnButton();
}

void drawRGBButtons() {
  // Desenha a tela com botões para a seleção de cores RGB
  gfx->fillScreen(COLOR_BLACK);

  // Calcula as coordenadas para centralizar os botões
  offsetX = (gfx->width() - 3 * BUTTON_WIDTH - 2 * BUTTON_MARGIN_X) / 2;
  offsetY = (gfx->height() - 2 * BUTTON_HEIGHT - 2 * BUTTON_MARGIN_Y) / 2;

  // Rótulos e cores dos botões
  String buttonLabels[] = {"BRANCO", "VERMELHO", "LARANJA", "AMARELO", "VERDE", "CIANO", "AZUL", "ROXO", "DESLIGAR"};
  uint16_t buttonColors[] = {COLOR_WHITE, COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_PURPLE, COLOR_WHITE};

  // Desenhar os botões na tela
  for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
      int x = offsetX + col * (BUTTON_WIDTH + BUTTON_MARGIN_X);
      int y = offsetY + row * (BUTTON_HEIGHT + BUTTON_MARGIN_Y);
      drawButton(x, y, buttonLabels[row * 3 + col], buttonColors[row * 3 + col], BUTTON_WIDTH, BUTTON_HEIGHT/1.5);
    }
  }

  drawReturnButton();
}

void processMainScreenTouch() {
  // Processa o toque na tela na tela principal
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Ambiente 1 pressionado!");
      process = 1;
      drawDeviceButtons1();
    } else if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Ambiente 2 pressionado!");
      process = 2;
      drawDeviceButtons2();
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Ambiente 3 pressionado!");
      process = 3;
      drawDeviceButtons3();    
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Ambiente 4 pressionado!");
      process = 4; 
      drawDeviceButtons4();    
    }
  }
}

void processDeviceScreenTouch1() {
  // Processa o toque na tela do dispositivo 1
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 1 pressionado!");
      process = 5;
      drawRGBButtons();
    } else if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 2 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 2" é pressionado
      process = 6;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 3 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 3" é pressionado
      process = 7;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 4 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 4" é pressionado
      process = 8;
    } else if (x >= 0 && x < 80 && y >= 0 && y < 30) {
      Serial.println("Botão Voltar pressionado!");
      drawMainScreen();
      process = 0;
    }
  }
}

void processDeviceScreenTouch2() {
  // Processa o toque na tela do dispositivo 2
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 1 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 1" é pressionado
      process = 9;
    } else if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 2 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 2" é pressionado
      process = 10;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 3 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 3" é pressionado
      process = 11;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 4 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 4" é pressionado
      process = 12;
    } else if (x >= 0 && x < 80 && y >= 0 && y < 30) {
      Serial.println("Botão Voltar pressionado!");
      drawMainScreen();
      process = 0;
    }
  }
}

void processDeviceScreenTouch3() {
  // Processa o toque na tela do dispositivo 3
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 1 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 1" é pressionado
      process = 13;
    } else if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 2 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 2" é pressionado
      process = 14;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 3 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 3" é pressionado
      process = 15;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 4 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 4" é pressionado
      process = 16;
    } else if (x >= 0 && x < 80 && y >= 0 && y < 30) {
      Serial.println("Botão Voltar pressionado!");
      drawMainScreen();
      process = 0;
    }
  }
}

void processDeviceScreenTouch4() {
  // Processa o toque na tela do dispositivo 4
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 1 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 1" é pressionado
      process = 17;
    } else if (x >= offsetX && x < offsetX + BUTTON_WIDTH && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 2 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 2" é pressionado
      process = 18;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY && y < offsetY + BUTTON_HEIGHT) {
      Serial.println("Botão Dispositivo 3 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 3" é pressionado
      process = 19;
    } else if (x >= offsetX + BUTTON_WIDTH + BUTTON_MARGIN_X && x < offsetX + 2 * BUTTON_WIDTH + BUTTON_MARGIN_X && y >= offsetY + BUTTON_HEIGHT + BUTTON_MARGIN_Y && y < offsetY + 2 * BUTTON_HEIGHT + BUTTON_MARGIN_Y) {
      Serial.println("Botão Dispositivo 4 pressionado!");
      // Ação a ser realizada quando o botão "Dispositivo 4" é pressionado
      process = 20;
    } else if (x >= 0 && x < 80 && y >= 0 && y < 30) {
      Serial.println("Botão Voltar pressionado!");
      drawMainScreen();
      process = 0;
    }
  }
}

void processRGBScreenTouch() {
  // Processa o toque na tela de controle de cores RGB
  TSPoint p = ts.getPoint();
  configureTouchScreen();

  // Verifica se houve toque ou não
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    int16_t x = map(p.x, TS_MINX, TS_MAXX, 0, gfx->width());
    int16_t y = map(p.y, TS_MINY, TS_MAXY, 0, gfx->height());

    // Verifica qual botão foi pressionado
    for (int row = 0; row < 3; row++) {
      for (int col = 0; col < 3; col++) {
        int buttonIndex = row * 3 + col;
        int buttonX = offsetX + col * (BUTTON_WIDTH + BUTTON_MARGIN_X);
        int buttonY = offsetY + row * (BUTTON_HEIGHT + BUTTON_MARGIN_Y);
        
        if (x >= buttonX && x < buttonX + BUTTON_WIDTH && y >= buttonY && y < buttonY + BUTTON_HEIGHT/1.5) {
          // Lógica para cada botão
          switch(buttonIndex) {
            case 0: // Botão BRANCO
              Serial.println("Botão BRANCO pressionado!");
              color = 1;
              break;
            case 1: // Botão AMARELO
              Serial.println("Botão AMARELO pressionado!");
              color = 2;
              break;
            case 2: // Botão AZUL
              Serial.println("Botão AZUL pressionado!");
              color = 3;
              break;
            case 3: // Botão VERMELHO
              Serial.println("Botão VERMELHO pressionado!");
              color = 4;
              break;
            case 4: // Botão VERDE
              Serial.println("Botão VERDE pressionado!");
              color = 5;
              break;
            case 5: // Botão ROXO
              Serial.println("Botão ROXO pressionado!");
              color = 6;
              break;
            case 6: // Botão LARANJA
              Serial.println("Botão LARANJA pressionado!");
              color = 7;
              break;
            case 7: // Botão CIANO
              Serial.println("Botão CIANO pressionado!");
              color = 8;
              break;
            case 8: // Botão DESLIGAR
              Serial.println("Botão DESLIGAR pressionado!");
              color = 0;
              break;
          }
        }
      }
    }
    
    // Verifica se o botão Voltar foi pressionado
    if (x >= 0 && x < 80 && y >= 0 && y < 30) {
      Serial.println("Botão Voltar pressionado!");
      drawMainScreen();
      process = 0;
    }
  }
}

void configureTouchScreen() {
  // Configura os pinos do touchscreen
  pinMode(XM, OUTPUT);
  digitalWrite(XM, LOW);
  pinMode(YP, OUTPUT);
  digitalWrite(YP, HIGH);
  pinMode(YM, OUTPUT);
  digitalWrite(YM, LOW);
  pinMode(XP, OUTPUT);
  digitalWrite(XP, HIGH);
}

Para fazer o upload do código abaixo para a placa Arduino Nano 33 IoT, siga os seguintes passos:

  • Na Arduino IDE, vá em Ferramentas > Placa > Gerenciador de Placas. Busque por “SAMD” e faça a instalação do do pacote Arduino SAMD Boards (32-bit ARM Cortex-M0+).
  • Vá em Ferramentas > Placa > Arduino SAMD Boards (32-bit ARM Cortex-M0+) e selecione Arduino NANO 33 IoT.
  • Depois vá em Ferramentas > Gerenciador de Bibliotecas. Busque por “NINA” e faça a instalação da biblioteca WiFININA
  • Vá novamente em Ferramentas > Gerenciador de Bibliotecas.  Busque por “NeoPixel” e faça a instalação da biblioteca Adafruit NeoPixel.
  • Copie e cole o código abaixo na Arduino IDE.
  • Altere as linhas 8 e 9 com as credenciais da rede WiFi em que o sistema secundário estará conectado. 
  • Carregue o código para a placa. 
// Programa: Sistema de Automação Residencial - Secundário
// Placa: Arduino Nano 33 IoT
// Autor: Rosana Guse

#include <Adafruit_NeoPixel.h>
#include "WiFiNINA.h"

char ssid[] = "nome-da-rede-wifi";        // SSID da sua rede Wi-Fi
char pass[] = "senha-da-rede-wifi";        // Senha da sua rede Wi-Fi

WiFiServer server(80);  // Cria um servidor na porta 80
WiFiClient client;  // Inicializa um cliente Wi-Fi

#define PIN       2  // Pino de dados do LED
#define NUMPIXELS 24  // Número total de LEDs
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);  // Cria uma instância do objeto NeoPixel

int colorReceived = 0;  // Armazena a cor recebida do cliente

void setup() {
  Serial.begin(9600);  // Inicializa a comunicação serial
  delay(1000);  // Aguarda um segundo

  connectWiFi();  // Conecta-se à rede Wi-Fi

  pixels.begin();  // Inicializa o objeto NeoPixel
  pixels.clear();  // Limpa todos os LEDs
}

void loop() {
  receiveColor();  // Recebe a cor enviada pelo cliente
  updateLEDs();  // Atualiza os LEDs com base na cor recebida
}

void connectWiFi() {
  Serial.println("Conectando na rede WiFi...");  // Exibe mensagem de conexão
  WiFi.begin(ssid, pass);  // Inicia a conexão Wi-Fi
  while (WiFi.status() != WL_CONNECTED) {  // Aguarda até que o dispositivo esteja conectado à rede Wi-Fi
    delay(500);  // Aguarda 500 milissegundos
    Serial.print(".");  // Exibe um ponto para indicar o processo de conexão
  }
  Serial.println("Conexão com WiFi realizada com sucesso!");  // Exibe mensagem de conexão bem-sucedida

  server.begin();  // Inicia o servidor
  Serial.print("Servidor iniciado. IP: ");  // Exibe mensagem indicando o início do servidor
  Serial.println(WiFi.localIP());  // Exibe o endereço IP local atribuído ao dispositivo
}

void receiveColor() {
  if (!client.connected()) {  // Verifica se o cliente não está conectado
    // Se o cliente não estiver conectado, aguarda por uma nova conexão
    client = server.available();  // Aceita a conexão do cliente
    if (client) {  // Se uma nova conexão foi estabelecida
      Serial.println("Novo cliente conectado!");  // Exibe mensagem indicando que um novo cliente foi conectado
    }
  } else {  // Se o cliente estiver conectado
    if (client.available()) {  // Verifica se há dados disponíveis para leitura
      String request = client.readStringUntil('\r');  // Lê a requisição do cliente até o caractere de retorno de carro
      if (request.indexOf("color=") != -1) {  // Verifica se a requisição contém a variável "color"
        int colorIndex = request.indexOf("color=");  // Obtém o índice onde a cor está localizada na requisição
        colorReceived = request.substring(colorIndex + 6).toInt();  // Extrai e converte a cor recebida em um número inteiro
        Serial.print("Valor da cor recebido: ");  // Exibe mensagem indicando que a cor foi recebida
        Serial.println(colorReceived);  // Exibe o valor da cor recebida
      }
    }
  }
}

void updateLEDs() {
  switch (colorReceived) {  // Seleciona a ação com base no valor da cor recebida
    case 0: // Desligar LEDs
      pixels.clear();  // Limpa todos os LEDs
      pixels.show();  // Atualiza os LEDs
      break;
    case 1: // Branco
      setAllPixelsColor(255, 255, 255);  // Define a cor de todos os LEDs como branco
      break;
    case 2: // Amarelo
      setAllPixelsColor(255, 255, 50);  // Define a cor de todos os LEDs como amarelo
      break;
    case 3: // Azul
      setAllPixelsColor(0, 0, 255);  // Define a cor de todos os LEDs como azul
      break;
    case 4: // Vermelho
      setAllPixelsColor(255, 0, 0);  // Define a cor de todos os LEDs como vermelho
      break;
    case 5: // Verde
      setAllPixelsColor(0, 255, 0);  // Define a cor de todos os LEDs como verde
      break;
    case 6: // Roxo
      setAllPixelsColor(128, 0, 128);  // Define a cor de todos os LEDs como roxo
      break;
    case 7: // Laranja
      setAllPixelsColor(255, 165, 0);  // Define a cor de todos os LEDs como laranja
      break;
    case 8: // Ciano
      setAllPixelsColor(0, 255, 255);  // Define a cor de todos os LEDs como ciano
      break;
    default:  // Se nenhum caso corresponder ao valor da cor recebida
      break;  // Não faz nada
  }
}

// Função para definir a cor de todos os LEDs
void setAllPixelsColor(uint8_t red, uint8_t green, uint8_t blue) {
  for (int i = 0; i < NUMPIXELS; i++) {  // Loop através de todos os LEDs
    pixels.setPixelColor(i, pixels.Color(red, green, blue));  // Define a cor do LED atual
  }
  pixels.show();  // Atualiza os LEDs com a nova cor
}

Funcionamento do sistema de automação residencial com Arduino

Conecte as placas Arduino Uno R4 WiFi e Arduino Nano 33 IoT usando um cabo USB tipo C e um cabo micro USB, respectivamente.

Na tela inicial do Display LCD TFT Touch Shield 3.5″, será exibido o menu para selecionar o ambiente do dispositivo a ser controlado. Após selecionar o ambiente desejado, aparecerá a lista de dispositivos disponíveis para controle. Em seguida, é possível manipular o dispositivo selecionado. Por exemplo, é possível controlar uma luminária, ajustando as cores dos LEDs ou desligando-a completamente.

 

O código principal mencionado acima pode ser facilmente adaptado para controlar outros dispositivos via WiFi. Basta modificar as lógicas dentro das funções processDeviceScreenTouchX.


Se você tiver dúvidas, sugestões ou experiências para compartilhar, fique a vontade para deixar um comentário abaixo. E para não perder nenhum conteúdo como este, não deixe de nos seguir no Instagram.

Faça seu comentário

Acesse sua conta e participe