banner

Ir para o Forum

Monitoramento de Data Center por IOT ESP32



Conhece o SNMP (Simple Network Management Protocol), em português: Protocolo Simples de Gerência de Rede? Utilizado para controlar serviços e equipamentos na internet, bem como para gerenciamento de dispositivos em redes IP, resolvi utilizá-lo em um projeto semelhante a um que eu já tinha desenvolvido: Controle Automático de Umidificador usando ESP32/8266.



Utilizando um ESP32 e um ESP8266, este segundo ligado a um aparelho umidificador através de um relé, estes ESPs se comunicam através do protocolo ESP-NOWÉ possível checar a temperatura e umidade de um ambiente, como um CPD, por exemplo, monitorando a rede com o SNMP.
O ESP32 vai ler umidade, temperatura e mostrar em um display Oled. Baseado na umidade, este mesmo microcontrolador vai, portanto, através do protocolo ESP-NOW, enviar sinal para um ESP8266 ligar ou desligar o relê. Verificaremos temperatura e umidade através do protocolo SNMP e alteraremos umidade máxima e mínima de acionamento do relê também utilizando o protocolo SNMP.


ESP32 Pinout




Montagem

Na montagem, como você pode ver na imagem, utilizamos também um DHT22.





Arquitetura SNMP

No protocolo SNMP, temos agentes que trocam mensagens de comando e de resposta.




Demonstração




SNMP

O SNMP (Simple Network Management Protocol) é um protocolo usado em sistemas de gerenciamento de redes para que se possa monitorar diversos dispositivos.



Biblioteca SimpleDHT

Na IDE do Arduino vá em Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Instale SimpleDHT




Biblioteca SSD1306

Na IDE do Arduino vá em Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Procure por SSD1306 e instale ESP8266 and ESP32 Oled Driver for SSD1306 display



Biblioteca ArduinoSNMP

Vá em https://github.com/fusionps/Arduino_SNMP faça o download do arquivo ZIP descompacte e copie para a pasta C:\Users\<SEU_USUARIO>\Documents\Arduino\libraries


Código Fonte

Neste projeto temos dois códigos fonte, sendo o primeiro do ESP32 e o segundo, do ESP8266, que fica ligado no relé de estado sólido.


ESP32_EspNow_Master.ino

Vamos incluir as bibliotecas e definir os pinos. Iniciamos o SMMPAgent.

#include <esp_now.h>
#include <WiFi.h>
#include <SimpleDHT.h>
#include <WiFiUdp.h>
#include <Arduino_SNMP.h>
#include <SSD1306.h>
#include <FS.h>
#include <SPIFFS.h>

#define DHTPIN 4
#define INTERVAL 100
#define ESPNOW_CHANNEL 1
#define CONFIG_PATH "/conf.bin"
#define SSID "SSID"
#define PASSWORD "12345678"
#define IP "192.168.0.134"

WiFiUDP udp;
SNMPAgent snmp = SNMPAgent("public");  //Inicia o SMMPAgent

//Referências para o SNMP
char* strHumidity;
char* strTemperature;

//Valores caso nada esteja salvo no arquivo de configuração
int maxHumidity = 65;
int minHumidity = 55;

Seguimos definindo parâmetros:

//parametros: address,SDA,SCL 
SSD1306 display(0x3c, 21, 22); //construtor do objeto que controlaremos o display
uint8_t slaveMacAddress[] = {0x1A,0xFE,0x34,0xA5,0x90,0x69};
// uint8_t slaveMacAddress[] = {0x18,0xFE,0x34,0xA5,0x90,0x69};

esp_now_peer_info_t slave;

//Objeto que realiza a leitura da umidade
SimpleDHT22 dht;

//Variável para guardarmos o valor da umidade
float humidity = 0;

//Variável para guardarmos o valor da temperatura
float temperature = 0;


No Setup, inicializamos o monitor serial e chamo a função para guardar as strings. Verifico a possibilidade de carregar o arquivo. Ainda inicializo aqui o WiFi, protocolo SNMP, Display, ESP-NOW e o Slave.

void setup() {
  Serial.begin(115200);

  strHumidity = (char*)malloc(6);
  strTemperature = (char*)malloc(6);
  memset(strHumidity, 0, 6);
  memset(strTemperature, 0, 6);

  if(SPIFFS.begin(true))
  {
    loadConfig();
  }
  else
  {
    //Se não conseguiu inicializar
    Serial.println("SPIFFS Mount Failed");
  }
  
  setupWiFi();
  setupSNMP();
  setupDisplay();
  setupESPNow();
  setupSlave();
}


Loop
No Loop, chamo as funções para leitura do sensor, verificação de SNMP, exibição no display, verificação de umidade e intervalo. 

void loop() {
  readSensor();
  verifySNMP();
  showOnDisplay();
  verifyHumidity();
  delay(INTERVAL);
}


SetupWiFi
Antes de tudo, vamos desconectar para limpar configurações e depois inicializar a rede.

void setupWiFi()
{
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);

  WiFi.begin(SSID, PASSWORD);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(SSID);

  //Configura o IP
  IPAddress ipAddress;
  ipAddress.fromString(IP);
  WiFi.config(ipAddress, WiFi.gatewayIP(), WiFi.subnetMask());

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}


SetupSNMP
Aqui inicializamos o SNMP e utilizamos o PEN 12345 apenas para testes. Para uma aplicação de verdade o correto seria registrar a aplicação em https://pen.iana.org/pen/PenApplication.page para não haver conflitos.

void setupSNMP()
{
  //Inicializa o snmp
  snmp.setUDP(&udp);
  snmp.begin();
  //Adiciona o OID para umidade (apenas leitura)
  snmp.addStringHandler(".1.3.6.1.4.1.12345.0", &strHumidity, false);
  //Adiciona o OID para temperatura (apenas leitura)
  snmp.addStringHandler(".1.3.6.1.4.1.12345.1", &strTemperature, false);
  //Adiciona o OID para umidade máxima (leitura e escrita)
  snmp.addIntegerHandler(".1.3.6.1.4.1.12345.2", &maxHumidity, true);
  //Adiciona o OID para umidade mínima (leitura e escrita)
  snmp.addIntegerHandler(".1.3.6.1.4.1.12345.3", &minHumidity, true);
}


SetupDisplay
Aqui inicializamos o display e configuramos a fonte.

void setupDisplay(){
  display.init(); //inicializa o display
  display.flipScreenVertically(); 
  display.setFont(ArialMT_Plain_10); //configura a fonte
}


SetupESPNow
Verificamos se a inicialização foi bem sucedida.

void setupESPNow() {
  //Se a inicialização foi bem sucedida
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  //Se houve erro na inicialização
  else {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}


SetupSlave
Adicionamos aqui o Slave. Caso você queira saber mais detalhes de ESP-NOW, recomendo este vídeo: ESP32 com Protocolo ESP-NOW.

void setupSlave(){
  slave.channel = ESPNOW_CHANNEL;
  //0 para não usar criptografia ou 1 para usar
  slave.encrypt = 0;
  //Copia o endereço do array para a estrutura do slave
  memcpy(slave.peer_addr, slaveMacAddress, 6);
  //Adiciona o slave
  esp_now_add_peer(&slave);
}


SendRelayStatus
Enviamos para o Slave o status atual do relé.

void sendRelayStatus(int relayStatus){
  //Envia para o slave o status atual do relê
  esp_err_t result = esp_now_send(slaveMacAddress, (uint8_t*)&relayStatus, 1);
}


VerifySNMP
Essa função deve ser sempre chamada durante o loop principal.

void verifySNMP()
{
  //Deve ser sempre chamado durante o loop principal
  snmp.loop();

  //Se aconteceu alteração de um dos valores
  if(snmp.setOccurred)
  {
    //Salva as os valores
    saveConfig();
    //Reseta a flag de alteração
    snmp.resetSetOccurred();
  }
}


VerifyHumidity
Verificamos se a umidade está fora dos limites e informamos ao ESP8266 se o relé deve ficar ligado ou desligado.

//Verifica se a umidade está fora dos limites e informa ao ESP8266 
//se o relê deve ficar ligado ou desligado
void verifyHumidity(){
  if(humidity > maxHumidity)
  {
    sendRelayStatus(LOW);
  }
  else if(humidity < minHumidity)
  {
    sendRelayStatus(HIGH);
  }
}


ReadSensor
Essa função é responsável por realizar a leitura da umidade e temperatura.

//Função responsável por realizar a leitura 
//da umidade e temperatura
void readSensor(){
  float h, t;
  int status = dht.read2(DHTPIN, &t, &h, NULL);
 
  if (status == SimpleDHTErrSuccess) {
    humidity = h;
    temperature = t;
    //Transforma os dados em string
    String strH = String(humidity);
    strH.toCharArray(strHumidity, strH.length());
    String strT = String(temperature);
    strT.toCharArray(strTemperature, strT.length());
  }
}


ShowOnDisplay
Trabalhamos aqui com a exibição dos dados no display.

//Mostra a umidade no display
void showOnDisplay(){
  //apaga o conteúdo do display
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);
  
  display.drawString(0, 0, "Humidity: ");
  display.drawString(70, 0, String(humidity));
  display.drawString(0, 30, "Temperat: ");
  display.drawString(75, 30, String(temperature));
  display.display(); //mostra o conteúdo na tela
  
}


SaveConfig
Nesta etapa, abrimos o arquivo para salvar as configurações.

void saveConfig()
{
  Serial.println("saveConfig");
   //Abre o arquivo para escrita
  File file = SPIFFS.open(CONFIG_PATH, FILE_WRITE);
  
  //Se não conseguiu abrir/criar o arquivo
  if(!file)
  {
    Serial.println("Failed to open file for writing");
    return;
  }

  file.seek(0);
  file.write((uint8_t*)&maxHumidity, sizeof(maxHumidity));
  file.write((uint8_t*)&minHumidity, sizeof(minHumidity));
  //Fecha o arquivo
  file.close();
}


LoadConfig
Aqui abrimos o arquivo para leitura.

void loadConfig()
{
  Serial.println("loadConfig");
  File file = SPIFFS.open(CONFIG_PATH, FILE_READ);
  
  //Se arquivo não existe
  if(!file)
  {
    //Na primeira vez o arquivo ainda não foi criado
    Serial.println("Failed to open file for reading");
    return;
  }

  file.read((uint8_t*)&maxHumidity, sizeof(maxHumidity));
  file.read((uint8_t*)&minHumidity, sizeof(minHumidity));
  //Fecha o arquivo
  file.close();
}


ESP8266_EspNow_Slave.ino – setup

Incluímos duas bibliotecas importantes aqui: do ESP-NOW e do ESP8266WiFi.

extern "C" {
  #include <espnow.h>
}

#include <ESP8266WiFi.h> 
#define RELAY_PIN D1


Setup
Colocamos o pino do relé como saída e com sinal baixo. Resetamos, então, as configurações da WiFi e colocamos em modo AP. Copiamos o endereço que aparece e colocamos no slaveMacAddress do Master.

void setup() {
  Serial.begin(115200);
  //Coloca o pino do relê como saída e coloca com sinal baixo
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH);

  //Reseta as configurações da WiFi
  WiFi.disconnect();
  //Coloca em modo AP
  WiFi.mode(WIFI_AP);

  setupESPNow();

  //Copiar o endereço que aparece aqui e colocar
  //no slaveMacAddress do Master
  Serial.print("AP MAC: "); 
  Serial.println(WiFi.softAPmacAddress());
}


SetupESPNow
Inicializamos o ESP-NOW e registramos a função que será executada quando novos dados chegarem.

void setupESPNow(){
  //Inicializa o ESPNOW
  if (esp_now_init()!=0) {
    Serial.println("EspNow init failed");
    ESP.restart();
  }

  //0=IDLE, 1=MASTER, 2=SLAVE and 3=MASTER+SLAVE
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  //Registra a função que será executada quando novos
  //dados chegarem
  esp_now_register_recv_cb(receiveCallback);
}


ReceiveCallback
Esta função coleta as mensagens do ESP-NOW e executa a ação de ligar ou de desligar o umidificador.

//Função que será executada quando chegarem novos dados
void receiveCallback(uint8_t *mac, uint8_t *data, uint8_t len) {
  int relayStatus = data[0];
  Serial.println("Received " + String(relayStatus));
  digitalWrite(RELAY_PIN, !relayStatus);
}


Loop
Neste código não temos nada para fazer no loop já que as informações são recebidas pelo receiveCallback automaticamente quando novos dados chegam.

//Nada para fazer no loop já que as informações 
//são recebidas pelo receiveCallback
//automaticamente quando novos dados chegam
void loop() {
   
}


NET SNMP

Vá para https://sourceforge.net/projects/net-snmp/files/net-snmp/ e instale o Net SNMP.
Digite no cmd ou terminal:
snmpget -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.0 para verificar o valor da umidade
snmpget -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.1 para verificar o valor da temperature
snmpget -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.2 para verificar a umidade máxima
snmpget -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.3 para verificar a umidade minima
snmpwalk -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345 para verificar todos a partir do 12345
snmpset -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.2 i 75 para alterar o valor da umidade máxima
para 75 (ou substitua 75 por qualquer outro valor maior que a umidade mínima)
snmpset -v 1 -c public 192.168.0.134 1.3.6.1.4.1.12345.3 i 45 para alterar o valor da umidade mínima
para 45 (ou substitua 45 por qualquer outro valor menor que a umidade máxima)




POWER SNMP

Vá para http://www.dart.com/snmp-free-manager.aspx e baixe o power snmp. Instale e execute o
Programa. Clique com o botão esquerdo do mouse em SNMP Agents e clique em Add Agent…


Vá para http://www.dart.com/snmp-free-manager.aspx e baixe o power snmp. Instale e execute o
Programa. Clique com o botão direito do mouse em SNMP Agents e clique em Add Agent…


Clique em Add Agent


Digite o ip e deixe a porta como 161. Clique em OK nesta janela e na próxima


Deverá aprecer o IP na lista do lado esquerdo do programa. Clique com o botão direito do mouse e escolha Add Watch...


Em variable IID digite 1.3.6.1.4.1.12345.0. Em update interval coloque o tempo de cada verificação. No exemplo eixamos para verificar de 1 em 1 segundo. Clique em Add.


O valor da umidade deverá aparecer. Agora repita o processo para as variáveis 1.3.6.1.4.1.12345.1, 1.3.6.1.4.1.12345.2 e 1.3.6.1.4.1.12345.3.





Faça o download dos arquivos:



Um comentário:

  1. Sugestão: Usando framework ESP-IDF poderia ser melhor para gerenciamento de memoria dinâmica e prioridades entre outros serviços para alem do SMNP.

    ResponderExcluir

Tecnologia do Blogger.