Search Code

ESP32 Tutorial 46/55 - Remote Temperature Monitoring using HiveMQ MQTT | SunFounder's ESP32 kit

ESP32 Tutorial 46/55 - Remote Temperature Monitoring using HiveMQ MQTT | SunFounder's ESP32 kit

In this tutorial, we will create a remote temperature monitoring system using the ESP32 and the MQTT protocol. This project allows us to publish temperature data to an MQTT broker and control an LED remotely using a web interface. By pressing a button, we can send temperature readings to the cloud, and we can also receive commands to turn the LED on or off.

esp32-47-mqt-1

The ESP32 is a powerful microcontroller that features built-in Wi-Fi and Bluetooth, making it ideal for Internet of Things (IoT) applications. In this setup, we will use an NTC thermistor to measure temperature, a push button to trigger the readings, and an LED to indicate status. The data will be sent to HiveMQ, a popular MQTT broker, where it can be accessed remotely (in video at 00:45).

esp32-47-mqt-2

Hardware Explained

For this project, we will utilize the following components:

  • ESP32 Microcontroller: This board serves as the central processing unit, handling Wi-Fi connections and MQTT communications.
  • NTC Thermistor: This temperature sensor changes its resistance based on temperature. It provides an analog signal that the ESP32 can read to determine the current temperature.
  • LED: This light-emitting diode will be used to indicate the status based on commands received via MQTT.
  • Push Button: This button will trigger the ESP32 to read the temperature and publish it to the MQTT broker.

Datasheet Details

Manufacturer SunFounder
Part number ESP32
Logic/IO voltage 3.3 V
Supply voltage 5 V (via USB)
Output current (per channel) 12 mA max
PWM frequency guidance Up to 40 kHz
Input logic thresholds 0.3 V (low), 2.4 V (high)
Thermal limits -40 to 85 °C
Package ESP32-WROOM-32

 

  • Ensure proper voltage levels to avoid damage.
  • Use pull-up resistors for the push button to ensure stable readings.
  • Decoupling capacitors can help stabilize the power supply.
  • Be cautious with the thermistor's wiring to avoid incorrect readings.
  • Verify your MQTT broker details for successful connection.

Wiring Instructions

esp32-47-mqtt-wiring

To wire the components, start by connecting the NTC thermistor. Connect one pin of the thermistor to the 3.3 V supply on the ESP32. The other pin connects to pin 36 on the ESP32, and it should also connect to a 10 kΩ resistor, which is then connected to ground. This creates a voltage divider that allows the ESP32 to read the thermistor's resistance.

Next, connect the LED. The longer pin (anode) of the LED connects to pin 4 on the ESP32 through a 220 Ω resistor, while the shorter pin (cathode) connects to ground. For the push button, connect one side to 3.3 V and the other side to pin 14 on the ESP32. Additionally, connect a 10 kΩ resistor from the button pin to ground to ensure a stable LOW state when the button is not pressed.

Install Required library

The PubSubClient library is used here, you can install it from the Library Manager.

esp32-47-mqtt-library

Code Examples & Walkthrough

In the setup, we initialize the serial communication, set up the Wi-Fi connection, and configure the MQTT server. Here's a snippet of the setup code:

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

This part of the code establishes the connection to the Wi-Fi network and sets up the MQTT server. The pin modes for the button and LED are also configured here.

The loop function continuously checks the button state and publishes temperature data when pressed. Here's a focused excerpt from the loop:

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if (digitalRead(buttonPin)) {
    long now = millis();
    if (now - lastMsg > 5000) {
      lastMsg = now;
      char tempString[8];
      dtostrf(thermistor(), 1, 2, tempString);
      client.publish("SF/TEMP", tempString);
    }
  }
}

In this loop, we check if the ESP32 is connected to the MQTT broker. If the button is pressed, it reads the temperature from the thermistor and publishes it to the topic "SF/TEMP" every 5 seconds.

Demonstration / What to Expect

When the project is set up and running, pressing the button will publish the current temperature to the MQTT broker. You can monitor this data from any MQTT client. Additionally, you can send messages to control the LED; sending "on" will light it up, while "off" will turn it off. Watch for the expected behavior in the video at 15:30, where the temperature readings are shown after each button press.

Video Timestamps

  • 00:00 Start
  • 2:05 Introduction to the project
  • 7:06 Free HiveMQ service
  • 7:56 Wiring explained
  • 11:11 Arduino code explained
  • 18:46 Selecting ESP32 board and COM port in Arduino IDE
  • 20:30 Demonstration of HiveMQ Free broker

Images

esp32-47-mqt-1
esp32-47-mqt-1
esp32-47-mqt-2
esp32-47-mqt-2
esp32-47-mqtt-library
esp32-47-mqtt-library
esp32-47-mqtt-wiring
esp32-47-mqtt-wiring
847-ESP32 Tutorial 46/55- Arduino code for IoT Communication with MQTT
Language: C++
/*********
  :ref: https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/
  https://docs.sunfounder.com/projects/kepler-kit/en/latest/iotproject/5.mqtt_pub.html
*********/

#include <WiFi.h>
#include <PubSubClient.h>
//#include <Wire.h>

// Replace the next variables with your SSID/Password combination
const char* ssid = "SSID";
const char* password = "PASSWORD";

// Add your MQTT Broker address, example:
const char* mqtt_server = "broker.hivemq.com";
const char* unique_identifier = "sunfounder-client-sdgvsda";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
int value = 0;


// LED Pin
const int ledPin = 4;
const int buttonPin = 14;

// When you connect to WIFI, only 36 39 34 35 32 33 pins can be used for analog reading.
// Define constants
const int thermistorPin = 36; // Pin connected to the thermistor
const float referenceVoltage = 3.3;
const float referenceResistor = 10000; // Resistance value (10k)
const float beta = 3950; // Beta value (Typical Value)
const float nominalTemperature = 25; // Nominal temperature for calculating the temperature coefficient
const float nominalResistance = 10000; // Resistance value at nominal temperature



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

  // default settings
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

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

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // If a message is received on the topic "SF/LED", you check if the message is either "on" or "off".
  // Changes the output state according to the message
  if (String(topic) == "SF/LED") {
    Serial.print("Changing state to ");
    if (messageTemp == "on") {
      Serial.println("on");
      digitalWrite(ledPin, HIGH);
    } else if (messageTemp == "off") {
      Serial.println("off");
      digitalWrite(ledPin, LOW);
    }
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(unique_identifier)) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("SF/LED");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

float thermistor() {
  int adcValue = analogRead(thermistorPin); // Read ADC value
  float voltage = (adcValue * referenceVoltage) / 4095.0; // Calculate voltage
  float resistance = (voltage * referenceResistor) / (referenceVoltage - voltage); // Calculate thermistor resistance with updated configuration

  // Calculate temperature using the Beta parameter equation
  float tempK = 1 / (((log(resistance / nominalResistance)) / beta) + (1 / (nominalTemperature + 273.15)));
  
  float tempC = tempK - 273.15; // Get temperature in Celsius
  float tempF = 1.8 * tempC + 32.0; // Get temperature in Fahrenheit

  //Print temperature
  Serial.print("Temp: ");
  Serial.println(tempC);
  delay(200); //wait for 200 milliseconds
  return tempC;
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // if the button pressed, publish the temperature to topic "SF/TEMP"
  if (digitalRead(buttonPin)) {
    long now = millis();
    if (now - lastMsg > 5000) {
      lastMsg = now;
      char tempString[8];
      dtostrf(thermistor(), 1, 2, tempString);
      client.publish("SF/TEMP", tempString);
    }
  }
}

Resources & references

Files📁

No files available.