From 34b624b9a0c9324e2e9ef3ab81a72cfa69de13dc Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 28 Sep 2016 13:45:01 +0200 Subject: [PATCH 1/4] Code cleaning --- WifiControlSensor/MQTT.ino | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/WifiControlSensor/MQTT.ino b/WifiControlSensor/MQTT.ino index afd5ec2..752696f 100644 --- a/WifiControlSensor/MQTT.ino +++ b/WifiControlSensor/MQTT.ino @@ -9,29 +9,26 @@ Adafruit_MQTT_Publish *mqtt_dht_temp; Adafruit_MQTT_Publish *mqtt_dht_humidity; Adafruit_MQTT_Publish *mqtt_dry; Adafruit_MQTT_Publish *mqtt_ip; +Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {}; #define FEED_MAX_SIZE 96 //FEED have the following formats /feeds/USER/DEVICE_NAME/.... -#define TEMPERATURE_FEED_FORMAT "/feeds/%s/%s/temperature" -#define PRESSURE_FEED_FORMAT "/feeds/%s/%s/pressure" -#define TEMPERATURE_DHT_FEED_FORMAT "/feeds/%s/%s/dht/temperature" -#define HUMIDITY_DHT_FEED_FORMAT "/feeds/%s/%s/dht/humidity" -#define DRY_FEED_FORMAT "/feeds/%s/%s/dry" +#define TEMPERATURE_FEED_FORMAT "/feeds/%s/%s/temperature" +#define PRESSURE_FEED_FORMAT "/feeds/%s/%s/pressure" +#define TEMPERATURE_DHT_FEED_FORMAT "/feeds/%s/%s/dht/temperature" +#define HUMIDITY_DHT_FEED_FORMAT "/feeds/%s/%s/dht/humidity" +#define DRY_FEED_FORMAT "/feeds/%s/%s/dry" +#define GPIO_FEED_FORMAT "/feeds/%s/%s/gpio/%d" +#define GPIO_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" +#define IP_FEED_FORMAT "/feeds/%s/%s/configuration/ip/addr" // Should have less that MAXSUBSCRIPTIONS elements // MAXSUBSCRIPTIONS is defined is Adafruit_mqtt.h const int gpioWatched[] = CONFIG_MQTT_CONTROLLED_GPIO; -#define GPIO_FEED_FORMAT "/feeds/%s/%s/gpio/%d" -#define GPIO_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" - -#define IP_FEED_FORMAT "/feeds/%s/%s/configuration/ip/addr" - char *mqttId; -Adafruit_MQTT_Publish * mqttGpio[MAXSUBSCRIPTIONS] = {}; - bool isMqttConfigured = false; bool useMqtts = false; From c911376cce2da5d4a9d5bb335a17998d19a63f91 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 28 Sep 2016 14:08:43 +0200 Subject: [PATCH 2/4] PWM controlled by mqtt --- WifiControlSensor/MQTT.ino | 53 ++++++++++++++++++++++--------- WifiControlSensor/config.h | 4 +++ WifiControlSensor/config_device.h | 5 ++- WifiControlSensor/utils.h | 8 +++++ 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/WifiControlSensor/MQTT.ino b/WifiControlSensor/MQTT.ino index 752696f..c3737e8 100644 --- a/WifiControlSensor/MQTT.ino +++ b/WifiControlSensor/MQTT.ino @@ -10,6 +10,7 @@ Adafruit_MQTT_Publish *mqtt_dht_humidity; Adafruit_MQTT_Publish *mqtt_dry; Adafruit_MQTT_Publish *mqtt_ip; Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {}; +Adafruit_MQTT_Publish *mqttPwm[MAXSUBSCRIPTIONS] = {}; #define FEED_MAX_SIZE 96 @@ -21,11 +22,14 @@ Adafruit_MQTT_Publish *mqttGpio[MAXSUBSCRIPTIONS] = {}; #define DRY_FEED_FORMAT "/feeds/%s/%s/dry" #define GPIO_FEED_FORMAT "/feeds/%s/%s/gpio/%d" #define GPIO_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" +#define PWM_FEED_FORMAT "/feeds/%s/%s/gpio/%d" +#define PWM_SET_FEED_FORMAT "/feeds/%s/%s/gpio/%d/set" #define IP_FEED_FORMAT "/feeds/%s/%s/configuration/ip/addr" // Should have less that MAXSUBSCRIPTIONS elements // MAXSUBSCRIPTIONS is defined is Adafruit_mqtt.h const int gpioWatched[] = CONFIG_MQTT_CONTROLLED_GPIO; +const int pwmWatched[] = CONFIG_CONTROLLED_PWM; char *mqttId; @@ -53,10 +57,21 @@ int MqttSetup(char *server, char *user, char *passwd, int port, char *hostname) mqtt_dry = MqttCreatePublisher(DRY_FEED_FORMAT, user, mqttId); mqtt_ip = MqttCreatePublisher(IP_FEED_FORMAT, user, mqttId); + if( NB_ELEMENTS(gpioWatched) + NB_ELEMENTS(pwmWatched) > MAXSUBSCRIPTIONS){ + SKETCH_DEBUG_PRINTF("Too much gpio/pwm to control\n Nb gpio %d Nb pwm %d Max is %d", + NB_ELEMENTS(gpioWatched), NB_ELEMENTS(pwmWatched), MAXSUBSCRIPTIONS); + return -1; + } + for (uint i = 0 ; i < NB_ELEMENTS(gpioWatched) && i < MAXSUBSCRIPTIONS; i++) { mqtt->subscribe(MqttCreateSubscribe(GPIO_SET_FEED_FORMAT, user, mqttId, gpioWatched[i])); mqttGpio[i] = MqttCreatePublisher(GPIO_FEED_FORMAT, user, mqttId, gpioWatched[i]); } + + for (uint i = 0 ; i < NB_ELEMENTS(gpioWatched) && i < MAXSUBSCRIPTIONS; i++) { + mqtt->subscribe(MqttCreateSubscribe(PWM_SET_FEED_FORMAT, user, mqttId, pwmWatched[i])); + mqttPwm[i] = MqttCreatePublisher(PWM_FEED_FORMAT, user, mqttId, pwmWatched[i]); + } return 0; } @@ -143,11 +158,11 @@ int MqttDhtPublish(float temp, float humidity) { return 0; } -int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription) { - char *temp = strstr(subscription->topic, "/gpio/"); +int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription, const char *pattern) { + char *temp = strstr(subscription->topic, pattern); if (!temp) return -1; - String gpioStr(temp + strlen("/gpio/")); + String gpioStr(temp + strlen(pattern)); int idx = gpioStr.indexOf("/"); int gpio = gpioStr.substring(0, idx).toInt(); @@ -157,18 +172,18 @@ int getGpioFromSubscription(Adafruit_MQTT_Subscribe *subscription) { return -1; } -int getGpioWatchedIndex(int gpio) { - for ( uint i = 0; i < NB_ELEMENTS(gpioWatched); i++) { - if (gpio == gpioWatched[i]) - return i; - } - return -1; -} - void MqttChangeGpioValue(int gpio, int value) { pinMode(gpio, OUTPUT); digitalWrite(gpio, value); - int watchIdx = getGpioWatchedIndex(gpio); + int watchIdx = findIndex(gpio, gpioWatched); + if (watchIdx >= 0 ) { + mqttGpio[watchIdx]->publish(value); + } +} + +void MqttChangePWMValue(int gpio, int value) { + analogWrite(gpio, value); + int watchIdx = findIndex(gpio, gpioWatched); if (watchIdx >= 0 ) { mqttGpio[watchIdx]->publish(value); } @@ -178,13 +193,21 @@ void MqttCheckSubscription() { if (MqttConnect() == 0) { Adafruit_MQTT_Subscribe *subscription; while ((subscription = mqtt->readSubscription(0))) { - int gpio = getGpioFromSubscription(subscription); - SKETCH_DEBUG_PRINTF("Got Subscription for gpio %d\n", gpio); - if (gpio > 0 && getGpioWatchedIndex(gpio) >= 0) { + int gpio = getGpioFromSubscription(subscription, "/gpio/"); + if (gpio > 0 && findIndex(gpio, gpioWatched) >= 0) { + SKETCH_DEBUG_PRINTF("Got Subscription for GPIO %d\n", gpio); char *value = (char *) subscription->lastread; SKETCH_DEBUG_PRINTF("Receive data: %s\n", value); MqttChangeGpioValue(gpio, atoi(value)); } + + gpio = getGpioFromSubscription(subscription, "/pwm/"); + if (gpio > 0 && findIndex(gpio, pwmWatched) >= 0) { + SKETCH_DEBUG_PRINTF("Got Subscription for PWM %d\n", gpio); + char *value = (char *) subscription->lastread; + SKETCH_DEBUG_PRINTF("Receive data: %s\n", value); + MqttChangePWMValue(gpio, atoi(value)); + } } } } diff --git a/WifiControlSensor/config.h b/WifiControlSensor/config.h index df3fdcb..27b4d02 100644 --- a/WifiControlSensor/config.h +++ b/WifiControlSensor/config.h @@ -39,6 +39,10 @@ #define CONFIG_SSID_NAME "ESPConfigurator" #endif +#ifndef CONFIG_CONTROLLED_PWM +#define CONFIG_CONTROLLED_PWM {} +#endif + #ifndef CONFIG_WEB_CONTROLLED_GPIO #define CONFIG_WEB_CONTROLLED_GPIO {} #endif diff --git a/WifiControlSensor/config_device.h b/WifiControlSensor/config_device.h index 4119d6c..90a1162 100644 --- a/WifiControlSensor/config_device.h +++ b/WifiControlSensor/config_device.h @@ -25,9 +25,12 @@ // Disable mDNS can also save power #define CONFIG_ENABLE_MDNS -//Web controlled GPIO +// Web controlled GPIO #define CONFIG_WEB_CONTROLLED_GPIO {2} +// GPIO used in PWM +#define CONFIG_CONTROLLED_PWM {} + /* DEFAULT VALUE ALSO DEFINED IN CONFIG.H */ //If this GPIO is LOW at boot, device will enter setup mode diff --git a/WifiControlSensor/utils.h b/WifiControlSensor/utils.h index 0512751..fd8bcb7 100644 --- a/WifiControlSensor/utils.h +++ b/WifiControlSensor/utils.h @@ -4,3 +4,11 @@ #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) + +int findIndex(int el, const int array[]){ + for ( uint i = 0; i < NB_ELEMENTS(array); i++) { + if (el == array[i]) + return i; + } + return -1; +} From 0ccf653cc669191adc47a9f0a11759d3a756370b Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 28 Sep 2016 15:28:02 +0200 Subject: [PATCH 3/4] Build HTML to control GPIO one time only --- WifiControlSensor/WebServer.ino | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/WifiControlSensor/WebServer.ino b/WifiControlSensor/WebServer.ino index cd77263..fa6f716 100644 --- a/WifiControlSensor/WebServer.ino +++ b/WifiControlSensor/WebServer.ino @@ -1,17 +1,8 @@ const int gpioWebConf[] = CONFIG_WEB_CONTROLLED_GPIO; -void WebHandleRoot() { - String gpioWeb = ""; +String gpioControlHTML = ""; - if (NB_ELEMENTS(gpioWebConf) > 0){ - gpioWeb += "
" - "Relay"; - for (uint i = 0 ; i < NB_ELEMENTS(gpioWebConf) ; i++) { - gpioWeb += "Relay " + String(gpioWebConf[i]) + " " + "ON/"; - gpioWeb += "OFF
"; - } - gpioWeb += "
"; - } +void WebHandleRoot() { server.send(200, "text/html", "" @@ -29,7 +20,7 @@ void WebHandleRoot() { #ifdef CONFIG_ENABLE_DRY_SENSOR "Dryness " + String((dryness*100)/1024) + "%
" #endif - "" + gpioWeb + "
" + "
" + gpioControlHTML + "
" "Settings" "Enter Setup
" "Put device in OTA mode
" @@ -244,7 +235,21 @@ void WebHandleWifiStatus() { server.send(200, "text/html", message); } +void WebBuildGpioControl(){ + if (NB_ELEMENTS(gpioWebConf) > 0){ + gpioControlHTML += "
" + "Relay"; + for (uint i = 0 ; i < NB_ELEMENTS(gpioWebConf) ; i++) { + gpioControlHTML += "Relay " + String(gpioWebConf[i]) + " " + "ON/"; + gpioControlHTML += "OFF
"; + } + gpioControlHTML += "
"; + } +} + void WebSetupServer(int ) { + WebBuildGpioControl(); + server.on("/", WebHandleRoot); server.on("/setup", WebHandleSetup); server.on("/save", WebHandleSave); From 997f63b917eed8a8426d40354bf5f91c330b8969 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 28 Sep 2016 15:45:45 +0200 Subject: [PATCH 4/4] Add PWM controlled by web --- WifiControlSensor/MQTT.h | 1 + WifiControlSensor/WebServer.ino | 36 ++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/WifiControlSensor/MQTT.h b/WifiControlSensor/MQTT.h index a3544db..d3003a0 100644 --- a/WifiControlSensor/MQTT.h +++ b/WifiControlSensor/MQTT.h @@ -11,4 +11,5 @@ int MqttDryPublish(int dry); int MqttIPPublish(const String &ip); void MqttCheckSubscription(); void MqttChangeGpioValue(int gpio, int value); +void MqttChangePWMValue(int gpio, int value); bool MqttIsConfigured(); diff --git a/WifiControlSensor/WebServer.ino b/WifiControlSensor/WebServer.ino index fa6f716..e2b3f67 100644 --- a/WifiControlSensor/WebServer.ino +++ b/WifiControlSensor/WebServer.ino @@ -1,6 +1,8 @@ const int gpioWebConf[] = CONFIG_WEB_CONTROLLED_GPIO; +const int pwmWebConf[] = CONFIG_CONTROLLED_PWM; String gpioControlHTML = ""; +String pwmControlHTML = ""; void WebHandleRoot() { @@ -20,7 +22,7 @@ void WebHandleRoot() { #ifdef CONFIG_ENABLE_DRY_SENSOR "Dryness " + String((dryness*100)/1024) + "%
" #endif - "
" + gpioControlHTML + "
" + "
" + gpioControlHTML + pwmControlHTML + "
" "Settings" "Enter Setup
" "Put device in OTA mode
" @@ -120,6 +122,16 @@ void WebHandleGpio() { server.send(200, "text/html", "

GPIO" + server.arg("gpio") + " changed to " + server.arg("value") + "

"); } +void WebHandlePWM() { + if (!server.hasArg("gpio") || !server.hasArg("value")) { + server.send(500, "text/plain", "Bad arguments\r\n"); + return; + } + + MqttChangePWMValue(server.arg("gpio").toInt(), server.arg("value").toInt()); + server.send(200, "text/html", "

PWM" + server.arg("gpio") + " changed to " + server.arg("value") + "

"); +} + boolean WebSetIp(IPAddress &addr, const char *id, const char *error) { if (server.arg(id) != "" && !addr.fromString(server.arg(id).c_str())) { WebSendError(error); @@ -247,13 +259,35 @@ void WebBuildGpioControl(){ } } +void WebBuildPwmControl(){ + if (NB_ELEMENTS(pwmWebConf) > 0){ + pwmControlHTML += "
" + "PWM"; + for (uint i = 0 ; i < NB_ELEMENTS(pwmWebConf) ; i++) { + pwmControlHTML += "PWM " + String(pwmWebConf[i]) + "
"; + pwmControlHTML += ""; + } + pwmControlHTML += ""; + pwmControlHTML += "
"; + } +} + void WebSetupServer(int ) { WebBuildGpioControl(); + WebBuildPwmControl(); server.on("/", WebHandleRoot); server.on("/setup", WebHandleSetup); server.on("/save", WebHandleSave); server.on("/gpio", WebHandleGpio); + server.on("/pwm", WebHandlePWM); server.on("/otamode", WebHandleOTA); server.on("/reboot", WebHandleReboot); server.on("/wifiStatus", WebHandleWifiStatus);