├── schematic.jpg ├── PinModes_ESP32_NodeMCU.jpg ├── PinModes_ESP8266_NodeMCU.jpg ├── GPIO_Limitations_ESP32_NodeMCU.jpg ├── README.md ├── PinModes_ESP32_NodeMCU_nolegend.jpg ├── home_assistant_configuration.yaml └── Ceiling_Light_CONFIGURE.ino /schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehookup/ESP32_Ceiling_Light/HEAD/schematic.jpg -------------------------------------------------------------------------------- /PinModes_ESP32_NodeMCU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehookup/ESP32_Ceiling_Light/HEAD/PinModes_ESP32_NodeMCU.jpg -------------------------------------------------------------------------------- /PinModes_ESP8266_NodeMCU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehookup/ESP32_Ceiling_Light/HEAD/PinModes_ESP8266_NodeMCU.jpg -------------------------------------------------------------------------------- /GPIO_Limitations_ESP32_NodeMCU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehookup/ESP32_Ceiling_Light/HEAD/GPIO_Limitations_ESP32_NodeMCU.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32_Ceiling_Light 2 | 3 | ESP32 based dimmable ceiling light 4 | 5 | https://www.youtube.com/watch?v=PVQhGzo-Dtg 6 | -------------------------------------------------------------------------------- /PinModes_ESP32_NodeMCU_nolegend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehookup/ESP32_Ceiling_Light/HEAD/PinModes_ESP32_NodeMCU_nolegend.jpg -------------------------------------------------------------------------------- /home_assistant_configuration.yaml: -------------------------------------------------------------------------------- 1 | ##Add to configuration.yaml file: 2 | 3 | - platform: mqtt 4 | name: "Family Room Front Left" 5 | on_command_type: "brightness" 6 | command_topic: "FamilyRoom/FrontLeft" 7 | brightness_command_topic: "FamilyRoom/FrontLeft" 8 | state_topic: "FamilyRoom/FrontLeft/Status" 9 | retain: true 10 | - platform: mqtt 11 | name: "Family Room Front Right" 12 | on_command_type: "brightness" 13 | command_topic: "FamilyRoom/FrontRight" 14 | brightness_command_topic: "FamilyRoom/FrontRight" 15 | state_topic: "FamilyRoom/FrontRight/Status" 16 | retain: true 17 | - platform: mqtt 18 | name: "Family Room Front Middle" 19 | on_command_type: "brightness" 20 | command_topic: "FamilyRoom/FrontMiddle" 21 | brightness_command_topic: "FamilyRoom/FrontMiddle" 22 | state_topic: "FamilyRoom/FrontMiddle/Status" 23 | retain: true 24 | - platform: mqtt 25 | name: "Family Room Middle Left" 26 | on_command_type: "brightness" 27 | command_topic: "FamilyRoom/MiddleLeft" 28 | brightness_command_topic: "FamilyRoom/MiddleLeft" 29 | state_topic: "FamilyRoom/MiddleLeft/Status" 30 | retain: true 31 | - platform: mqtt 32 | name: "Family Room Middle Right" 33 | on_command_type: "brightness" 34 | command_topic: "FamilyRoom/MiddleRight" 35 | brightness_command_topic: "FamilyRoom/MiddleRight" 36 | state_topic: "FamilyRoom/MiddleRight/Status" 37 | retain: true 38 | - platform: mqtt 39 | name: "Family Room Back Left" 40 | on_command_type: "brightness" 41 | command_topic: "FamilyRoom/BackLeft" 42 | brightness_command_topic: "FamilyRoom/BackLeft" 43 | state_topic: "FamilyRoom/BackLeft/Status" 44 | retain: true 45 | - platform: mqtt 46 | name: "Family Room Back Right" 47 | on_command_type: "brightness" 48 | command_topic: "FamilyRoom/BackRight" 49 | brightness_command_topic: "FamilyRoom/BackRight" 50 | state_topic: "FamilyRoom/BackRight/Status" 51 | retain: true 52 | - platform: mqtt 53 | name: "Family Room Back Middle" 54 | on_command_type: "brightness" 55 | command_topic: "FamilyRoom/BackMiddle" 56 | brightness_command_topic: "FamilyRoom/BackMiddle" 57 | state_topic: "FamilyRoom/BackMiddle/Status" 58 | retain: true 59 | 60 | ##Add to groups.yaml file: 61 | familyRoomCeilingLight: 62 | name: Family Room Light 63 | entities: 64 | - light.family_room_front_left 65 | - light.family_room_front_middle 66 | - light.family_room_front_right 67 | - light.family_room_middle_left 68 | - light.family_room_middle_right 69 | - light.family_room_back_left 70 | - light.family_room_back_middle 71 | - light.family_room_back_right -------------------------------------------------------------------------------- /Ceiling_Light_CONFIGURE.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | /****************** LIBRARY SECTION *************************************/ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | //USER CONFIGURED SECTION START// 13 | const char* ssid = "YOUR_WIRELESS_SSID"; 14 | const char* password = "YOUR_WIRELESS_PASSWORD"; 15 | const char* mqtt_server = "YOUR_MQTT_SERVER_ADDRESS"; 16 | const int mqtt_port = 1883; 17 | const char *mqtt_user = "YOUR_MQTT_USERNAME"; 18 | const char *mqtt_pass = "YOUR_MQTT_PASSWORD"; 19 | const char *mqtt_client_name = "CeilingLightMCU"; // Client connections can't have the same connection name 20 | //USER CONFIGURED SECTION END// 21 | 22 | /***************** DECLARATIONS ****************************************/ 23 | 24 | WiFiClient espClient; 25 | PubSubClient client(espClient); 26 | SimpleTimer timer; 27 | 28 | /***************** GLOBAL VARIABLES ************************************/ 29 | 30 | 31 | const int FrontLeft = 4; 32 | const int FrontMiddle = 16; 33 | const int FrontRight = 17; 34 | const int MiddleLeft = 13; 35 | const int MiddleRight = 5; 36 | const int BackLeft = 14; 37 | const int BackMiddle = 27; 38 | const int BackRight = 26; 39 | const int ambientPin = 15; 40 | 41 | int FrontLeft_Bright = 100; 42 | int FrontMiddle_Bright = 100; 43 | int FrontRight_Bright = 100; 44 | int MiddleLeft_Bright = 100; 45 | int MiddleRight_Bright = 100; 46 | int BackLeft_Bright = 100; 47 | int BackMiddle_Bright = 100; 48 | int BackRight_Bright = 100; 49 | 50 | int freq = 600; 51 | int resolution = 8; 52 | 53 | bool boot = true; 54 | 55 | 56 | /***************** SYSTEM FUNCTIONS *************************************/ 57 | 58 | void setup_wifi() 59 | { 60 | // We start by connecting to a WiFi network 61 | Serial.println(); 62 | Serial.print("Connecting to "); 63 | Serial.println(ssid); 64 | 65 | WiFi.begin(ssid, password); 66 | 67 | while (WiFi.status() != WL_CONNECTED) { 68 | delay(500); 69 | Serial.print("."); 70 | } 71 | 72 | Serial.println(""); 73 | Serial.println("WiFi connected"); 74 | Serial.println("IP address: "); 75 | Serial.println(WiFi.localIP()); 76 | } 77 | 78 | void reconnect() 79 | { 80 | // Loop until we're reconnected 81 | int retries = 0; 82 | while (!client.connected()) { 83 | if(retries < 150) 84 | { 85 | Serial.print("Attempting MQTT connection..."); 86 | // Attempt to connect 87 | if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass)) 88 | { 89 | Serial.println("connected"); 90 | // Once connected, publish an announcement... 91 | if(boot == true) 92 | { 93 | client.publish("checkIn/FamilyRoomMCU","Rebooted"); 94 | boot = false; 95 | } 96 | if(boot == false) 97 | { 98 | client.publish("checkIn/FamilyRoomMCU","Reconnected"); 99 | } 100 | client.subscribe("FamilyRoom/FrontLeft"); 101 | client.subscribe("FamilyRoom/FrontMiddle"); 102 | client.subscribe("FamilyRoom/FrontRight"); 103 | client.subscribe("FamilyRoom/MiddleLeft"); 104 | client.subscribe("FamilyRoom/MiddleRight"); 105 | client.subscribe("FamilyRoom/BackLeft"); 106 | client.subscribe("FamilyRoom/BackMiddle"); 107 | client.subscribe("FamilyRoom/BackRight"); 108 | } 109 | else 110 | { 111 | Serial.print("failed, rc="); 112 | Serial.print(client.state()); 113 | Serial.println(" try again in 5 seconds"); 114 | retries++; 115 | // Wait 5 seconds before retrying 116 | delay(5000); 117 | } 118 | } 119 | if(retries > 1500) 120 | { 121 | } 122 | } 123 | } 124 | 125 | void callback(char* topic, byte* payload, unsigned int length) 126 | { 127 | Serial.print("Message arrived ["); 128 | String newTopic = topic; 129 | Serial.print(topic); 130 | Serial.print("] "); 131 | payload[length] = '\0'; 132 | String newPayload = String((char *)payload); 133 | int intPayload = newPayload.toInt(); 134 | Serial.println(newPayload); 135 | Serial.println(); 136 | if (newTopic == "FamilyRoom/FrontLeft") 137 | { 138 | if(newPayload == "OFF") 139 | { 140 | ledcWrite(1, 0); 141 | client.publish("FamilyRoom/FrontLeft/Status","OFF"); 142 | } 143 | else if(newPayload == "0") 144 | { 145 | ledcWrite(1, 0); 146 | client.publish("FamilyRoom/FrontLeft/Status","OFF"); 147 | } 148 | else 149 | { 150 | FrontLeft_Bright = intPayload; 151 | ledcWrite(1, FrontLeft_Bright); 152 | client.publish("FamilyRoom/FrontLeft/Status","ON"); 153 | } 154 | } 155 | if (newTopic == "FamilyRoom/FrontMiddle") 156 | { 157 | if(newPayload == "OFF") 158 | { 159 | ledcWrite(0, 0); 160 | client.publish("FamilyRoom/FrontMiddle/Status","OFF"); 161 | } 162 | else if(newPayload == "0") 163 | { 164 | ledcWrite(0, 0); 165 | client.publish("FamilyRoom/FrontMiddle/Status","OFF"); 166 | } 167 | else 168 | { 169 | FrontMiddle_Bright = intPayload; 170 | ledcWrite(0, FrontMiddle_Bright); 171 | client.publish("FamilyRoom/FrontMiddle/Status","ON"); 172 | } 173 | } 174 | if (newTopic == "FamilyRoom/FrontRight") 175 | { 176 | if(newPayload == "OFF") 177 | { 178 | ledcWrite(2, 0); 179 | client.publish("FamilyRoom/FrontRight/Status","OFF"); 180 | } 181 | else if(newPayload == "0") 182 | { 183 | ledcWrite(2, 0); 184 | client.publish("FamilyRoom/FrontRight/Status","OFF"); 185 | } 186 | else 187 | { 188 | FrontRight_Bright = intPayload; 189 | ledcWrite(2, FrontRight_Bright); 190 | client.publish("FamilyRoom/FrontRight/Status","ON"); 191 | } 192 | } 193 | if (newTopic == "FamilyRoom/MiddleLeft") 194 | { 195 | if(newPayload == "OFF") 196 | { 197 | ledcWrite(3, 0); 198 | client.publish("FamilyRoom/MiddleLeft/Status","OFF"); 199 | } 200 | else if(newPayload == "0") 201 | { 202 | ledcWrite(3, 0); 203 | client.publish("FamilyRoom/MiddleLeft/Status","OFF"); 204 | } 205 | else 206 | { 207 | MiddleLeft_Bright = intPayload; 208 | ledcWrite(3, MiddleLeft_Bright); 209 | client.publish("FamilyRoom/MiddleLeft/Status","ON"); 210 | } 211 | } 212 | if (newTopic == "FamilyRoom/MiddleRight") 213 | { 214 | if(newPayload == "OFF") 215 | { 216 | ledcWrite(4, 0); 217 | client.publish("FamilyRoom/MiddleRight/Status","OFF"); 218 | } 219 | else if(newPayload == "0") 220 | { 221 | ledcWrite(4, 0); 222 | client.publish("FamilyRoom/MiddleRight/Status","OFF"); 223 | } 224 | else 225 | { 226 | MiddleRight_Bright = intPayload; 227 | ledcWrite(4, MiddleRight_Bright); 228 | client.publish("FamilyRoom/MiddleRight/Status","ON"); 229 | } 230 | } 231 | if (newTopic == "FamilyRoom/BackLeft") 232 | { 233 | if(newPayload == "OFF") 234 | { 235 | ledcWrite(5, 0); 236 | client.publish("FamilyRoom/BackLeft/Status","OFF"); 237 | } 238 | else if(newPayload == "0") 239 | { 240 | ledcWrite(5, 0); 241 | client.publish("FamilyRoom/BackLeft/Status","OFF"); 242 | } 243 | else 244 | { 245 | BackLeft_Bright = intPayload; 246 | ledcWrite(5, BackLeft_Bright); 247 | client.publish("FamilyRoom/BackLeft/Status","ON"); 248 | } 249 | } 250 | if (newTopic == "FamilyRoom/BackMiddle") 251 | { 252 | if(newPayload == "OFF") 253 | { 254 | ledcWrite(6, 0); 255 | client.publish("FamilyRoom/BackMiddle/Status","OFF"); 256 | } 257 | else if(newPayload == "0") 258 | { 259 | ledcWrite(6, 0); 260 | client.publish("FamilyRoom/BackMiddle/Status","OFF"); 261 | } 262 | else 263 | { 264 | BackMiddle_Bright = intPayload; 265 | ledcWrite(6, BackMiddle_Bright); 266 | client.publish("FamilyRoom/BackMiddle/Status","ON"); 267 | } 268 | } 269 | if (newTopic == "FamilyRoom/BackRight") 270 | { 271 | if(newPayload == "OFF") 272 | { 273 | ledcWrite(7, 0); 274 | client.publish("FamilyRoom/BackRight/Status","OFF"); 275 | } 276 | else if(newPayload == "0") 277 | { 278 | ledcWrite(7, 0); 279 | client.publish("FamilyRoom/BackRight/Status","OFF"); 280 | } 281 | else 282 | { 283 | BackRight_Bright = intPayload; 284 | ledcWrite(7, BackRight_Bright); 285 | client.publish("FamilyRoom/BackRight/Status","ON"); 286 | } 287 | } 288 | } 289 | 290 | /***************** GLOBAL LIGHT FUNCTIONS *******************************/ 291 | 292 | void checkIn() 293 | { 294 | client.publish("checkIn/CeilingLightMCU","OK"); 295 | } 296 | 297 | /***************** SETUP FUNCTIONS ****************************************/ 298 | 299 | 300 | void setup() 301 | { 302 | Serial.begin(115200); 303 | WiFi.mode(WIFI_STA); 304 | 305 | //LEDC Setup 306 | ledcSetup(1, freq, resolution); 307 | ledcAttachPin(FrontLeft, 1); 308 | ledcSetup(0, freq, resolution); 309 | ledcAttachPin(FrontMiddle, 0); 310 | ledcSetup(2, freq, resolution); 311 | ledcAttachPin(FrontRight, 2); 312 | ledcSetup(3, freq, resolution); 313 | ledcAttachPin(MiddleLeft, 3); 314 | ledcSetup(4, freq, resolution); 315 | ledcAttachPin(MiddleRight, 4); 316 | ledcSetup(5, freq, resolution); 317 | ledcAttachPin(BackLeft, 5); 318 | ledcSetup(6, freq, resolution); 319 | ledcAttachPin(BackMiddle, 6); 320 | ledcSetup(7, freq, resolution); 321 | ledcAttachPin(BackRight, 7); 322 | 323 | setup_wifi(); 324 | client.setServer(mqtt_server, mqtt_port); 325 | client.setCallback(callback); 326 | 327 | timer.setInterval(120000, checkIn); 328 | 329 | ArduinoOTA.setHostname("CeilingLightMCU"); 330 | ArduinoOTA.begin(); 331 | } 332 | 333 | 334 | /***************** MAIN LOOP ****************************************/ 335 | 336 | 337 | void loop() 338 | { 339 | if (!client.connected()) 340 | { 341 | reconnect(); 342 | } 343 | client.loop(); 344 | ArduinoOTA.handle(); 345 | timer.run(); 346 | } 347 | 348 | 349 | 350 | 351 | --------------------------------------------------------------------------------