This circuit involves an ESP32 microcontroller interfacing with an LM35 temperature sensor. The ESP32 reads the temperature data from the LM35 sensor and displays it on an OLED screen. Additionally, the ESP32 controls a fan using a TRIAC based on the temperature readings.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define LM35_PIN 34 // ESP32 analog input pin connected to LM35
#define TRIAC_PIN 12 // Pin controlling the TRIAC (GPIO 12)
#define ZERO_CROSS_PIN 13 // Pin connected to zero-cross detector (GPIO 13)
#define FAN_MAX_DELAY 8333 // Max delay in microseconds (100% off at 60Hz)
// Baseline temperature in °C (adjust this to your desired baseline)
float baselineTemp = 20.0;
int delayTime = 0; // Delay for phase angle control
void IRAM_ATTR zeroCrossDetected() {
delayMicroseconds(delayTime);
digitalWrite(TRIAC_PIN, HIGH); // Fire the TRIAC
delayMicroseconds(10); // Keep TRIAC on for a few microseconds
digitalWrite(TRIAC_PIN, LOW); // Turn off the TRIAC
}
void setup() {
pinMode(TRIAC_PIN, OUTPUT);
pinMode(ZERO_CROSS_PIN, INPUT);
// Attach interrupt for zero-cross detection
attachInterrupt(digitalPinToInterrupt(ZERO_CROSS_PIN), zeroCrossDetected, RISING);
Serial.begin(115200); // ESP32 operates faster, so use a higher baud rate
// Initialize the OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for most OLEDs
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay(); // Clear the buffer
display.setTextSize(4); // Set text size (increase for bigger text)
display.setTextColor(SSD1306_WHITE); // Set text color
delay(2000); // Give display some time to initialize
}
void loop() {
int sensorValue = analogRead(LM35_PIN); // Read analog value from LM35
// Convert the analog value to temperature in Celsius
// LM35 outputs 10mV per degree Celsius, powered at 5V
float voltage = sensorValue * (5.0 / 4095.0); // Convert analog reading to voltage at 5V
int currentTemp = (int)(voltage * 100); // Convert voltage to temperature in Celsius as whole number
// Display the temperature in the Serial Monitor
Serial.print("Current Temp: ");
Serial.println(currentTemp);
// Display the temperature on the OLED
display.clearDisplay(); // Clear the display each loop
display.setCursor(0, 0); // Start at top-left corner
display.setTextSize(2); // Set text size
display.print("Temp: ");
display.print(currentTemp); // Show only whole degrees
display.println(" C");
// Display fan speed (based on the delay time)
float fanSpeed = map(delayTime, FAN_MAX_DELAY, 0, 0, 100); // Calculate fan speed as percentage
display.print("Fan: ");
display.print((int)fanSpeed); // Show fan speed as whole number
display.println(" %");
display.display(); // Update the display with the new data
// Calculate the delay for the TRIAC phase control based on temperature
if (currentTemp > baselineTemp) {
float tempDiff = currentTemp - baselineTemp;
float fanPower = map(tempDiff, 0, 10, 0, 100); // Scale temperature difference to 0-100% power
fanPower = constrain(fanPower, 0, 100); // Constrain to max 100% power
delayTime = map(fanPower, 0, 100, FAN_MAX_DELAY, 0); // Larger delay = less power
} else {
delayTime = FAN_MAX_DELAY; // No power to the fan if temp is below baseline
}
delay(1000); // Update every second
}
This code initializes the ESP32 to read temperature data from the LM35 sensor, display it on an OLED screen, and control a fan using a TRIAC based on the temperature readings. The fan speed is adjusted using phase angle control, which is synchronized with the AC zero-crossing signal.