Skip to main content

9758

#include <stdio.h>
#include <WiFi.h>
#include <MQTT.h>
#include <SPI.h>
#include "DallasTemperature.h"
#include "EmonLib.h"
#include <PubSubClient.h>
#include <time.h>
#include <ArduinoJson.h>
#include "ESPDateTime.h"
#include <esp_task_wdt.h> //Biblioteca do watchdog
//#define MDASH_APP_NAME "BLE_31364"
//#include <mDash.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>


void BLE();
void connect2();
void HoraData1();
void HoraData2();
void Temperaturas();
void conectarEnviar();
void Correntes();
void Tensoes();
void DHCP();

//***********Define o nome da rede, senha para conexão e os endereços para conexão********************

const char* rede = "SmartVac Telemetria";
const char* senha = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; procurar
const char* SERVIDOR = "web.smartvac.app"; 
int PORTA = 1883;
 
//***************************************Define os itens do MQTT **************************************

WiFiClient Client;
PubSubClient MQTT(Client);

//***************Definição dos pinos para os sensores de temperatura, corrente e tensão****************

#define ONE_WIRE_BUS_PINA   14   // Temperatura
#define ONE_WIRE_BUS_PINB   36   // Temperatura

#define PIN_CURR_R             34   // Corrente R
#define PIN_CURR_S             36  // Corrente S
#define PIN_CURR_T             39   // Corrente T

#define PIN_VOLT_R             35   // Tensão R
#define PIN_VOLT_S             32   // Tensão S
#define PIN_VOLT_T             33   // Tensão T


//#define DEVICE_PASSWORD    "oh099QByIVRdERWq4CRijnA"

//******************************Variaveis Globais******************************************************
    
float TempIns;
float TempRet;
float TempSuc;
float TempDes;
float TempExt;
float TempExt2;
float BLERet;
float BLESuc;
float BLEIns;
float BLELinha;
float BLEExt;

float BLEX;
float BLEY;
float BLEZ;

float Bat_ins;
float Bat_ret;
float Bat_linha;
float Bat_suc;
float Bat_ext;


uint16_t voltage;
int16_t accX;
int16_t accY;
int16_t accZ;




std::map<std::string, float> macTemperatures;

time_t timer;
time_t timeStemp;
int diferenca=0;
int difOitoHoras=0;

//***************************Abre a instância OneWire***************************************

OneWire oneWireA(ONE_WIRE_BUS_PINA);
OneWire oneWireB(ONE_WIRE_BUS_PINB);

//*****************Passagem de dados do one wire para o Dallas******************************

DallasTemperature sensorsA(&oneWireA);
DallasTemperature sensorsB(&oneWireB);

// Declaração das variaveis para medição de corrente e tensão

EnergyMonitor emon1,emon2,emon3,emon4,emon5,emon6;

double Irms1,Irms2, Irms3;
double Vrms4, Vrms5, Vrms6;

//****************************Calibração***************************************************

#define VOLT_CAL1 263.38 //VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)
#define VOLT_CAL2 0000 //VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)
#define VOLT_CAL3 0000  //VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)
#define CURR_CAL1 17.88   //17.7VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)
#define CURR_CAL2 00000 //VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)
#define CURR_CAL3 0000 //VALOR DE CALIBRAÇÃO (DEVE SER AJUSTADO EM PARALELO COM UM MULTÍMETRO)

//*****************Declaração endereço sensores de temperatura******************************

DeviceAddress Probe01 = { 0x28, 0x6F, 0x2A, 0x95, 0xF0, 0x01, 0x3C, 0x88  }; //Insuflamento
DeviceAddress Probe02 = { 0x28, 0xAD, 0xD3, 0x56, 0xB5, 0x01, 0x3C, 0x99  }; //Retorno
DeviceAddress Probe03 = { 0x28, 0x7D, 0x6D, 0x95, 0xF0, 0x01, 0x3C, 0x05  }; //Sucção 
DeviceAddress Probe04 = { 0x28, 0xC1, 0x30, 0x95, 0xF0, 0x01, 0x3C, 0x06  }; //Descarga
DeviceAddress Probe05 = { 0x28, 0x9C, 0x44, 0x56, 0xB5, 0x01, 0x3C, 0xA5  }; //Externa
DeviceAddress Probe06 = { 0x28, 0xC9, 0x27, 0x95, 0xF0, 0x01, 0x3C, 0x8A  }; //Externa Reserva (entrada do condensador) 

//*****************Setup do hardware********************************************************


BLEScan* pBLEScan;

/*----------------------------------------------------------------------------------------------------------------
// Lista de sensores BLE. SEMPRE SEGUIR A ORDEM: Insuflamento, Retorno, Sucção, Linha de Líquido/Descarga, Externa.
--------------------------------------------------------------------------------------------------------------------*/
std::string macAddresses[] = {
    "bc:57:29:0e:2e:c1", //Insuflamento
    "bc:57:29:0e:19:9d", //Retorno
    "bc:57:29:0e:25:e9", // Sucção
    "bc:57:29:0e:26:10", // Linha De Líquido/ Descarga
    "bc:57:29:0e:26:2b" //Externa
};

// Keep track of the current MAC address index we are looking for
int currentMacIndex = 0;
const int numMacAddresses = sizeof(macAddresses) / sizeof(macAddresses[0]);

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
        std::string strServiceData = advertisedDevice.getServiceData();
        std::string mac = advertisedDevice.getAddress().toString();

 
        
        // Only proceed if the MAC address matches the current one we are looking for
        if(mac == macAddresses[currentMacIndex]){
            uint8_t* payload = (uint8_t*)strServiceData.c_str();
            int len = strServiceData.length();

            Serial.print("Received payload from ");
            Serial.print(mac.c_str());
            Serial.print(": ");
            for(int i = 0; i < len; i++){
                if(payload[i] < 16) Serial.print("0");  // If less than 16, prepend with '0' to maintain 2 hex digits
                Serial.print(payload[i], HEX);
            }
            Serial.println();

            int offset = 2; // Starting offset after frame type and version tag

            uint8_t sensorMask = payload[offset++];
            if(sensorMask & 0x01) { // Voltage
                uint16_t voltage = (payload[offset] << 8) | payload[offset + 1];
                offset += 2;
                Serial.print("Voltage: ");
                Serial.print(voltage);
                Serial.println(" mV");
                    if (mac == macAddresses[0]) { //Insuflamento
                     
                      Bat_ins = voltage;
                  }
                  else if (mac == macAddresses[1]) { //Retorno
                      
                      Bat_ret = voltage;
                  }
                    else if (mac == macAddresses[2]) { //Sucção
                      
                      Bat_suc = voltage;
                  }
                    else if (mac == macAddresses[3]) { //Linha de liquido
                    
                     Bat_linha = voltage;
                    }

                    else if (mac == macAddresses[4]) { //Externa
                    
                     Bat_ext = voltage;
                    }
            }

            if(sensorMask & 0x02) { // Temperature
                uint16_t tempRaw = (payload[offset] << 8) | payload[offset + 1];
                float temp = tempRaw / 256.0;
                offset += 2;
                Serial.print("Temperature: ");
                Serial.print(temp);
                Serial.println(" °C");
                  if (mac == macAddresses[0]) { //Insuflamento
                     // ArraySensores[0] = temp;
                      BLEIns = temp;
                  }
                  else if (mac == macAddresses[1]) { //Retorno
                      
                      BLERet = temp;
                  }
                    else if (mac == macAddresses[2]) { //Sucção
                      
                      BLESuc = temp;
                  }
                    else if (mac == macAddresses[3]) { //Linha de liquido
                    
                     BLELinha = temp;
                    }

                    else if (mac == macAddresses[4]) { //Externa
                    
                     BLEExt = temp;
                    }
            }

            if(sensorMask & 0x08) { // Acceleration
                int16_t accX = (payload[offset] << 8) | payload[offset + 1];
                offset += 2;
                int16_t accY = (payload[offset] << 8) | payload[offset + 1];
                offset += 2;
                int16_t accZ = (payload[offset] << 8) | payload[offset + 1];
                offset += 2;
                Serial.print("Acceleration - X: ");
                Serial.print(accX);
                Serial.println(" mg");
                Serial.print("Y: ");
                Serial.print(accY);
                Serial.println(" mg");
                Serial.print("Z: ");
                Serial.print(accZ);
                Serial.println(" mg");

                if (mac == macAddresses[3]) // Se for o sensor de sucção, lê as vibrações
                {
                    
                      BLEX = accX;
                      BLEY = accY;
                      BLEZ = accZ;
    
                 }
            }
            
            Serial.println("--------------------"); // Separator for readability
            
            // Move to the next MAC address in the list
            currentMacIndex = (currentMacIndex + 1) % numMacAddresses;
        }
    }
   
};
void setup() {

  // Serial para leitura dos dados

  Serial.begin(115200);

  // Inicia o Wifi
  WiFi.mode(WIFI_STA);
  WiFi.begin(rede, senha);

  //Inicia o password do MDash
  //mDashBegin(DEVICE_PASSWORD);

  // Estabelece o DHCP para conexão com ip dinâmico
  DHCP();
  
  //Inicia sensores
  sensorsA.begin();
  sensorsB.begin(); 

  // Seta a resolução do sensor, menor mais rápido
  sensorsA.setResolution(Probe01, 12);
  sensorsA.setResolution(Probe02, 12);
  sensorsB.setResolution(Probe03, 12);
  sensorsB.setResolution(Probe04, 12);
  sensorsA.setResolution(Probe05, 12);
  sensorsB.setResolution(Probe06, 12);

 // Define os pinos e resolução do sensor de corrente 
  emon1.current(PIN_CURR_R, CURR_CAL1);       // Current: input pin, calibration. Cur Const= Ratio/BurdenR. 1800/62 = 29.
  emon2.current(PIN_CURR_S, CURR_CAL2);       // Current: input pin, calibration. Cur Const= Ratio/BurdenR. 1800/62 = 29.
  emon3.current(PIN_CURR_T, CURR_CAL3);       // Current: input pin, calibration. Cur Const= Ratio/BurdenR. 1800/62 = 29.
 
  // Definição do pino para tensão
  emon4.voltage(PIN_VOLT_R, VOLT_CAL1, 1.7); //PASSA PARA A FUNÇÃO OS PARÂMETROS (PINO ANALÓGIO / VALOR DE CALIBRAÇÃO / MUDANÇA DE FASE)  
  emon5.voltage(PIN_VOLT_S, VOLT_CAL2, 1.7); //PASSA PARA A FUNÇÃO OS PARÂMETROS (PINO ANALÓGIO / VALOR DE CALIBRAÇÃO / MUDANÇA DE FASE)  
  emon6.voltage(PIN_VOLT_T, VOLT_CAL3, 1.7); //PASSA PARA A FUNÇÃO OS PARÂMETROS (PINO ANALÓGIO / VALOR DE CALIBRAÇÃO / MUDANÇA DE FASE)  


//********************************************************************
  //Indica para o objeto "MQTT" em que servidor e em que porta iremos nos conectar
 
   MQTT.setServer(SERVIDOR,PORTA);
   MQTT.setCallback(mqtt_callback);

   connect2();

   // Inicia o timer
   HoraData1();

   //Watchdog
   esp_task_wdt_init(10800, true);
   esp_task_wdt_add(NULL);
   
   //BLE
    BLEDevice::init("");
    pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);
    pBLEScan->setInterval(100);
    pBLEScan->setWindow(99);
  }


//*****************Função loop***********************************************************
 
void loop() {

  conectarEnviar();
  
  }


//*****************Função do timer********************************************************
  
void HoraData1()
{

   const char tenn[]="CST-3";
   DateTime.setTimeZone(tenn);
   DateTime.setServer("ntp02.oal.ul.pt");
   DateTime.begin();   
   int timer = DateTime.getTime();
   
   timeval tv;//Cria a estrutura temporaria para funcao abaixo.
   tv.tv_sec = timer;//Atribui minha data atual.
   settimeofday(&tv, NULL);//Atualiza a data e hora
  
   //String hora = String(String(dia) + String("/") + String(mes) + String("/") + String(ano) + String("  ") + String(hora) + String(":") + String(minuto) + String(":") + String(segundo));

}

//*****************Função do timer ****************************************************************************

void HoraData2()
{

   struct tm data;

   time_t tt = time(NULL);//Obtem o tempo atual em segundos. Utilize isso sempre que precisar obter o tempo atual
   //data = *gmtime(&tt);//Converte o tempo atual e atribui na estrutura

   diferenca=tt-timeStemp;//faz a conta para verificar se a diferença é de 2 segundos para os envios

   difOitoHoras=tt-timer; //faz a conta para verificar se a diferença é de 28800 segundos para os envios


   timeStemp=tt;
   
}
//*****************Função para publicar em formato JSON********************************************************

void Publish() {
  
JsonDocument doc1;
//  StaticJsonDocument<300> doc;

doc1["t"] = timeStemp;
doc1["s91372"] = Irms1; 
//doc1["s91345"] = Irms2; 
//doc1["s91346"] = Irms3; 
doc1["s91371"] = Vrms4; 
//doc1["s91342"] = Vrms5; 
//doc1["s91343"] = Vrms6;
doc1["s91373"] = BLEX;


String STD1;

JsonDocument doc2;
doc2["t"] = timeStemp;
doc2["s91367"] = BLEIns;
doc2["s91368"] = BLERet;
doc2["s91369"] = BLESuc;
doc2["s91370"] = BLELinha; 
doc2["s91380"] = BLEExt;
doc2["s91374"] = BLEY;
doc2["s91375"] = BLEZ;

String STD2;

JsonDocument doc3;
doc3["t"] = timeStemp;
doc3["s91376"] = Bat_ins;
doc3["s91377c"] = Bat_ret;
doc3["s91378"] = Bat_suc;
doc3["s91379"] = Bat_linha;
//doc3["bat_ext"] = Bat_ext;

String STD3;

serializeJson(doc1, STD1);  
serializeJson(doc2, STD2);  
serializeJson(doc3, STD3);
Serial.println (STD1);
Serial.println (STD2);
Serial.println (STD3);



//*****************MQTT.publish aceita apenas char, as próximas linhas convertem a string em char*****************

    int tamanho = STD1.length() + 1;    //Define o tamanho da String
    char mensa1[tamanho];               //Cria um array de char com o tamanho da String
    STD1.toCharArray(mensa1, tamanho);   //Converte a String  para char e atribui os valores ao array
   
    int tamanho2 = STD2.length() + 1;    //Define o tamanho da String
    char mensa2[tamanho2];               //Cria um array de char com o tamanho da String
    STD2.toCharArray(mensa2, tamanho2);   //Converte a String  para char e atribui os valores ao array
    
    int tamanho3 = STD3.length() + 1;    //Define o tamanho da String
    char mensa3[tamanho3];               //Cria um array de char com o tamanho da String
    STD3.toCharArray(mensa3, tamanho3);   //Converte a String  para char e atribui os valores ao array

   

//****************************************************************************************************************
    MQTT.publish("v4/matr0541",mensa1); // Envio de dados para determinado lugar do tópico
    delay (1000);
    MQTT.publish("v4/matr0541",mensa2); // Envio de dados para determinado lugar do tópico
    delay (1000);
    MQTT.publish("v4/matr0541",mensa3); // Envio de dados para determinado lugar do tópico
    delay (1000);
    Serial.println("Enviou");

    delay(60000);

   }


//*****************Função de conexão no MQTT**********************************************************************


void conectarEnviar()  {

    
     MQTT.loop();

     if (WiFi.status() == WL_CONNECTED && MQTT.connected()) {
      
     Serial.println("------------------");
     Serial.println("Wifi conectado e servidor conectados");
     Serial.println("------------------");

     // Calcula a ultima atualização horária e roda as leituras
     if(difOitoHoras > 28600)
     {
      
      HoraData1();
      Tensoes();
      Temperaturas();
      Correntes();
      BLE();
      Publish();

      difOitoHoras=0;
      
     }
     else
     {
    
     HoraData2();

     if(diferenca>2)
     {
      
     Tensoes();
     Temperaturas();
     Correntes();
   BLE();
     Publish();
     
     }
     }
     
     }   
     else if(WiFi.status() != WL_CONNECTED || !MQTT.connected())
     {   
     Serial.println("------------------");
     Serial.println("Wifi ou servidor desconectado");
     Serial.println("------------------");
     
     DHCP();
     connect2();
     
     }
  }


//*****************Função de leitura das temperaturas********************************************************

void Temperaturas() {
 
  sensorsA.requestTemperatures();
  sensorsB.requestTemperatures();

 // Serial.println("######TEMPERATURAS######");

  TempIns = (sensorsA.getTempC(Probe01));
  //Serial.print("Insuflamento: ");
  //Serial.print(TempIns);
  //Serial.println("°C");
    
  TempRet = (sensorsA.getTempC(Probe02));
  //Serial.print("Retorno: ");
  //Serial.print(TempRet);
  //Serial.println("°C");

  TempSuc = (sensorsB.getTempC(Probe03));
  //Serial.print("Sucção: ");
  //Serial.print(TempSuc);
  //Serial.println("°C");
  
  TempDes = (sensorsB.getTempC(Probe04));
  //Serial.print("Descarga: ");
  //Serial.print(TempDes);
  //Serial.println("°C");
  
  TempExt = (sensorsA.getTempC(Probe05));
  //Serial.print("Externa: ");
  //Serial.print(TempExt);
  //Serial.println("°C");
  
  TempExt2 = (sensorsB.getTempC(Probe06));
  //Serial.print("Retorno Condensador: ");
  //Serial.print(TempExt2);
  //Serial.println("°C");

}   

//*****************Função de leitura das correntes********************************************************

void Correntes() {
  
  Irms1 = emon1.calcIrms(1996);//Para 50Hz 1480 e para 60Hz 1996
  Irms2 = emon2.calcIrms(1996);//Para 50Hz 1480 e para 60Hz 1996
  Irms3 = emon3.calcIrms(1996);//Para 50Hz 1480 e para 60Hz 1996
  
}

//*****************Função de leitura das tensões**********************************************************

void Tensoes() 
{
  
emon4.calcVI(17,1000); //FUNÇÃO DE CÁLCULO (17 SEMICICLOS, TEMPO LIMITE PARA FAZER A MEDIÇÃO)
  Vrms4 = emon4.Vrms;    //VARIÁVEL RECEBE O VALOR DE TENSÃO RMS OBTIDO

  emon5.calcVI(17,1000); //FUNÇÃO DE CÁLCULO (17 SEMICICLOS, TEMPO LIMITE PARA FAZER A MEDIÇÃO)
  Vrms5 = emon5.Vrms;    //VARIÁVEL RECEBE O VALOR DE TENSÃO RMS OBTIDO

  emon6.calcVI(17,1000); //FUNÇÃO DE CÁLCULO (17 SEMICICLOS, TEMPO LIMITE PARA FAZER A MEDIÇÃO)
  Vrms6 = emon6.Vrms;    //VARIÁVEL RECEBE O VALOR DE TENSÃO RMS OBTIDO          

}

//*********************Função de leitura BLE*************************************************************

void BLE() {

  // Início da varredura BLE
  BLEScanResults foundDevices = pBLEScan->start(5, false);

  // Limpa os resultados da varredura BLE
  pBLEScan->clearResults();
}


 

//*****************Função de login e conexão MQTT********************************************************

void connect2() {

int cont=0;
    
    while (!MQTT.connect("9758", "matr4", "canudos92sc")) 
    {
        Serial.println("* Tentando se conectar ao Broker MQTT: ");
        if (MQTT.connect("9758", "matr4", "canudos92sc")) 
        {
            Serial.println("Conectado com sucesso ao broker MQTT!");
            MQTT.subscribe("/v4/matr0541"); 
        } 
        else
        {
            Serial.println("Falha ao reconectar no broker.");
            Serial.println("Havera nova tentativa de conexao em 1s");
            delay(1000);
            
            cont++;

            if(WiFi.status() != WL_CONNECTED && cont<10)
            {
            DHCP();
            }
            else
            {
            cont=0;
            Serial.println("Teste");
            }
        }
    }
}

//*****************Função de callback do servidor********************************************************

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);      // Lê o que o servidor envia

  MQTT.setCallback(mqtt_callback);
}


void mqtt_callback(char* topic, byte* payload, unsigned int length) 
{
    String msg;
 
    //obtem a string do payload recebido
    for(int i = 0; i < length; i++) 
    {
       char c = (char)payload[i];
       msg += c;
    }
    Serial.print("[MQTT] Mensagem recebida: ");
    Serial.println(msg);     
}


//*****************Função do DHCP IP Dinâmico********************************************************

void DHCP()
{
 
  if(WiFi.status() != WL_CONNECTED) {
    Serial.println("Reconectando no wifi...");
    WiFi.disconnect();
    WiFi.reconnect();
    delay(500);
  }
  else if(WiFi.status() == WL_CONNECTED)
  {
    return;
  }
}


//*****************************************