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.
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:
- Arduino Uno R4 WiFi
- Arduino Nano 33 IoT
- Display LCD TFT Touch Shield 3.5″ para Arduino
- Anel de LED RGB x24 WS2812 5050 Endereçável
- Fios para Conexão
- Cabo USB tipo C
- Cabo Micro USB
- Peças 3D para Luminária (Opcional)
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.
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
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.