Pular para o conteúdo

MySQL com Arduino ESP8266, ESP32…

MySQL com Arduino

Quer conectar a uma base de dados MySQL com Arduino ou outra MCU? Sem problemas! Bom, na verdade tem “muitos” problemas, por isso, como sysadmin, engenheiro de redes e segurança e SRE, afirmo categoricamente: Não faça isso e, se fizer, não sugira que eu o induzi a fazer.

Segurança

Primeiramente, não se conecta diretamente a uma base de dados. Em datacenters, duas formas de fazer uma interação com o banco são instalando a aplicação no mesmo computador em que está a base de dados ou, em sistemas grandes “clusterizados”, com isolamento do ambiente, onde um conjunto de procedimentos físicos e lógicos isolam o banco, dando acesso “apenas” ao computador da aplicação que pode (ou não) estar na mesma rede, mas jamais na Internet. O banco de dados é a “espinha dorsal” da empresa.

MySQL com Arduino

É proibido? – Não, o banco de dados é seu, então pode destruir. Mas nenhuma ideia pode ser pior do que acessar um banco de dados usando uma MCU qualquer. Ainda assim quer fazer? Então vamos lá.

Instale a biblioteca MySQL_MariaDB_Generic. Se for realmente usar um Arduino, então faça interface com algo que lhe dê o acesso à Internet, seja um ESP-01 (como nesse exemplo) ou um ethernet shield (como nesse exemplo, ou esse).

No código, precisaremos especificar algumas variáveis, como usuário, senha, ip do MySQL e criar um array para a query. Só que a query não tem tamanho fixo normalmente, portanto devemos fazer alocação dinâmica. Escrevi uma série de artigos falando sobre ponteiros, vou deixar alguns:

Como criar arrays dinâmicos em C++

Ponteiros em C++

Interagir com ponteiros em C++

Alocação de memória em C++

Porém, temos a API em C++ e o objeto String, então fica menos trabalhoso compor uma query. Tendo deixado tudo claro em relação à segurança, sigamos.

Configurar MariaDB para aceitar conexões externas

Se não leu acima e pulou direto para cá, leia o texto anterior antes de seguir.

Se ainda não tem uma base de dados instalada, sugiro o mesmo procedimento para Linux e Windows – claro, no Windows, usando o WSL. Não sabe o que é o WSL? Nesse vídeo eu demonstro e falo da instalação. É fácil e vai tornar todos os tutoriais do blog compatíveis com o Windows.

Tendo o WSL, abra o Ubuntu e digite:

sudo su (vai pedir senha. Ao digitar, ficará invisível)
apt-get update
apt-get install mariadb-server
mysql_secure_installation

Ao digitar o último comando, um prompt com perguntas se abrirá. Pode escolher N para a primeira e segunda questão e o resto é só apertar Enter.

Por padrão não é necessário sequer uma senha pra acessar localmente como root, porém, para acessar externamente, algumas configurações são necessárias. Se seu banco de dados está no ponto para receber conexão externa, pule essa parte, senão, inicie criando sua base de dados, tabela, dê as permissões etc. Para isso, após se conectar à base, digite essa série de comandos:

sudo su #digite a senha, que deve ser invisível
mariadb #ao pressionar enter, entrará no prompt do MariaDB
create database dobitaobyte; #crie a sua, claro
create table mcu(name varchar(20), value int); #crie sua tabela como desejar
create user 'espressif'@'localhost' identified by 'esp32';
grant all privileges on *.* to 'espressif'@'%' identified by 'esp32' with grant option;
flush privileges;

A sequência acima cria a base de dados dobitaobyte, cria uma tabela chamada mcu que aceita nome de identificação com até 20 bytes e recebe um valor inteiro. Daí poderíamos criar chave primária, definir se os campos não podem ser NULL, se teria valor default etc. Estamos fazendo o básico do básico aqui.

Criada a tabela, precisamos criar o usuário que poderá acessar externamente o banco. No caso, criei um para receber dados de um ESP32, cujo usuário chamei de espressif, criado em localhost (ou, 127.0.0.1, se preferir) e com a senha esp32.

Em seguida, foi garantida todas as permissões em qualquer base e qualquer tabela para esse usuário, vindo de qualquer origem (‘%’ significa qualquer origem), identificado pela senha do usuário criado. Por fim, um flush dos privilégios e tudo estará devidamente aplicado. Mas não basta. Se a base for MySQL, talvez haja uma pequena diferença na próxima configuração. Lembre-se de que o tutorial usa MariaDB, que é um fork do MySQL.

Não importa onde esteja instalado o banco de dados; Linux, Windows ou MacOS. Entre no diretório de configurações da base de dados e edite o arquivo my.cnf. No Linux, fica em /etc/mysql/my.cnf. O arquivo terá o mesmo nome, sendo ou não o MariaDB. Edite o arquivo e crie a sessão a seguir, caso não exista. Se já existir, adicione apenas o bind-address, como abaixo:

[mysqld]
bind-address = 0.0.0.0

Se já existir um bind-address com o endereço 127.0.0.1, substitua o endereço por 0.0.0.0 para que fique como acima. Hora de reiniciar o serviço. No Linux (ou no Windows, usando WSL) faça:

sudo systemctl restart mariadb

No Linux (ou no Windows, usando WSL), verifique se o serviço está rodando e escutando em 0.0.0.0 na porta 3306:

Finalizamos a destruição da segurança. Agora podemos partir para o código na MCU.

Conectando ao MySQL com Arduino ou outra MCU

Eu vou utilizar ESP32 por razões claras; ele tem WiFi, não vou precisar configurar ethernet shield e com isso economizo tempo e código. Estou utilizando a placa chamada de “downloader”, onde simplesmente encaixamos o ESP32-S ou WROVER, gravamos, testamos e podemos colecionar nossos projetos em diferentes MCUs. Um espetáculo! Essa placa você encontra na Saravati, conheça esse parque de diversões. É um “shopping” dos embarcados!

Instalar driver para CP2104 USB Bridge UART no Windows

Ao precisar instalar um driver, me lembrou 1998. Desde aquela época o Windows é o mesmo. Como foi a primeira vez que usei uma MCU com esse componente, tive que seguir o estranho processo de instalar driver – coisa que raramente acontece usando Linux.

O driver CP2104 não está disponível por padrão, então baixe desse link, descomprimi o diretório em Downloads e abri o gerenciador de dispositivos. Aparecerá um dispositivo com um triângulo amarelo. Clique sobre ele duas vezes e na janela que abrir, clique em Atualizar Driver. Selecione a opção de “Procurar no meu computador” e aponte o diretório recém extraído.

Código para conectar ao MySQL com ESP32

Preciso deixar claro que optei pelo ESP32 para facilitar. Também, preciso deixar claro que usei como base um código de exemplo, adicionando apenas a geração de números randômicos e também dei uma “ajeitada” na query pra atender os critérios da base criada.

#include "Credentials.h"

#define MYSQL_DEBUG_PORT    Serial
#define _MYSQL_LOGLEVEL_    1

#include <MySQL_Generic.h>

IPAddress server(192, 168, 15, 133); //TROQUE PELO IP DA SUA BASE SQL


uint16_t server_port = 3306;

MySQL_Connection conn((Client *)&client);
MySQL_Query *query_mem;

void setup(){
  Serial.begin(115200);
  while (!Serial && millis() < 5000); // wait for serial port to connect

  MYSQL_DISPLAY1("\nInitializing ", ARDUINO_BOARD);
  MYSQL_DISPLAY(MYSQL_MARIADB_GENERIC_VERSION);
  MYSQL_DISPLAY1("Connecting to", ssid);
  
  WiFi.begin(ssid, pass);
  
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    MYSQL_DISPLAY0(".");
  }

  MYSQL_DISPLAY1("Connected to network. My IP address is:", WiFi.localIP());
  MYSQL_DISPLAY3("Connecting to SQL Server @", server, ", Port =", server_port);
}

void runInsert(){
  long rand_val = random(0,500);
  // Initiate the query class instance
  MySQL_Query query_mem = MySQL_Query(&conn);

  if (conn.connected()){
    /*Aqui voce popde compor sua query como desejar, basta que a tabela comporte a string, como se fosse uma query local*/
    String sql_query = "insert into dobitaobyte.mcu(name,value) values('esp32'," + String(rand_val) + ");";
    MYSQL_DISPLAY(sql_query);

    if (!query_mem.execute(sql_query.c_str())){
      MYSQL_DISPLAY("Insert error");
    }
    else{
      MYSQL_DISPLAY("Data Inserted.");
    }
  }
  else{
    MYSQL_DISPLAY("Disconnected from Server. Can't insert.");
  }
}

void loop(){
  MYSQL_DISPLAY("Connecting...");
  
  //if (conn.connect(server, server_port, user, password))
  if (conn.connectNonBlocking(server, server_port, user, password) != RESULT_FAIL){
    delay(500);
    runInsert();
    conn.close(); 
  } 
  else{
    MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration.");
  }

  MYSQL_DISPLAY("\nSleeping...");
  MYSQL_DISPLAY("================================================");
 
  delay(60000);
}

O arquivo Credentials.h deve conter o seguinte código:

#ifndef Credentials_h
#define Credentials_h

char ssid[] = "SuaRedeWiFi";            
char pass[] = "suaSenhaWiFi";        

char user[]         = "espressif"; // "espressif" foi o usuário criado no início
char password[]     = "esp32";     // senha criada com o usuário

#endif    //Credentials_h

Conclusão e vídeo

Farei um vídeo apresentando rapidamente esse tutorial, então, se não é inscrito ainda, inscreva-se em nosso canal DobitaobyteBrasil no Youtube.

E finalizo falando da última falha de segurança. Para mostrar de forma transparente na imagem de destaque, utilizei a senha como parâmetro. Isso é outra coisa que não se faz, porque o histórico do terminal deixará a senha registrada e qualquer pessoa poderá ver.

Usei “MySQL com Arduino” no título porque MariaDB é um fork do MySQL e é uma base de dados padrão nos repositórios de pacotes do Linux. Fiz a instalação no Windows, usando WSL, como recomendado no vídeo do link mais acima. Usei “MySQL com Arduino” apenas pela palavra chave, porque atualmente não vale a pena fazer projetos com MCUs de 8bits. Isso é passado, bem passado.

Se for para testar ou exibir, tudo bem, mas não use isso em produção, porque é extremamente vulnerável, interceptável, volátil, é uma tarefa excessiva para uma MCU, é incabível do ponto de vista de segurança e uma vergonha que deve ser guardada em segredo. Se seu cliente faz questão, sugiro que o faça assinar um documento que isente você de responsabilidade das inevitáveis consequências.

Outra falha de segurança é trafegar os dados através de WiFi, ainda por cima WiFi 2.4GHz, que pode facilmente ser derrubado com o recurso desse artigo – que aliás, pode ser usado como forma de convencimento para que não se use isso como solução profissional. Me exima de culpa quando sua implementação baseada nesse tutorial causar um problema.

Sair da versão mobile