Non-Contact IR Temperature Monitoring & Remote LED Control via ESP32 & Bluetooth
Do you need to manage an output indicator while wirelessly monitoring the temperature without making physical contact? When used with an ESP32, the MLX90614 Infrared (IR) Thermometer makes Bluetooth-controlled LED brightness and non-contact temperature transmission simple and dependable.

Components Needed
- ESP32 Development Board
- MLX90614 Contactless IR Temperature Sensor (GY-906 module)
- Standard 5mm LED (connected to GPIO 4 for PWM control)
- 100Ω Resistor (current limiter for the LED)
- Breadboard and Jumper Wires
- USB Cable / 5V Power Source

Where to Find Components
You can easily source all these electronic parts at affordable prices online:
MLX90614 Sensor
A high-precision non-contact infrared thermometer, the MLX90614 is intended for non-invasive item surface and ambient temperature readings. It transmits ambient (the surrounding air) and object temperatures back to the microcontroller via I2C connection.
Pinout

Circuit Diagram
| Pin | Function | ESP32 Connection |
| VIN | Power Supply (3.3V or 5V depending on module version) | 3.3V or 5V |
| GND | Ground | Ground |
| SCL | I2C Clock Line | GPIO 22 (Default I2C SCL) |
| SDA | I2C Data Line | GPIO 21 (Default I2C SDA) |

Required Arduino Libraries
Before uploading the sketch, open your Arduino IDE and install the required library:
- Go to Tools → Manage Libraries…
- Search for Adafruit MLX90614 and click Install.
- (Built-in) BluetoothSerial comes pre-installed with the ESP32 board package.

Arduino code
#include "BluetoothSerial.h"
#include <Adafruit_MLX90614.h>
// Check if Bluetooth configs are enabled
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
// MLX90614 object
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
// Bluetooth Serial object
BluetoothSerial SerialBT;
// GPIO where DC motor is connected
const int dcmotor = 4;
// Handle received and sent messages
String message = "";
char incomingChar;
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 1000; // 1 second
void setup() {
pinMode(dcmotor, OUTPUT);
Serial.begin(115200);
// Start MLX90614
if (!mlx.begin()) {
Serial.println("Error connecting to MLX90614 sensor. Check wiring.");
while (1);
}
// Bluetooth device name
SerialBT.begin("ESP32");
Serial.println("The device started, now you can pair it with Bluetooth!");
}
void loop() {
// Read Bluetooth commands (motor speed)
if (SerialBT.available()) {
incomingChar = SerialBT.read();
if (incomingChar != '\n') {
message += String(incomingChar);
} else {
message.trim(); // Remove trailing newline/spaces
Serial.println("Received: " + message);
// Handle motor speed commands
if (message == "0") {
analogWrite(dcmotor, 0);
Serial.println("Motor stopped");
} else if (message == "63") {
analogWrite(dcmotor, 63);
Serial.println("Motor speed: 63");
} else if (message == "126") {
analogWrite(dcmotor, 126);
Serial.println("Motor speed: 126");
} else if (message == "189") {
analogWrite(dcmotor, 189);
Serial.println("Motor speed: 189");
} else if (message == "252") {
analogWrite(dcmotor, 252);
Serial.println("Motor speed: 252");
}
message = ""; // Clear message after processing
}
Serial.write(incomingChar);
}
// Every 1 second: send temperatures via Bluetooth
if (millis() - lastSendTime >= sendInterval) {
lastSendTime = millis();
float ambientTemp = mlx.readAmbientTempC();
float objectTemp = mlx.readObjectTempC();
String tempString = "Ambient: " + String(ambientTemp, 2) + "°C | Object: " + String(objectTemp, 2) + "°C";
SerialBT.println(tempString);
Serial.println(tempString);
}
delay(10); // Small delay to stabilize loop
}
How It Works
Bluetooth Pairing: Under the designation ESP32, the ESP32 sets up Classic Bluetooth. Any PC or Android Bluetooth Serial Terminal app can be used to connect to it.

Periodic Temperature Streaming: Every 1,000 milliseconds (1 second), non-blocking timing using millis() reads the ambient and target object temperatures without causing the loop to stall.
Dual Output: Formatted strings (Ambient: XX.XX°C | Object: XX.XX°C) are transmitted simultaneously to your smartphone via Bluetooth and the hardware Serial Monitor (USB).
Wireless Brightness Control: analogWrite() modifies the PWM duty cycle on GPIO 4 when you transmit numeric commands (0, 63, 126, 189, or 252) followed by a newline over Bluetooth. This allows you to directly control the LED brightness levels (0% to 100%).

