#define WITH_HTTP #define WITH_UDP //#define WITH_MQTT //#define WITH_OTA // flash size needs to be 2* sketch size :/ //#define WITH_SERIAL // not used yet #define SILENT_STARTUP #include #include #include #include #ifdef WITH_OTA #include #endif #ifdef WITH_HTTP #include #endif #ifdef WITH_UDP #include #endif #ifdef WITH_MQTT #include #endif const char* ssid = ""; const char* password = ""; #define ME "esplamp-1" #ifdef WITH_MQTT const char* mqtt_server = ""; #endif #ifdef WITH_UDP const int udpPort = 2391; IPAddress multicastAddr(239, 1, 0, 0); #endif #ifdef WITH_MQTT const char* connectTopic = "api/" ME "/connected"; const char* outTopic = "api/" ME "/status/rgb"; const char* inTopic = "api/" ME "/set/rgb"; const char* updateTopic = "api/" ME "/get/rgb"; #endif // R G B const int leds[] = {2, 0, 3}; // remember: TX is inverted, not used here unsigned int state[] = {0, 0, 0}; unsigned char cstate[] = {0, 0, 0}; DynamicJsonBuffer jsonBuffer; char cJson[50]; #ifdef WITH_HTTP ESP8266WebServer server(80); #endif #ifdef WITH_UDP WiFiUDP RAWudp; #endif #ifdef WITH_MQTT WiFiClient espClient; PubSubClient mqtt(espClient); #endif /* hardware access */ void writeJson() { JsonObject& root = jsonBuffer.createObject(); root["red"] = state[0]; root["green"] = state[1]; root["blue"] = state[2]; root.printTo(cJson, sizeof(cJson)); } void updateLeds(bool fast) { for(int i=0; i<3; i++) analogWrite(leds[i], state[i]); if (!fast) { writeJson(); #ifdef WITH_MQTT if (mqtt.connected()) mqtt.publish(outTopic, cJson, true); #endif } } #ifdef WITH_HTTP /* http API */ void handleRoot() { if(server.hasArg("red")) state[0] = server.arg("red").toInt(); if(server.hasArg("green")) state[1] = server.arg("green").toInt(); if(server.hasArg("blue")) state[2] = server.arg("blue").toInt(); updateLeds(false); server.send(200, "application/json", cJson); } #endif #ifdef WITH_MQTT /* MQTT API */ void handleMqtt(char* topic, byte* payload, unsigned int length) { if (strcmp(topic, inTopic) == 0) { JsonObject& root = jsonBuffer.parseObject((char*)payload); if (!root.success()) return; state[0] = root["red"]; state[1] = root["green"]; state[2] = root["blue"]; updateLeds(false); } if (strcmp(topic, updateTopic) == 0) { updateLeds(false); // force update /rgb information } } void connectMqtt() { // connect(id, willTopic, willQoS, willRetain, willMessage) if (mqtt.connect(ME, connectTopic, 2, true, "offline")) { // topic, msg, retain mqtt.publish(connectTopic, "online", true); mqtt.subscribe(inTopic); mqtt.subscribe(updateTopic); } } #endif #ifdef WITH_UDP /* UDP API */ // expected to be most time critical void handleUdp() { if (!RAWudp) RAWudp.beginMulticast(WiFi.localIP(), multicastAddr, udpPort); if (!RAWudp) return; if (RAWudp.parsePacket()) { RAWudp.read(cstate, 3); for(int i=0; i<3; i++) state[i] = cstate[i] << 2; updateLeds(true); // skip publishing } } #endif /* core code */ void setup() { #ifdef WITH_SERIAL Serial.begin(115200); #endif WiFi.begin(ssid, password); for(int i=0; i<3; i++) pinMode(leds[i], OUTPUT); while(WiFi.status() != WL_CONNECTED) { #ifndef SILENT_STARTUP // blink three times for(int i=0; i<3; i++) { if(state[i] < 512) state[i] = 1023; else state[i] = 0; } updateLeds(); #endif delay(500); } WiFi.hostname(ME); MDNS.begin(ME, WiFi.localIP()); #ifdef WITH_OTA ArduinoOTA.setHostname(ME); ArduinoOTA.begin(); #endif #ifdef WITH_HTTP server.on("/", handleRoot); server.begin(); MDNS.addService("http", "tcp", 80); #endif #ifdef WITH_UDP MDNS.addService("udp", "udp", udpPort); #endif #ifdef WITH_MQTT mqtt.setServer(mqtt_server, 1883); mqtt.setCallback(handleMqtt); #endif } void loop() { #ifdef WITH_OTA ArduinoOTA.handle(); #endif #ifdef WITH_HTTP server.handleClient(); #endif #ifdef WITH_UDP handleUdp(); #endif #ifdef WITH_MQTT if (!mqtt.connected()) connectMqtt(); mqtt.loop(); #endif }