This tutorial explains creating an intelligent AC controller using an ESP32-C3 microcontroller and an IR LED. We'll use the IRremoteESP8266 library for IR communication and the SinricPro library for integrating with smart home platforms.
- ESP32-C3 microcontroller
- IR LED
- NPN transistor (e.g., 2N2222 or BC547)
- 1kΩ resistor
- Breadboard and jumper wires
Note
I used an ESP32-C3 Mini and an 2N2222A tranzistor.
- Arduino IDE
- IRremoteESP8266 library
- SinricPro library
- Connect the 1kΩ resistor from GPIO 4 of the ESP32-C3 to the base of the NPN transistor.
- Connect the emitter of the NPN transistor to GND.
- Connect the IR LED's cathode (shorter leg) to the collector of the NPN transistor.
- Connect the IR LED's anode (longer leg) to the 3.3V pin of the ESP32-C3.
This configuration allows the transistor to act as a switch, providing more current to the IR LED when activated.
- Open Arduino IDE
- Go to Sketch > Include Library > Manage Libraries
- Search for and install:
- IRremoteESP8266
- SinricPro
Install the additional ArduinoJson and WebSockets libraries requested for the SinricPro library.
Also, make sure that the appropriate board is installed and selected. To do so:
- Go to Tools > Board: > Boards Managers.
- Search for and install esp32 by Espressif.
- Choose Tools > Board: > ESP32C3 Dev Module and the correct Port.
Warning
I advise you to install the version 2.0.17, as newer versions produce error during IRremoteESP8266 library compilation.
To find which protocol the AC listens to, we use one of the IRremoteESP8266 example sketches, which goes through all the types.
- Open the sketch File > Examples > IRremoteESP8266 > CommonAcControl
- Verify and Upload
- Point the IR towards the AC
- Open the serial monitor from Tools > Serial Monitor
- Once the AC accepts the command (Turn On/Off), observe on the serial monitor which protocol triggers it
Note
For example, mine was Coolix protocol.
Tip
If you have a phone that supports OTG, download the "Serial USB Terminal" from the Play Store and connect your phone with the ESP for a portable serial monitor.
- Go to SinricPro and create an account
- Create a new device of type "AC Unit"
- Note down the Device ID and App Key
Create a new sketch in Arduino IDE and paste the following code:
#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
#include <WiFi.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include "SinricPro.h"
#include "SinricProWindowAC.h"
#define BAUD_RATE 115200 // Change baudrate to your need
// IR LED pin
const uint16_t kIrLed = 4;
// WIFI parameters
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASS "YOUR_WIFI_PASSWORD"
// Sinric Pro parameters
#define APP_KEY "YOUR_APP_KEY_HERE" // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET "YOUR_APP_SECRET_HERE" // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define ACUNIT_ID "YOUR_DEVICE_ID_HERE" // Should look like "5dc1564130xxxxxxxxxxxxxx"
// IR parameters and variables
//replace with the actual ac model
#include <ir_Coolix.h> //replace with the actual ac model
#define AUTO_MODE kCoolixAuto
#define COOL_MODE kCoolixCool
#define DRY_MODE kCoolixDry
#define HEAT_MODE kCoolixHeat
#define FAN_MODE kCoolixFan
#define FAN_AUTO kCoolixFanAuto
#define FAN_MIN kCoolixFanMin
#define FAN_MED kCoolixFanMed
#define FAN_HI kCoolixFanMax
IRCoolixAC ac(kIrLed);
// AC state
float globalTemperature = 25.0;
bool globalPowerState = false;
int globalFanSpeed = 1;
String globalMode = "COOL";
bool new_request = false;
// Functions to handle web requests
bool onPowerState(const String &deviceId, bool &state) {
Serial.printf("Thermostat %s turned %s\r\n", deviceId.c_str(), state?"on":"off");
globalPowerState = state;
new_request = true;
return true; // request handled properly
}
bool onTargetTemperature(const String &deviceId, float &temperature) {
Serial.printf("Thermostat %s set temperature to %f\r\n", deviceId.c_str(), temperature);
globalTemperature = temperature;
new_request = true;
return true;
}
bool onAdjustTargetTemperature(const String & deviceId, float &temperatureDelta) {
globalTemperature += temperatureDelta; // calculate absolut temperature
Serial.printf("Thermostat %s changed temperature about %f to %f", deviceId.c_str(), temperatureDelta, globalTemperature);
temperatureDelta = globalTemperature; // return absolut temperature
new_request = true;
return true;
}
bool onThermostatMode(const String &deviceId, String &mode) {
Serial.printf("Thermostat %s set to mode %s\r\n", deviceId.c_str(), mode.c_str());
globalMode = mode;
new_request = true;
return true;
}
bool onRangeValue(const String &deviceId, int &rangeValue) {
Serial.printf("Fan speed set to %d\r\n", rangeValue);
globalFanSpeed = rangeValue;
new_request = true;
return true;
}
bool onAdjustRangeValue(const String &deviceId, int &valueDelta) {
globalFanSpeed += valueDelta;
Serial.printf("Fan speed changed about %d to %d\r\n", valueDelta, globalFanSpeed);
valueDelta = globalFanSpeed;
new_request = true;
return true;
}
// Function to control AC with IR LED
void send_command() {
if (globalPowerState) { // set state
ac.on();
ac.setTemp((uint8_t)globalTemperature); // set temperature
if (globalMode == "AUTO") { // set operation
ac.setMode(AUTO_MODE);
ac.setFan(FAN_AUTO);
globalFanSpeed = 0;
} else if (globalMode == "COOL") {
ac.setMode(COOL_MODE);
// } else if (globalMode == "ECO") {
// ac.setMode(DRY_MODE);
} else if (globalMode == "HEAT") {
ac.setMode(HEAT_MODE);
} else if (globalMode == "ECO") {
ac.setMode(FAN_MODE);
}
if (globalMode != "AUTO") { // set fan speed
if (globalFanSpeed == 0) {
ac.setFan(FAN_AUTO);
} else if (globalFanSpeed == 1) {
ac.setFan(FAN_MIN);
} else if (globalFanSpeed == 2) {
ac.setFan(FAN_MED);
} else if (globalFanSpeed == 3) {
ac.setFan(FAN_HI);
}
}
} else {
ac.off();
}
ac.send(); // transmit IR signal
}
// Functions to setup WIFI and Sinric Pro
void setupWiFi() {
Serial.printf("\r\n[Wifi]: Connecting");
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.setAutoReconnect(true);
#elif defined(ESP32)
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
#endif
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
delay(250);
}
IPAddress localIP = WiFi.localIP();
Serial.printf("connected!\r\n[WiFi]: IP-Address is %d.%d.%d.%d\r\n", localIP[0], localIP[1], localIP[2], localIP[3]);
}
void setupSinricPro() {
SinricProWindowAC &myAcUnit = SinricPro[ACUNIT_ID];
myAcUnit.onPowerState(onPowerState);
myAcUnit.onTargetTemperature(onTargetTemperature);
myAcUnit.onAdjustTargetTemperature(onAdjustTargetTemperature);
myAcUnit.onThermostatMode(onThermostatMode);
myAcUnit.onRangeValue(onRangeValue);
myAcUnit.onAdjustRangeValue(onAdjustRangeValue);
// setup SinricPro
SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); });
SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
}
// Arduino functions
void setup() {
Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
setupWiFi();
setupSinricPro();
ac.begin();
delay(1000);
}
void loop() {
SinricPro.handle();
if (new_request) {
send_command();
new_request = false;
}
}Replace the following placeholders in the code:
- YOUR_WIFI_SSID: Your WiFi network name
- YOUR_WIFI_PASSWORD: Your WiFi password
- YOUR_APP_KEY_HERE: Your SinricPro App Key
- YOUR_APP_SECRET_HERE: Your SinricPro App Secret
- YOUR_DEVICE_ID_HERE: Your SinricPro Device ID
Also, modify according to your protocol with the following:
- AUTO_MODE
- COOL_MODE
- DRY_MODE
- HEAT_MODE
- FAN_MODE
- FAN_AUTO
- FAN_MIN
- FAN_MED
- FAN_HI
- IRCoolixAC
- Connect your ESP32-C3 to your computer
- Select the correct board and port in Arduino IDE
- Upload the code to your ESP32-C3
- Open the Serial Monitor to check for a successful connection to WiFi and SinricPro
You can now control your AC using:
- SinricPro mobile app
- Voice commands through Alexa or Google Home (after setting up the integration in SinricPro)