├── .gitattributes ├── H801_mqtt.ino ├── README.md ├── h801-with-program-header.jpg ├── h801.jpg ├── mqtt_H801_send_in_network.py └── mqtt_withparms_RGB.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.h text 8 | 9 | # Declare files that will always have CRLF line endings on checkout. 10 | *.sln text eol=crlf 11 | 12 | # Denote all files that are truly binary and should not be modified. 13 | *.png binary 14 | *.jpg binary 15 | 16 | -------------------------------------------------------------------------------- /H801_mqtt.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This bespoke "hack" code is for the H801 (LIXADA) control module. 3 | The H801 module is based on an ESP8266EX and can drive a RGB LED strip of lights. Select "Generic ESP8266 Module" in "Tools -> Board" 4 | 5 | Some background info can be found here 6 | https://tasmota.github.io/docs/devices/H801/#hardware 7 | https://www.inspectmygadgets.com/flashing-the-h801-led-controller-with-tasmota-firmware/ 8 | 9 | ####################################### 10 | # H801 actions 11 | ####################################### 12 | # Physical actions 13 | # - Remove all cables and power from H801 14 | # - Open up H801 case to access H801 PCB 15 | # - Solder 6 header pins into H801 PCB 16 | # - Attach 3 dupont female to female cables to connect from the H801 PCB to the TTL serial FTDI adaptor (as per advice from above links) 17 | # - Attach a single dupont female to female cable to short the 2 pins on the H801 PCB (that set the H801 PCB into programming mode on its power up) 18 | # - Attach a USB cable from your computer to the TTL serial FTDI adaptor 19 | # - Attach a female barrel power connector socket to the H801 PCB by hooking up the +ve and -ve power leads accordingly. You can then power the H801 using a standard 5V-2V brick power supply and it makes it easier to remove and attach power whenever you need to 20 | # 21 | # Software actions 22 | # - Execute Arduino IDE in your desktop 23 | # - add "https://arduino.esp8266.com/stable/package_esp8266com_index.json" to "File->Preferences->field "Additinnal Board Manager URLs" 24 | # - Load up this Arduino sketch into the Arduino IDE 25 | # - Setup Arduino IDE to use a board called "generic ESP8266 module" 26 | # - Setup Arduino IDE to use the COM Port that points to the FDTI adapter 27 | # - Setup Arduino IDE to use a serial speed of 115200 28 | # - Alter the following 5 parameters to suit i.e. ssid, password, mqtt_server, mqtt_user, mqtt_pass 29 | # - If you want to control multiple H801 devices, ensure each H801 has a separate "mqtt_topic" e.g. Change the software for the 2nd H801 to be "ESP_RGB_2" etc 30 | # - Initiate Programming into the H801 by following the sequence below 31 | # - Remove FDTI adapter USB cable from Computer 32 | # - Remove power plug from female barrel socket 33 | # - Short the programming pins with a dupont female to female cable 34 | # - Insert power plug into female barrel socket (to power the H801 PCB) 35 | # - Insert FDTI adapter USB cable into Computer 36 | # - Press the "Upload" button in your Arduino IDE 37 | # - N.B. It may be that you see dots and dashes and after a while the upload crashes. This part of the process is signifying that the arduino IDE is trying to connect to the H801 and it times out before success. 38 | # If this is happening to you, just try the followin trick. Try the upload again, but when you see the dots and dashes, unplug and replug the barrel power plug. 39 | # This unplug and replug power action will kick the H801 to accept a connection for programming, and the process should then continue to completion. 40 | # If this still doesn't work, check you really did short the programming pins together with a dupont female to female cable (for the H801 to accept reprogramming on powerup) 41 | # - Check that uploading has finished OK - you should see a success message in the Arduino IDE 42 | # - Remove the single dupont female to female cable, its the one that shorts the programming pins together 43 | # - Unplug power plug from female barrel socket 44 | # - Unplug FDTI adapter USB cable from Computer 45 | # - Wait 2 seconds 46 | # - Plug FDTI adapter USB cable into Computer 47 | # - Plug power plug into female barrel socket 48 | # - View messages in the Arduinio IDE serial monitor (on your desktop) 49 | # - If all is OK, the red and green LEDS will both be lit, and the device will be ready to accept RGB MQTT messages 50 | 51 | N.B. Remember you have to solder 6 header pins on the H801 PCB - this is so you can connect a cheap FDTI USB adapter to enable programming. 52 | Only 5 pins are actually used though 53 | - 2 pins are for putting the H801 into programming mode (You connect them together with a female to female dupont cable) 54 | - 3 pins are for the Ground/TX/RX to a TTL/USB convertor 55 | 56 | ####################################### 57 | # Python program actions 58 | ####################################### 59 | # This is a separate partner program called "mqtt_H801_send_in_network.py". 60 | # Please go to the program comments in that program - To see the other actions that you need to progress 61 | 62 | 63 | ############################################################################ 64 | # H O W T H I S P R O G R A M W O R K S 65 | ############################################################################# 66 | When executing, this code 67 | - Logs into the SSID network and if successful, the red LED is lit 68 | - Logs into the MQTT broker and if successful, the green LED is lit 69 | - Publishes a welcome message to the broker 70 | - Subscribes to topic ESP_RGB_1. 71 | - When a MQTT message is received For topic "ESP_RGB_1", this code retrieves the first 6 characters from the payload and uses it to formulate the RGB data 72 | - Lights are changfed to suit 73 | It will reconnect to the server if the connection is lost using a blocking reconnect function. 74 | */ 75 | 76 | 77 | 78 | // Update these with values suitable for your network. 79 | 80 | 81 | const char* ssid = "PUT YOUR BROADBAND SSID HERE"; 82 | const char* password = "PUT YOUR BROADBAND PASSWORD HERE"; 83 | const char* mqtt_server = "PUT YOUR MQTT IP ADDRESS HERE e.g. 192.168.1.123"; 84 | const char* mqtt_user = "PUT YOUR MQTT USER ID HERE"; 85 | const char* mqtt_pass = "PUT YOUR MQTT PASSWORD HERE"; 86 | 87 | 88 | // Do not change mqtt_topic from "ESP_RGB_1" unless you want to control multiple H801 devices 89 | const char* mqtt_topic = "ESP_RGB_1"; 90 | 91 | #include 92 | #include 93 | 94 | 95 | #define PWM_VALUE 63 96 | int gamma_table[PWM_VALUE+1] = { 97 | 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 98 | 11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55, 99 | 61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250, 100 | 279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023 101 | }; 102 | 103 | #define redPIN 15 // 12 104 | #define greenPIN 13 // 15 105 | #define bluePIN 12 // 13 106 | #define LED1PIN 1 // onboard red LED D1 107 | #define LED2PIN 5 // onboard green LED D2 108 | 109 | #define LED1off digitalWrite(LED1PIN,LOW) 110 | #define LED1on digitalWrite(LED1PIN,HIGH) 111 | #define LED2off digitalWrite(LED2PIN,HIGH) 112 | #define LED2on digitalWrite(LED2PIN,LOW) 113 | 114 | #define time_at_colour 1000 115 | 116 | int led_delay_red = 0; 117 | int led_delay_green = 0; 118 | int led_delay_blue = 0; 119 | 120 | unsigned long TIME_LED_RED = 0; 121 | unsigned long TIME_LED_GREEN = 0; 122 | unsigned long TIME_LED_BLUE = 0; 123 | int RED, GREEN, BLUE; 124 | int RED_A = 0; 125 | int GREEN_A = 0; 126 | int BLUE_A = 0; 127 | 128 | WiFiClient espClient; 129 | PubSubClient client(espClient); 130 | unsigned long lastMsg = 0; 131 | #define MSG_BUFFER_SIZE (50) 132 | //#define LED_PIN 1 133 | char msg[MSG_BUFFER_SIZE]; 134 | int value = 0; 135 | 136 | //************************************************************** 137 | // void setup_wifi() 138 | //************************************************************** 139 | void setup_wifi() { 140 | 141 | delay(10); 142 | // We start by connecting to a WiFi network 143 | Serial1.println(); 144 | Serial1.print("Connecting to "); 145 | Serial1.println(ssid); 146 | WiFi.mode(WIFI_STA); 147 | WiFi.setPhyMode(WIFI_PHY_MODE_11G); 148 | WiFi.begin(ssid, password); 149 | 150 | while (WiFi.status() != WL_CONNECTED) { 151 | delay(500); 152 | Serial1.print("."); 153 | } 154 | 155 | randomSeed(micros()); 156 | 157 | Serial1.println(""); 158 | Serial1.print("WiFi connected - "); 159 | Serial1.print("IP address: "); 160 | Serial1.println(WiFi.localIP()); 161 | } 162 | 163 | //************************************************************** 164 | // void callback() 165 | //************************************************************** 166 | void callback(char* topic, byte* payload, unsigned int length) { 167 | Serial1.print("Message arrived ["); 168 | Serial1.print(topic); 169 | Serial1.print("] "); 170 | for (int i = 0; i < length; i++) { 171 | Serial1.print((char)payload[i]); 172 | } 173 | Serial1.println(); 174 | 175 | String hexRGB = String((char*)payload); 176 | // convert HEX to RGB 177 | Serial1.println(); 178 | Serial1.print(hexRGB); 179 | Serial1.println(); 180 | hexRGB.toUpperCase(); 181 | char c[6]; 182 | hexRGB.toCharArray(c,7); 183 | long r = convertToInt(c[0],c[1]); //red 184 | long g = convertToInt(c[2],c[3]); //green 185 | long b = convertToInt(c[4],c[5]); //blue 186 | // long s = convertToInt(c[6],c[7]); //speed 187 | //Serial1.println(r); Serial1.println(g); Serial1.println(b); 188 | // set value of RGB controller 189 | int red = map(r,0,255,0,PWM_VALUE); 190 | red = constrain(red,0,PWM_VALUE); 191 | int green = map(g,0,255,0,PWM_VALUE); 192 | green = constrain(green, 0, PWM_VALUE); 193 | int blue = map(b,0,255,0,PWM_VALUE); 194 | blue = constrain(blue,0,PWM_VALUE); 195 | 196 | RED = gamma_table[red]; 197 | GREEN = gamma_table[green]; 198 | BLUE = gamma_table[blue]; 199 | // Serial1.println(RED); Serial1.println(GREEN); Serial1.println(BLUE); 200 | change_LED(); 201 | 202 | while ((RED != RED_A) or (GREEN != GREEN_A) or (BLUE != BLUE_A)) { 203 | if(millis() - TIME_LED_RED >= led_delay_red){ 204 | TIME_LED_RED = millis(); 205 | LED_RED(); 206 | }; 207 | // }else{ 208 | 209 | if(millis() - TIME_LED_GREEN >= led_delay_green){ 210 | TIME_LED_GREEN = millis(); 211 | LED_GREEN(); 212 | }; 213 | // }else{ 214 | 215 | if(millis() - TIME_LED_BLUE >= led_delay_blue){ 216 | TIME_LED_BLUE = millis(); 217 | LED_BLUE(); 218 | }; 219 | // }}}; 220 | // delayMicroseconds(200); 221 | 222 | }; 223 | 224 | // LED1off; 225 | 226 | } 227 | 228 | //************************************************************** 229 | // void reconnect() 230 | //************************************************************** 231 | void reconnect() { 232 | // Loop until we're reconnected 233 | while (!client.connected()) { 234 | LED1on; 235 | LED2on; 236 | Serial1.print("Attempting MQTT connection..."); 237 | // Create a random client ID 238 | String clientId = "ESP8266Client-"; 239 | clientId += String(random(0xffff), HEX); 240 | // Attempt to connect 241 | if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) { 242 | Serial1.println("connected"); 243 | // Once connected, publish an announcement... 244 | client.publish("H801", "hello world"); 245 | // ... and resubscribe 246 | client.subscribe(mqtt_topic); 247 | LED1off; 248 | LED2on; 249 | } else { 250 | Serial1.print("failed, rc="); 251 | Serial1.print(client.state()); 252 | Serial1.println(" try again in 5 seconds"); 253 | // Wait 5 seconds before retrying 254 | delay(5000); 255 | } 256 | } 257 | } 258 | 259 | //************************************************************** 260 | // void change_LED(speed=1) 261 | //************************************************************** 262 | void change_LED() 263 | { 264 | int diff_red = abs(RED-RED_A); 265 | if(diff_red > 0){ 266 | led_delay_red = time_at_colour / abs(RED-RED_A); 267 | }else{ 268 | led_delay_red = time_at_colour / 1023; 269 | } 270 | 271 | int diff_green = abs(GREEN-GREEN_A); 272 | if(diff_green > 0){ 273 | led_delay_green = time_at_colour / abs(GREEN-GREEN_A); 274 | }else{ 275 | led_delay_green = time_at_colour / 1023; 276 | } 277 | 278 | int diff_blue = abs(BLUE-BLUE_A); 279 | if(diff_blue > 0){ 280 | led_delay_blue = time_at_colour / abs(BLUE-BLUE_A); 281 | }else{ 282 | led_delay_blue = time_at_colour / 1023; 283 | } 284 | 285 | } 286 | 287 | //************************************************************** 288 | // void LED_RED() 289 | //************************************************************** 290 | void LED_RED() 291 | { 292 | if(RED != RED_A){ 293 | if(RED_A > RED) RED_A = RED_A - 1; 294 | if(RED_A < RED) RED_A++; 295 | analogWrite(redPIN, RED_A); 296 | } 297 | } 298 | 299 | //************************************************************** 300 | // void LED_GREEN 301 | //************************************************************** 302 | void LED_GREEN() 303 | { 304 | if(GREEN != GREEN_A){ 305 | if(GREEN_A > GREEN) GREEN_A = GREEN_A - 1; 306 | if(GREEN_A < GREEN) GREEN_A++; 307 | analogWrite(greenPIN, GREEN_A); 308 | } 309 | } 310 | 311 | //************************************************************** 312 | // void LED_BLUE() 313 | //************************************************************** 314 | void LED_BLUE() 315 | { 316 | if(BLUE != BLUE_A){ 317 | if(BLUE_A > BLUE) BLUE_A = BLUE_A - 1; 318 | if(BLUE_A < BLUE) BLUE_A++; 319 | analogWrite(bluePIN, BLUE_A); 320 | } 321 | } 322 | 323 | //************************************************************** 324 | // void convertToInt() 325 | //************************************************************** 326 | int convertToInt(char upper,char lower) 327 | { 328 | int uVal = (int)upper; 329 | int lVal = (int)lower; 330 | uVal = uVal >64 ? uVal - 55 : uVal - 48; 331 | uVal = uVal << 4; 332 | lVal = lVal >64 ? lVal - 55 : lVal - 48; 333 | return uVal + lVal; 334 | } 335 | 336 | //************************************************************** 337 | // void setup() 338 | //************************************************************** 339 | void setup() { 340 | 341 | pinMode(LED1PIN, OUTPUT); 342 | pinMode(LED2PIN, OUTPUT); 343 | pinMode(redPIN, OUTPUT); 344 | pinMode(greenPIN, OUTPUT); 345 | pinMode(bluePIN, OUTPUT); 346 | 347 | digitalWrite(redPIN,LOW); 348 | digitalWrite(greenPIN,LOW); 349 | digitalWrite(bluePIN,LOW); 350 | 351 | LED1off; 352 | LED2off; 353 | 354 | Serial1.begin(115200); 355 | 356 | setup_wifi(); 357 | LED1on; 358 | LED2off; 359 | 360 | client.setServer(mqtt_server, 1883); 361 | client.setCallback(callback); 362 | //if you get here you have connected to the WiFi and MQTT 363 | LED1on; 364 | LED2on; 365 | 366 | } 367 | 368 | //************************************************************** 369 | // void loop() 370 | //************************************************************** 371 | void loop() { 372 | if (!client.connected()) { 373 | reconnect(); 374 | } 375 | client.loop(); 376 | } 377 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266-H801-MQTT 2 | 3 | H801 Controller 4 | 5 | ESP8266 / H801 RGB controller using MQTT and WiFi (with soft fade) 6 | 7 | I have had to re-visit this repository because the wifi manager library seems to have connection problems with the ESP8166EX chip 8 | 9 | Just in case it does get fixed, I have the left the original sketch in (called "mqtt_withparms_RGB.ino"). However, in the mean time, I have added the following 2 replacement programs which will work OK 10 | - __mqtt_H801_send_in_network.py__ 11 | - _This is an example python program that you can execute in your desktop to control the LED strip via MQTT_ 12 | - _Please see the program comments on how to use_ 13 | - _Reference info can be found here_ 14 | - https://www.emqx.com/en/blog/how-to-use-mqtt-in-python#full-python-mqtt-code-example 15 | 16 | 17 | - __H801_MQTT.ino__ 18 | - _This is the Arduino code that you need to flash into the H801_ 19 | - _Please see the program comments on how to use_ 20 | - _Reference info can be found here_ 21 | - https://github.com/knolleary/pubsubclient 22 | - https://www.inspectmygadgets.com/flashing-the-h801-led-controller-with-tasmota-firmware/ 23 | - https://tasmota.github.io/docs/devices/H801/#hardware 24 | 25 | 26 | H801 PCB 27 | 28 | 29 | # Old References (for the old "wifi manager" version - not needed now) 30 | This is based on the following sources 31 | - https://web.archive.org/web/20171221004955/https://eryk.io/2015/10/esp8266-based-wifi-rgb-controller-h801/ 32 | - https://github.com/tzapu/WiFiManager 33 | -------------------------------------------------------------------------------- /h801-with-program-header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CurlyWurly-1/ESP8266-H801-MQTT/4a1d723dac056ed403abee07c01e10e06ab0e99c/h801-with-program-header.jpg -------------------------------------------------------------------------------- /h801.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CurlyWurly-1/ESP8266-H801-MQTT/4a1d723dac056ed403abee07c01e10e06ab0e99c/h801.jpg -------------------------------------------------------------------------------- /mqtt_H801_send_in_network.py: -------------------------------------------------------------------------------- 1 | ## https://www.emqx.com/en/blog/how-to-use-mqtt-in-python#full-python-mqtt-code-example 2 | 3 | 4 | ####################################### 5 | # What to do with this program 6 | ####################################### 7 | # - Alter three parameters to suit - mqtt_broker, mqtt_username and mqtt_password 8 | # - Execute this program in a computer that is signed into your broadband network 9 | 10 | ####################################### 11 | # H801 actions 12 | ####################################### 13 | # Follow instructions in the Arduino "partner" program called "H801_mqtt.ino" 14 | 15 | 16 | 17 | import random 18 | import time 19 | 20 | from paho.mqtt import client as mqtt_client 21 | 22 | mqtt_broker = 'PUT YOUR MQTT IP ADDRESS HERE e.g. 192.168.1.123' 23 | mqtt_port = 1883 24 | mqtt_username = 'PUT YOUR MQTT USER ID HERE' 25 | mqtt_password = 'PUT YOUR MQTT PASSWORD HERE' 26 | 27 | 28 | # N.B. This needs to be the same value that is also programmed in your H801 29 | mqtt_topic = 'ESP_RGB_1' 30 | 31 | # Generate a Client ID with the publish prefix. 32 | client_id = f'publish-{random.randint(0, 1000)}' 33 | 34 | ########################################################### 35 | # connect_mqtt() 36 | ########################################################### 37 | def connect_mqtt(): 38 | def on_connect(client, userdata, flags, rc): 39 | if rc == 0: 40 | print("Connected to MQTT Broker!") 41 | else: 42 | print("Failed to connect, return code %d\n", rc) 43 | 44 | # client = mqtt_client.Client(client_id) 45 | client = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION1, client_id) 46 | client.username_pw_set(mqtt_username, mqtt_password) 47 | client.on_connect = on_connect 48 | client.connect(mqtt_broker, mqtt_port) 49 | return client 50 | 51 | ########################################################### 52 | # publish() 53 | ########################################################### 54 | def publish(client): 55 | msg_count = 1 56 | while True: 57 | time.sleep(1) 58 | msg = f"messages: {msg_count}" 59 | 60 | if msg_count == 1: 61 | msg = 'ff0000'; # Red 62 | elif msg_count == 2: 63 | msg = '00ff00'; # Green 64 | elif msg_count == 3: 65 | msg = '0000ff'; # Blue 66 | elif msg_count == 4: 67 | msg = '00ffff'; # mix 1 68 | elif msg_count == 5: 69 | msg = 'ffff00'; # mix 2 70 | elif msg_count == 6: 71 | msg = 'ff00ff'; # mix 3 72 | elif msg_count == 7: 73 | msg = 'ffffff'; # White 74 | elif msg_count == 8: 75 | msg = '000000' # All lights off 76 | 77 | result = client.publish(mqtt_topic, msg) 78 | # result: [0, 1] 79 | status = result[0] 80 | if status == 0: 81 | print(f"Send `{msg}` to topic `{mqtt_topic}`") 82 | else: 83 | print(f"Failed to send message to topic {mqtt_topic}") 84 | msg_count += 1 85 | if msg_count > 8: 86 | msg_count = 1 87 | 88 | ########################################################### 89 | # main() 90 | ########################################################### 91 | def main(): 92 | client = connect_mqtt() 93 | client.loop_start() 94 | publish(client) 95 | client.loop_stop() 96 | 97 | ########################################################### 98 | # P R O G R A M S T A R T S H E R E publish() 99 | ########################################################### 100 | if __name__ == '__main__': 101 | main() -------------------------------------------------------------------------------- /mqtt_withparms_RGB.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This bespoke "hack" code is for the H801 (LIXADA) control module. 3 | * The H801 module is based on an ESP8266 and can drive a RGB LED strip of lights. 4 | * - This code responds to MQTT messages of the form ffffff to topic ESP_RGB_1 5 | * e.g. 00cc00 or ff00cc for RGB control 6 | * 7 | * N.B. You have to solder 6 header pins on the H801 - this is so you can connect a cheap FDTI USB for programming. 8 | */ 9 | #include //this needs to be first, or it all crashes and burns... 10 | 11 | #include //https://github.com/esp8266/Arduino 12 | 13 | //needed for library 14 | #include 15 | #include 16 | #include 17 | #include //https://github.com/tzapu/WiFiManager 18 | 19 | #include //https://github.com/bblanchon/ArduinoJson 20 | 21 | void LED_RED(); 22 | void LED_GREEN(); 23 | void LED_BLUE(); 24 | void change_LED(); 25 | int convertToInt(char upper,char lower); 26 | 27 | #define PWM_VALUE 63 28 | int gamma_table[PWM_VALUE+1] = { 29 | 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 30 | 11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55, 31 | 61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250, 32 | 279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023 33 | }; 34 | 35 | 36 | // RGB FET 37 | #define redPIN 15 //12 38 | #define greenPIN 13 //15 39 | #define bluePIN 12 //13 40 | 41 | // onboard green LED D1 42 | #define LEDPIN 5 43 | // onboard red LED D2 44 | #define LED2PIN 1 45 | 46 | // note 47 | // TX GPIO2 @Serial1 (Serial ONE) 48 | // RX GPIO3 @Serial 49 | 50 | 51 | #define LEDoff digitalWrite(LEDPIN,HIGH) 52 | #define LEDon digitalWrite(LEDPIN,LOW) 53 | 54 | #define LED2off digitalWrite(LED2PIN,HIGH) 55 | #define LED2on digitalWrite(LED2PIN,LOW) 56 | 57 | int led_delay_red = 0; 58 | int led_delay_green = 0; 59 | int led_delay_blue = 0; 60 | #define time_at_colour 1000 61 | unsigned long TIME_LED_RED = 0; 62 | unsigned long TIME_LED_GREEN = 0; 63 | unsigned long TIME_LED_BLUE = 0; 64 | int RED, GREEN, BLUE; 65 | int RED_A = 0; 66 | int GREEN_A = 0; 67 | int BLUE_A = 0; 68 | 69 | 70 | //define your default values here, if there are different values in config.json, they are overwritten. 71 | //length should be max size + 1 72 | char mqtt_server[40] = "10.1.10.22"; 73 | char mqtt_port[6] = "1883"; 74 | //char blynk_token[33] = "YOUR_BLYNK_TOKEN"; 75 | //default custom static IP 76 | char device_topic[60] = "ESP_RGB_1"; 77 | char static_ip[16] = "10.1.10.141"; 78 | char static_gw[16] = "10.1.10.1"; 79 | char static_sn[16] = "255.255.255.0"; 80 | char config_file[25] = "/config.json"; 81 | boolean clean_reset = false; // should be false for production use! 82 | 83 | WiFiClient espClient; 84 | PubSubClient client(espClient); 85 | long lastMsg = 0; 86 | char msg[50]; 87 | int value = 0; 88 | 89 | //flag for saving data 90 | bool shouldSaveConfig = false; 91 | 92 | //callback notifying us of the need to save config 93 | void saveConfigCallback () { 94 | Serial1.println("Should save config"); 95 | shouldSaveConfig = true; 96 | } 97 | 98 | 99 | void callback(char* topic, byte* payload, unsigned int length) { 100 | LEDon; 101 | Serial1.print("Message arrived ["); 102 | Serial1.print(topic); 103 | Serial1.print("] "); 104 | for (int i = 0; i < length; i++) { 105 | Serial1.print((char)payload[i]); 106 | } 107 | Serial1.println(); 108 | 109 | // String hexRGB =(char)payload[0,1]; 110 | String hexRGB = String((char*)payload); 111 | // convert HEX to RGB 112 | Serial1.println(); 113 | Serial1.print(hexRGB); 114 | Serial1.println(); 115 | hexRGB.toUpperCase(); 116 | char c[6]; 117 | hexRGB.toCharArray(c,7); 118 | long r = convertToInt(c[0],c[1]); //red 119 | long g = convertToInt(c[2],c[3]); //green 120 | long b = convertToInt(c[4],c[5]); //blue 121 | //Serial1.println(r); Serial1.println(g); Serial1.println(b); 122 | // set value of RGB controller 123 | int red = map(r,0,255,0,PWM_VALUE); 124 | red = constrain(red,0,PWM_VALUE); 125 | int green = map(g,0,255,0,PWM_VALUE); 126 | green = constrain(green, 0, PWM_VALUE); 127 | int blue = map(b,0,255,0,PWM_VALUE); 128 | blue = constrain(blue,0,PWM_VALUE); 129 | 130 | RED = gamma_table[red]; 131 | GREEN = gamma_table[green]; 132 | BLUE = gamma_table[blue]; 133 | // Serial1.println(RED); Serial1.println(GREEN); Serial1.println(BLUE); 134 | change_LED(); 135 | 136 | while ((RED != RED_A) or (GREEN != GREEN_A) or (BLUE != BLUE_A)) { 137 | if(millis() - TIME_LED_RED >= led_delay_red){ 138 | TIME_LED_RED = millis(); 139 | LED_RED(); 140 | }; 141 | // }else{ 142 | 143 | if(millis() - TIME_LED_GREEN >= led_delay_green){ 144 | TIME_LED_GREEN = millis(); 145 | LED_GREEN(); 146 | }; 147 | // }else{ 148 | 149 | if(millis() - TIME_LED_BLUE >= led_delay_blue){ 150 | TIME_LED_BLUE = millis(); 151 | LED_BLUE(); 152 | }; 153 | // }}}; 154 | // delayMicroseconds(200); 155 | 156 | }; 157 | 158 | LEDoff; 159 | 160 | // Serial1.println(RED_A); Serial1.println(GREEN_A); Serial1.println(BLUE_A); 161 | 162 | LEDoff; 163 | } 164 | 165 | void reconnect() { 166 | // Loop until we're reconnected 167 | while (!client.connected()) { 168 | LEDon; 169 | LED2on; 170 | Serial1.print("Attempting MQTT connection..."); 171 | // Attempt to connect 172 | if (client.connect("ESP8266Client")) { 173 | Serial1.println("connected"); 174 | // Once connected, publish an announcement... 175 | client.publish("outTopic", device_topic); 176 | // ... and resubscribe 177 | Serial1.printf("Subscribing to %s\n", device_topic); 178 | client.subscribe(device_topic); 179 | LEDoff; 180 | LED2on; 181 | } else { 182 | Serial1.print("failed, rc="); 183 | Serial1.print(client.state()); 184 | Serial1.println(" try again in 5 seconds"); 185 | // Wait 5 seconds before retrying 186 | delay(5000); 187 | } 188 | } 189 | } 190 | 191 | void setup() { 192 | LEDon; 193 | LED2on; 194 | // put your setup code here, to run once: 195 | pinMode(LEDPIN, OUTPUT); 196 | pinMode(LED2PIN, OUTPUT); 197 | pinMode(redPIN, OUTPUT); 198 | pinMode(greenPIN, OUTPUT); 199 | pinMode(bluePIN, OUTPUT); 200 | 201 | 202 | Serial1.begin(115200); 203 | Serial1.println(); 204 | 205 | LEDoff; 206 | LED2off; 207 | 208 | //clean FS, for testing 209 | if (clean_reset) { 210 | Serial1.println("clean_reset is true, formatting file system..."); 211 | SPIFFS.format(); 212 | } 213 | 214 | //read configuration from FS json 215 | Serial1.println("mounting FS..."); 216 | 217 | if (SPIFFS.begin()) { 218 | Serial1.println("mounted file system"); 219 | if (SPIFFS.exists(config_file)) { 220 | //file exists, reading and loading 221 | Serial1.println("reading config file"); 222 | File configFile = SPIFFS.open(config_file, "r"); 223 | if (configFile) { 224 | Serial1.println("opened config file"); 225 | size_t size = configFile.size(); 226 | // Allocate a buffer to store contents of the file. 227 | std::unique_ptr buf(new char[size]); 228 | 229 | configFile.readBytes(buf.get(), size); 230 | DynamicJsonBuffer jsonBuffer; 231 | JsonObject& json = jsonBuffer.parseObject(buf.get()); 232 | json.printTo(Serial); 233 | if (json.success()) { 234 | Serial1.println("\nparsed json"); 235 | 236 | strcpy(mqtt_server, json["mqtt_server"]); 237 | strcpy(mqtt_port, json["mqtt_port"]); 238 | strcpy(device_topic, json["device_topic"]); 239 | // strcpy(blynk_token, json["blynk_token"]); 240 | 241 | if(json["ip"]) { 242 | Serial1.println("setting custom ip from config"); 243 | //static_ip = json["ip"]; 244 | strcpy(static_ip, json["ip"]); 245 | strcpy(static_gw, json["gateway"]); 246 | strcpy(static_sn, json["subnet"]); 247 | //strcat(static_ip, json["ip"]); 248 | //static_gw = json["gateway"]; 249 | //static_sn = json["subnet"]; 250 | Serial1.println(static_ip); 251 | /* Serial1.println("converting ip"); 252 | IPAddress ip = ipFromCharArray(static_ip); 253 | Serial1.println(ip);*/ 254 | } else { 255 | Serial1.println("no custom ip in config"); 256 | } 257 | } else { 258 | Serial1.println("failed to load json config"); 259 | } 260 | } 261 | } 262 | } else { 263 | Serial1.println("failed to mount FS"); 264 | } 265 | //end read 266 | Serial1.println(static_ip); 267 | // Serial1.println(blynk_token); 268 | Serial1.println(mqtt_server); 269 | 270 | 271 | // The extra parameters to be configured (can be either global or just in the setup) 272 | // After connecting, parameter.getValue() will get you the configured value 273 | // id/name placeholder/prompt default length 274 | WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); 275 | WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5); 276 | WiFiManagerParameter custom_device_topic("topic", "device topic", device_topic, 60); 277 | // WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34); 278 | 279 | //WiFiManager 280 | //Local intialization. Once its business is done, there is no need to keep it around 281 | WiFiManager wifiManager; 282 | 283 | //set config save notify callback 284 | wifiManager.setSaveConfigCallback(saveConfigCallback); 285 | 286 | //set static ip 287 | IPAddress _ip,_gw,_sn; 288 | _ip.fromString(static_ip); 289 | _gw.fromString(static_gw); 290 | _sn.fromString(static_sn); 291 | 292 | wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn); 293 | 294 | //add all your parameters here 295 | wifiManager.addParameter(&custom_mqtt_server); 296 | wifiManager.addParameter(&custom_mqtt_port); 297 | wifiManager.addParameter(&custom_device_topic); 298 | // wifiManager.addParameter(&custom_blynk_token); 299 | 300 | //reset settings - for testing 301 | if (clean_reset) { 302 | Serial1.println("clean_reset is true, resetting WifiManager..."); 303 | wifiManager.resetSettings(); 304 | } 305 | 306 | //set minimum quality of signal so it ignores AP's under that quality 307 | //defaults to 8% 308 | wifiManager.setMinimumSignalQuality(); 309 | 310 | //sets timeout until configuration portal gets turned off 311 | //useful to make it all retry or go to sleep 312 | //in seconds 313 | //wifiManager.setTimeout(120); 314 | 315 | //fetches ssid and pass and tries to connect 316 | //if it does not connect it starts an access point with the specified name 317 | //here "AutoConnectAP" 318 | //and goes into a blocking loop awaiting configuration 319 | LEDon; 320 | LED2off; 321 | if (!wifiManager.autoConnect("AutoConnectAP", "password")) { 322 | Serial1.println("failed to connect and hit timeout"); 323 | delay(3000); 324 | //reset and try again, or maybe put it to deep sleep 325 | ESP.reset(); 326 | delay(5000); 327 | } 328 | 329 | //if you get here you have connected to the WiFi 330 | LEDon; 331 | LED2on; 332 | Serial1.println("connected...yeey :)"); 333 | 334 | //read updated parameters 335 | strcpy(mqtt_server, custom_mqtt_server.getValue()); 336 | strcpy(mqtt_port, custom_mqtt_port.getValue()); 337 | strcpy(device_topic, custom_device_topic.getValue()); 338 | // strcpy(blynk_token, custom_blynk_token.getValue()); 339 | 340 | //save the custom parameters to FS 341 | if (shouldSaveConfig) { 342 | Serial1.println("saving config"); 343 | DynamicJsonBuffer jsonBuffer; 344 | JsonObject& json = jsonBuffer.createObject(); 345 | json["mqtt_server"] = mqtt_server; 346 | json["mqtt_port"] = mqtt_port; 347 | json["device_topic"] = device_topic; 348 | // json["blynk_token"] = blynk_token; 349 | 350 | json["ip"] = WiFi.localIP().toString(); 351 | json["gateway"] = WiFi.gatewayIP().toString(); 352 | json["subnet"] = WiFi.subnetMask().toString(); 353 | 354 | File configFile = SPIFFS.open(config_file, "w"); 355 | if (!configFile) { 356 | Serial1.println("failed to open config file for writing"); 357 | } 358 | 359 | json.prettyPrintTo(Serial); 360 | json.printTo(configFile); 361 | configFile.close(); 362 | //end save 363 | } 364 | 365 | Serial1.println("local ip"); 366 | Serial1.println(WiFi.localIP()); 367 | Serial1.println(WiFi.gatewayIP()); 368 | Serial1.println(WiFi.subnetMask()); 369 | Serial1.println(device_topic); 370 | 371 | client.setServer(mqtt_server, 1883); 372 | client.setCallback(callback); 373 | } 374 | 375 | 376 | 377 | void change_LED() 378 | { 379 | int diff_red = abs(RED-RED_A); 380 | if(diff_red > 0){ 381 | led_delay_red = time_at_colour / abs(RED-RED_A); 382 | }else{ 383 | led_delay_red = time_at_colour / 1023; 384 | } 385 | 386 | int diff_green = abs(GREEN-GREEN_A); 387 | if(diff_green > 0){ 388 | led_delay_green = time_at_colour / abs(GREEN-GREEN_A); 389 | }else{ 390 | led_delay_green = time_at_colour / 1023; 391 | } 392 | 393 | int diff_blue = abs(BLUE-BLUE_A); 394 | if(diff_blue > 0){ 395 | led_delay_blue = time_at_colour / abs(BLUE-BLUE_A); 396 | }else{ 397 | led_delay_blue = time_at_colour / 1023; 398 | } 399 | 400 | } 401 | 402 | void LED_RED() 403 | { 404 | if(RED != RED_A){ 405 | if(RED_A > RED) RED_A = RED_A - 1; 406 | if(RED_A < RED) RED_A++; 407 | analogWrite(redPIN, RED_A); 408 | } 409 | } 410 | 411 | void LED_GREEN() 412 | { 413 | if(GREEN != GREEN_A){ 414 | if(GREEN_A > GREEN) GREEN_A = GREEN_A - 1; 415 | if(GREEN_A < GREEN) GREEN_A++; 416 | analogWrite(greenPIN, GREEN_A); 417 | } 418 | } 419 | 420 | void LED_BLUE() 421 | { 422 | if(BLUE != BLUE_A){ 423 | if(BLUE_A > BLUE) BLUE_A = BLUE_A - 1; 424 | if(BLUE_A < BLUE) BLUE_A++; 425 | analogWrite(bluePIN, BLUE_A); 426 | } 427 | } 428 | 429 | int convertToInt(char upper,char lower) 430 | { 431 | int uVal = (int)upper; 432 | int lVal = (int)lower; 433 | uVal = uVal >64 ? uVal - 55 : uVal - 48; 434 | uVal = uVal << 4; 435 | lVal = lVal >64 ? lVal - 55 : lVal - 48; 436 | return uVal + lVal; 437 | } 438 | 439 | 440 | void loop() { 441 | // put your main code here, to run repeatedly: 442 | 443 | 444 | if (!client.connected()) { 445 | reconnect(); 446 | } 447 | client.loop(); 448 | 449 | // long now = millis(); 450 | // if (now - lastMsg > 2000) { 451 | // lastMsg = now; 452 | // ++value; 453 | // snprintf (msg, 75, "hello world #%ld", value); 454 | // Serial1.print("Publish message: "); 455 | // Serial1.println(msg); 456 | // client.publish("outTopic", msg); 457 | // } 458 | } 459 | --------------------------------------------------------------------------------