// Sources:
// https://www.survivingwithandroid.com/esp32-mqtt-client-publish-and-subscribe/
// http://www.hivemq.com/demos/websocket-client/
// https://github.com/adafruit/Adafruit_MPU6050/blob/master/examples/basic_readings/basic_readings.ino
// https://stevesnoderedguide.com/configuring-the-mqtt-publish-node (and configuring the MQTT subscribe node)
// https://nodered.org/docs/getting-started/local
// https://lastminuteengineers.com/ds1307-rtc-arduino-tutorial/
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <DHTesp.h>
#include <PubSubClient.h>
#include <U8g2lib.h>
#include <uRTCLib.h>
#include <WiFi.h>
const char *WIFI_SSID = "Wokwi-GUEST";
const char *WIFI_PWD = "";
const char *MQTT_SERVER = "broker.hivemq.com";
const uint16_t MQTT_PORT = 1883;
const byte DHT_PIN = 15;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
Adafruit_MPU6050 mpu;
DHTesp dhtSensor;
uRTCLib rtc(0x68);
U8X8_SSD1306_128X64_NONAME_HW_I2C display(U8X8_PIN_NONE);
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void CallbackMqtt(char* topic, byte* payload, unsigned int length)
{
Serial.print("Callback - ");
Serial.print("Message:");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
}
void SetupMqtt()
{
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
// set the callback function
mqttClient.setCallback(CallbackMqtt);
}
void ConnectToMqtt()
{
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected())
{
char clientId[100] = "\0";
sprintf(clientId, "ESP32Client-%04X", random(0xffff));
Serial.println(clientId);
if (mqttClient.connect(clientId))
{
Serial.println("Connected to MQTT broker.");
// subscribe to topic
mqttClient.subscribe("/sensors/commands");
}
}
}
void ConnectToWiFi()
{
Serial.print("Connecting to WiFi ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PWD, 6);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.print("\nConnected to ");
Serial.println(WIFI_SSID);
}
void SetupMpu6050()
{
if (!mpu.begin(0x69))
{
Serial.println("Failed to find MPU6050 chip");
while (1)
{
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange())
{
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange())
{
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth())
{
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
}
void SetupRtc()
{
URTCLIB_WIRE.begin();
}
void setup()
{
Serial.begin(115200);
Serial.println("Setup begin");
ConnectToWiFi();
SetupMqtt();
SetupMpu6050();
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
SetupRtc();
display.begin();
display.setPowerSave(0);
display.setFont(u8x8_font_pxplusibmcgathin_f);
display.clearDisplay();
display.drawString(2, 1, "Test");
display.setCursor(0, 0);
display.print('1');
display.setCursor(0, 1);
display.print('2');
display.setCursor(0, 2);
display.print('3');
display.setCursor(0, 3);
display.print('4');
display.setCursor(0, 4);
display.print('5');
display.setCursor(0, 5);
display.print('6');
Serial.println("Setup end");
}
const size_t BUFFER_SIZE = 100;
const char *BUFFER_FORMAT = "%1.3f";
char buffer[BUFFER_SIZE + 1]; // Extra one for NULL terminator.
void loop()
{
if (!mqttClient.connected())
{
ConnectToMqtt();
}
mqttClient.loop();
static uint64_t last_time;
uint64_t now = millis();
if (now - last_time > 1 * 1000)
{
// Get new sensor events with the readings.
TempAndHumidity dht22Data = dhtSensor.getTempAndHumidity();
sensors_event_t a, g, mpu_temp;
mpu.getEvent(&a, &g, &mpu_temp);
rtc.refresh();
// Publish and print the values.
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, dht22Data.temperature);
mqttClient.publish("/sensors/dht22_temp", buffer);
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, dht22Data.humidity);
mqttClient.publish("/sensors/dht22_hum", buffer);
Serial.println("Temp: " + String(dht22Data.temperature, 2) + "°C");
Serial.println("Humidity: " + String(dht22Data.humidity, 1) + "%");
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, a.acceleration.x);
mqttClient.publish("/sensors/mpu_ax", buffer);
Serial.print("Acceleration X: ");
Serial.print(buffer);
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, a.acceleration.y);
mqttClient.publish("/sensors/mpu_ay", buffer);
Serial.print(", Y: ");
Serial.print(buffer);
Serial.print(", Z: ");
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, a.acceleration.z);
mqttClient.publish("/sensors/mpu_az", buffer);
Serial.print(buffer);
Serial.println(" m/s^2");
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, g.gyro.x);
mqttClient.publish("/sensors/mpu_gx", buffer);
Serial.print("Rotation X: ");
Serial.print(buffer);
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, g.gyro.y);
mqttClient.publish("/sensors/mpu_gy", buffer);
Serial.print(", Y: ");
Serial.print(buffer);
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, g.gyro.z);
mqttClient.publish("/sensors/mpu_gz", buffer);
Serial.print(", Z: ");
Serial.print(buffer);
Serial.println(" rad/s");
snprintf(buffer, BUFFER_SIZE, BUFFER_FORMAT, mpu_temp.temperature);
mqttClient.publish("/sensors/mpu_temp", buffer);
Serial.print("Temperature: ");
Serial.print(buffer);
Serial.println(" degC");
snprintf(buffer, BUFFER_SIZE, "%02d/%02d/%02d (%s) %02d:%02d:%02d", rtc.year(), rtc.month(), rtc.day(), daysOfTheWeek[rtc.dayOfWeek() - 1], rtc.hour(), rtc.minute(), rtc.second());
mqttClient.publish("/sensors/rtc_time", buffer);
Serial.print("Current Date & Time: ");
Serial.println(buffer);
last_time = now;
}
}