This circuit is designed to control a 220V fan using an ESP32 microcontroller based on temperature readings from an LM35 temperature sensor. The fan's speed is regulated through phase angle control implemented with a MOC3041 optoisolator and a BT139 triac. The system also includes a 0.96" OLED display to provide real-time feedback on the temperature and fan speed. Safety features include a 5A fuse in series with the 120V outlet to protect against overcurrent conditions. The circuit is powered by the same 120V outlet, with resistors and a ceramic capacitor forming a snubber circuit for the triac.
EN
, VP
, VN
, D35
, D32
, D33
, D25
, D26
, D27
, D14
, TX0
, RX0
, D19
, D18
, D5
, TX2
, RX2
, D4
, D2
, D15
: Not connected.D34
: Connected to the Vout
pin of the Temperature Sensor (LM35).D12
: Connected to the ANODE
pin of the MOC3041.D13
: Not connected (presumably used for zero-cross detection).GND
: Common ground with the OLED, MOC3041, and Temperature Sensor (LM35).Vin
: Connected to the VDD
pin of the 0.96" OLED.D23
, D22
: Connected to the SCK
and SDA
pins of the 0.96" OLED for I2C communication.D21
: Not connected in the net list but presumably used for I2C communication with the OLED.3V3
: Connected to the +Vs
pin of the Temperature Sensor (LM35).GND
: Connected to the GND
pin of the ESP32.VDD
: Connected to the Vin
pin of the ESP32.SCK
: Connected to the D22
pin of the ESP32.SDA
: Connected to the D21
pin of the ESP32.AC Neutral
: Connected to the output
pin of the 5A Fuse.AC Hot
: Connected to the pin2
of the 360 Ohms Resistor.GND
: Not connected in the net list.TRIAC1
: Connected to the pin1
of the 360 Ohms Resistor.NC
: Not connected.TRIAC2
: Connected to the GATE
pin of the BT139 600 and pin1
of the 330 Ohms Resistor.CATHODE
: Connected to the GND
pin of the ESP32.ANODE
: Connected to the D12
pin of the ESP32.+Vs
: Connected to the 3V3
pin of the ESP32.Vout
: Connected to the D34
pin of the ESP32.GND
: Connected to the GND
pin of the ESP32.MT1
: Connected to the AC Hot
pin of the 120V Outlet.MT2
: Connected to the L
pin of the 220V Fan and pin0
of the Ceramic Capacitor.GATE
: Connected to the TRIAC2
pin of the MOC3041 and pin1
of the 330 Ohms Resistor.N
: Connected to the input
pin of the 5A Fuse.L
: Connected to the MT2
pin of the BT139 600.AC Hot
pin of the 120V Outlet, the other pin connected to the TRIAC1
pin of the MOC3041.GATE
pin of the BT139 600, the other pin connected to the TRIAC2
pin of the MOC3041 and pin0
of the Ceramic Capacitor.pin1
of the Ceramic Capacitor, the other pin not connected in the net list.MT2
pin of the BT139 600 and pin2
of the 330 Ohms Resistor.pin1
of the 360 Ohms Resistor.input
: Connected to the N
pin of the 220V Fan.output
: Connected to the AC Neutral
pin of the 120V Outlet.#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();