#define DHTPIN 2
#define DHTTYPE DHT22
#define rojo 13
#define verde 12
#define azul 14
#define ENCODER_CLK 27
#include<Wire.h>
#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <ArduinoOTA.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "mqtt.thingsboard.cloud";
const int mqttPort = 1883;
const char* mqttUser = "amerejil"; //User name
const char* mqttPassword = "amerejil"; //Password
const char* mqttClient = "amerejil_test"; //ID
WiFiClient espClient;
PubSubClient client(espClient);
const int capacity = JSON_OBJECT_SIZE(21);
StaticJsonDocument<capacity> doc;
//---------- MPU6050 Measurement & Filtering Range ----------------------------------------------
#define AFS_SEL 2 // Accelerometer Configuration Settings AFS_SEL=2, Full Scale Range = +/- 8 [g]
#define DLPF_SEL 0 // DLPF Configuration Settings Accel BW 260Hz, Delay 0ms / Gyro BW 256Hz, Delay 0.98ms, Fs 8KHz
//---------- Variables for gravity --------------------------------------------------------------
const int MPU_ADDR=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ; // Accelerometer values
long Cal_AcX, Cal_AcY, Cal_AcZ; // Calibration values
float GAcX, GAcY, GAcZ; // Convert accelerometer to gravity value
float Min_GAcX=0, Max_GAcX=0, PtoP_GAcX, Min_GAcY=0, Max_GAcY=0, PtoP_GAcY, Min_GAcZ=0, Max_GAcZ=0, PtoP_GAcZ; // Finding Min, Max & Peak to Peak of gravity value
float Min = 0, Max = 0; // Initial value of Min, Max
int cnt; // Count of calibration process
float Grvt_unit; // Gravity value unit
long period, prev_time; // Period of calculation
//
float temperature=0;
float temperaturaMin=50;
float temperaturaMax=65;
float rpmMin=20;
float rpmMax=50;
float humidity=0;
float humedadMin=40;
float humedadMax=60;
float vibracionMin=0.1;
float vibracionMax=0.2;
DHT dht(DHTPIN, DHTTYPE);
int contador = 1;
char mensagem[30];
volatile unsigned tiempoInterrupcionActual=0;
volatile unsigned tiempoInterrupcionAnterior=0;
volatile unsigned deltaTiempoInterrupciones=0;
double frecuencia =0;
int N=20; //Numero de ranuras
double rpm=0;
void IRAM_ATTR leerEncoder(){
frecuencia=(1000)/(double)deltaTiempoInterrupciones;
tiempoInterrupcionAnterior=tiempoInterrupcionActual;
}
unsigned long TiempoAhora = 0;
void setup() {
pinMode(ENCODER_CLK, INPUT);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), leerEncoder, RISING);
Serial.begin(115200);
WiFi.begin(ssid, password);
dht.begin();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Iniciando conexión a red wifi..");
}
Serial.println("Conectado a la red WiFi!");
Wire.begin();
init_MPU6050();
Gravity_Range_Option();
Calib_MPU6050(); // Calculating calibration value
pinMode(rojo, OUTPUT);
pinMode(verde, OUTPUT);
pinMode(azul, OUTPUT);
}
void loop() {
mostrarAlarma();
tiempoInterrupcionActual=millis();
deltaTiempoInterrupciones= tiempoInterrupcionActual-tiempoInterrupcionAnterior;
if(millis() > TiempoAhora + 2000){
TiempoAhora = millis();
ReadDate_MPU6050();
rpm=frecuencia*(60/N);
Calc_Grvt();
//Display_Grvt();
Min_GAcX = 0;
Max_GAcX = 0;
Min_GAcY = 0;
Max_GAcY = 0;
Min_GAcZ = 0;
Max_GAcZ = 0;
reconectabroker();
temperature = dht.readTemperature();
humidity = dht.readHumidity();
doc["temp"] = temperature;
doc["hum"]=humidity;
doc["vel"]=rpm;
doc["vibrX"]=PtoP_GAcX;
doc["vibrY"]=PtoP_GAcY;
doc["vibrZ"]=PtoP_GAcZ;
Serial.println(rpm);
String string1 = "v1/devices/me/telemetry";
char Buf1[256]; string1.toCharArray(Buf1, 256);
Serial.println(Buf1);
char docBuffer1[256];
size_t n = serializeJson(doc, docBuffer1);
Serial.println(docBuffer1);
client.publish(Buf1, docBuffer1, n);
sprintf(mensagem, "MQTT ESP32 - mensaje no. %d", contador);
Serial.print("Mensagem enviada: ");
Serial.println(mensagem);
client.publish(Buf1, mensagem);
Serial.println("Mensaje enviado satisfactoriamente...");
contador++;
}
}
void reconectabroker() {
client.publish("v1/devices/me/telemetry", mensagem);
Serial.println(mensagem);
String string1 = "v1/devices/me/telemetry";
char Buf1[256];
string1.toCharArray(Buf1, 256);
Serial.println(Buf1);
client.setServer(mqttServer, mqttPort);
while (!client.connected()) {
Serial.println("Conectando a broker MQTT...");
if (client.connect(mqttClient, mqttUser, mqttPassword )) {
Serial.println("Conectado a broker!");
}else {
Serial.print("Error al conectar al broker - Estado: ");
Serial.println(client.state());
}
}
}
void init_MPU6050(){
//MPU6050 Initializing & Reset
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
//MPU6050 Clock Type
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0x03); // Selection Clock 'PLL with Z axis gyroscope reference'
Wire.endTransmission(true);
//MPU6050 Accelerometer Configuration Setting
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x1C); // Accelerometer Configuration register
if(AFS_SEL == 0) Wire.write(0x00); // AFS_SEL=0, Full Scale Range = +/- 2 [g]
else if(AFS_SEL == 1) Wire.write(0x08); // AFS_SEL=1, Full Scale Range = +/- 4 [g]
else if(AFS_SEL == 2) Wire.write(0x10); // AFS_SEL=2, Full Scale Range = +/- 8 [g]
else Wire.write(0x18); // AFS_SEL=3, Full Scale Range = +/- 10 [g]
Wire.endTransmission(true);
//MPU6050 DLPF(Digital Low Pass Filter)
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x1A); // DLPF_CFG register
if(DLPF_SEL == 0) Wire.write(0x00); // Accel BW 260Hz, Delay 0ms / Gyro BW 256Hz, Delay 0.98ms, Fs 8KHz
else if(DLPF_SEL == 1) Wire.write(0x01); // Accel BW 184Hz, Delay 2ms / Gyro BW 188Hz, Delay 1.9ms, Fs 1KHz
else if(DLPF_SEL == 2) Wire.write(0x02); // Accel BW 94Hz, Delay 3ms / Gyro BW 98Hz, Delay 2.8ms, Fs 1KHz
else if(DLPF_SEL == 3) Wire.write(0x03); // Accel BW 44Hz, Delay 4.9ms / Gyro BW 42Hz, Delay 4.8ms, Fs 1KHz
else if(DLPF_SEL == 4) Wire.write(0x04); // Accel BW 21Hz, Delay 8.5ms / Gyro BW 20Hz, Delay 8.3ms, Fs 1KHz
else if(DLPF_SEL == 5) Wire.write(0x05); // Accel BW 10Hz, Delay 13.8ms / Gyro BW 10Hz, Delay 13.4ms, Fs 1KHz
else Wire.write(0x06); // Accel BW 5Hz, Delay 19ms / Gyro BW 5Hz, Delay 18.6ms, Fs 1KHz
Wire.endTransmission(true);
}
void Gravity_Range_Option(){
switch(AFS_SEL) { // Selecting Gravity unit value
case 0:
Grvt_unit = 16384;
break;
case 1:
Grvt_unit = 8192;
break;
case 2:
Grvt_unit = 4096;
break;
case 3:
Grvt_unit = 3276.8;
break;
}
}
void Calib_MPU6050() {
for(int i = 0 ; i < 2000 ; i++) { // Summing Iteration for finding calibration value
if(i % 200 == 0) { // Display progress every 200 cycles
cnt++;
if(cnt == 1) { // Characters to display first
Serial.print("Calculating .");
}
else { // Display progress by point
Serial.print(".");
}
}
ReadDate_MPU6050(); // Read Accelerometer data
delay(10);
// Sum data
Cal_AcX += AcX;
Cal_AcY += AcY;
Cal_AcZ += AcZ;
}
// Average Data
Cal_AcX /= 2000;
Cal_AcY /= 2000;
Cal_AcZ /= 2000;
// Serial Print
Serial.println("");
Serial.println("End of Calculation");
Serial.print("Cal_AcX = "); Serial.print(Cal_AcX);
Serial.print(" | Cal_AcY = "); Serial.print(Cal_AcY);
Serial.print(" | Cal_AcZ = "); Serial.println(Cal_AcZ);
}
void ReadDate_MPU6050() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
//Wire.requestFrom(MPU_ADDR,14,true); // request a total of 14 registers
Wire.requestFrom(MPU_ADDR,6,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
}
void Calc_Grvt() {
AcX = (AcX - Cal_AcX); // Calibrated Accelerometer value
AcY = (AcY - Cal_AcY); // Calibrated Accelerometer value
AcZ = (AcZ - Cal_AcZ); // Calibrated Accelerometer value
GAcX = AcX / Grvt_unit; // Converting the Calibrated value to Gravity value
GAcY = AcY / Grvt_unit; // Converting the Calibrated value to Gravity value
GAcZ = AcZ / Grvt_unit; // Converting the Calibrated value to Gravity value
//---------- Calculating Min, Max & Peak to Peak of Gravity --------------------------------------
Min_GAcX = min(Min_GAcX, GAcX);
Max_GAcX = max(Max_GAcX, GAcX);
PtoP_GAcX = Max_GAcX - Min_GAcX;
Min_GAcY = min(Min_GAcY, GAcY);
Max_GAcY = max(Max_GAcY, GAcY);
PtoP_GAcY = Max_GAcY - Min_GAcY;
Min_GAcZ = min(Min_GAcZ, GAcZ);
Max_GAcZ = max(Max_GAcZ, GAcZ);
PtoP_GAcZ = Max_GAcZ - Min_GAcZ;
}
void Display_Grvt() {
//---------- Serial print ----------------------------------------------------------------------
Serial.print("PtoP_GAcX= " + String(PtoP_GAcX));
Serial.print(" |PtoP_GAcY= " + String(PtoP_GAcY));
Serial.println(" |PtoP_GAcZ= " + String(PtoP_GAcZ));
period = millis() - prev_time;
if(period > 1000) {
prev_time = millis();
Min_GAcX = 0;
Max_GAcX = 0;
Min_GAcY = 0;
Max_GAcY = 0;
Min_GAcZ = 0;
Max_GAcZ = 0;
}
}
void mostrarAlarma(){
if (temperature<temperaturaMax && temperature>temperaturaMin
&& PtoP_GAcX<0.2 && humidity>40 && humidity<60 && rpm<rpmMax && rpm>rpmMin)
{
digitalWrite(rojo, LOW);
digitalWrite(azul, LOW);
digitalWrite(verde, HIGH);
}
else
{
digitalWrite(azul, LOW);
digitalWrite(verde, LOW);
digitalWrite(rojo, HIGH);
}
}