Arduino IDE With Dual Core: Remote Control
by Fernando Koyanagi in Circuits > Microcontrollers
515 Views, 0 Favorites, 0 Comments
Arduino IDE With Dual Core: Remote Control
![Arduino IDE com Dual Core: Controle Remoto!](/proxy/?url=https://content.instructables.com/FZ2/JEMJ/JQUU5EL2/FZ2JEMJJQUU5EL2.jpg&filename=Arduino IDE com Dual Core: Controle Remoto!)
![1.png](/proxy/?url=https://content.instructables.com/FSR/8HCI/JQUU5EL7/FSR8HCIJQUU5EL7.png&filename=1.png)
This video is all about “multi.” We are dealing with multitasking, multicores, and multiclients. A while ago, I made a remote control with two ESPs: a client and an access point. Based on this, today we’ll set up a multiclient server. This means we’ll have multiple clients connected in a single ESP.
Thus, the lesson today involves the creation of a server in ESP32, the addition of new clients in the loop, and the handling of the requests in another core. Clients will send information about the state change of their pins, and the server will reproduce these state changes.
Demonstration
![demo.jpg](/proxy/?url=https://content.instructables.com/F7C/A4XM/JQUU5ELM/F7CA4XMJQUU5ELM.jpg&filename=demo.jpg)
Mounting Server
![7.1.png](/proxy/?url=https://content.instructables.com/F66/I29C/JQUU5EM5/F66I29CJQUU5EM5.png&filename=7.1.png)
Client Assembly
![7.2.png](/proxy/?url=https://content.instructables.com/F4R/FZBJ/JQUU5EMQ/F4RFZBJJQUU5EMQ.png&filename=7.2.png)
Flow - Server
![8.1.png](/proxy/?url=https://content.instructables.com/F4X/K0Q4/JQUU5ENI/F4XK0Q4JQUU5ENI.png&filename=8.1.png)
Flow - Client
![8.2.png](/proxy/?url=https://content.instructables.com/F9B/EH9R/JQUU5EOO/F9BEH9RJQUU5EOO.png&filename=8.2.png)
Client.ino
Declarations and variables
#include <WiFi.h>
//Dados da rede //Deve ser giual no Server #define SSID "ESP32Server" #define PASSWORD "87654321" #define SERVER_PORT 5000 //Objeto que vai fazer a conexão com o server WiFiClient client; //Struct que define os dados que vamos enviar (deve ser igual no server) typedef struct{ int number; int status; }Pin; //Quantidade de pinos que iremos ler e enviar o status #define PIN_COUNT 2 //Array com os pinos definidos //No caso vamos trabalhar com os 21 e 19 mas você pode alterar para os pinos que desejar Pin pins[PIN_COUNT] = { {.number = 21}, {.number = 19} };
Setup
void setup(){
Serial.begin(115200); //Tempo para considerar a conexão como perdida client.setTimeout(5000); //Conectamos à rede WiFi e conectamos ao server setupWiFi(); connectClient(); for(int i=0; i
Setup WiFi
void setupWiFi()
{ Serial.print("Connecting to " + String(SSID)); //Conectamos à rede WiFi criado pelo outro ESP WiFi.begin(SSID, PASSWORD); //Esperamos conectar while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } //Se chegou aqui está conectado à rede WiFi Serial.println(); Serial.println("Connected!"); }
ConnectClient
void connectClient()
{ Serial.println("Connecting client"); //Esperamos conectar com o server while (!client.connect(WiFi.gatewayIP(), SERVER_PORT)) { Serial.print("."); delay(500); } //Se chegou aqui está conectado com o server Serial.println(); Serial.println("Client connected!"); }
Loop
void loop()
{ //Se não estiver conectado à rede WiFi, mandamos conectar if(WiFi.status() != WL_CONNECTED) { setupWiFi(); } }
HandleConnection
void handleConnection(void* pvParameters)
{ //IMPORTANTE: A tarefa não pode terminar, deve ficar presa em um loop infinito while(true) { //Se não estiver conectado com o server, mandamos conectar if(!client.connected()) { connectClient(); } //Para cada pino, verificamos se mudou o estado. Se mudou enviamos para o server o novo estado for(int i=0; i
hasPinStatusChanged
//Verifica se o estado do pino na posição 'i' do array mudou
//Retorna 'true' se mudou ou 'false' caso contrário boolean hasPinStatusChanged(int i) { //Faz a leitura do pino int pinStatus = digitalRead(pins[i].number); //Se o estado do pino for diferente if(pins[i].status != pinStatus) { //Guardamos o novo estado e retornamos true pins[i].status = pinStatus; return true; } //Só chegará aqui se o estado não foi alterado //Então retornamos falso return false; }
sendPinStatus
//Envia para o server os dados do pino na posição 'i' do array
void sendPinStatus(int i) { client.write((uint8_t*)&pins[i], sizeof(Pin)); client.flush(); }
Server.ino
Declarations and variables
#include <WiFi.h>
#include <vector> //Dados da rede //Deve ser igual no Client #define SSID "ESP32Server" #define PASSWORD "87654321" #define SERVER_PORT 5000 //Criamos um server na porta definida por 'SERVER_PORT' WiFiServer server(SERVER_PORT); //Vector onde vamos adicionar os clients conforme eles forem conectando std::vector clients; //Struct que define os dados que vamos enviar (deve ser igual no client) typedef struct{ int number; int status; }Pin;
Setup
void setup()
{ Serial.begin(115200); //Criamos a rede WiFi e iniciamos o server setupWiFi(); server.begin(); xTaskCreatePinnedToCore( handleClients, //Função que será executada "handleClients", //Nome da tarefa 10000, //Tamanho da pilha NULL, //Parâmetro da tarefa (no caso não usamos) 2, //Prioridade da tarefa NULL, //Caso queria manter uma referência para a tarefa que vai ser criada (no caso não precisamos) 0); //Número do core que será executada a tarefa (usamos o core 0 para o loop ficar livre com o core 1) }
SetupWiFi
void setupWiFi()
{ //Coloca este ESP como Access Point WiFi.mode(WIFI_AP); //SSID e Senha para se conectarem a este ESP WiFi.softAP(SSID, PASSWORD); }
Loop
void loop()
{ //Verifica se um novo client está tentando se conectar WiFiClient client = server.available(); //Se sim colocamos ele no vector if(client) { clients.push_back(client); } }
HandleClients
void handleClients(void* pvParameters)
{ //IMPORTANTE: A tarefa não pode terminar, deve ficar presa em um loop infinito while(true) { //Para cada client que temos no vector for(int i=0; i