From 5a39c618ce56f95b6c4ce01de5ea0644e217423f Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Sun, 4 Nov 2018 14:10:28 +0100 Subject: [PATCH] Allow LED and Relay logic level to be inverted --- include/main.h | 2 ++ src/channel.c | 15 ++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/main.h b/include/main.h index b6c99b1..f36f93f 100644 --- a/include/main.h +++ b/include/main.h @@ -12,7 +12,9 @@ struct channel_t { uint8_t button_gpio; uint8_t led_gpio; + bool led_invert; uint8_t relay_gpio; + bool relay_invert; bool relay_state; double button_last_change; }; diff --git a/src/channel.c b/src/channel.c index 542fc22..a253dc0 100644 --- a/src/channel.c +++ b/src/channel.c @@ -57,6 +57,8 @@ bool channel_init(const char *fn) { // Traverse Array while ((h = json_next_elem(json, strlen(json), h, ".channels", &idx, &val)) != NULL) { int led = -1, relay = -1, button = -1; + bool led_invert = false; + bool relay_invert = false; LOG(LL_DEBUG, ("[%d]: [%.*s]", idx, val.len, val.ptr)); if (val.len == 0 || !val.ptr) { @@ -66,7 +68,7 @@ bool channel_init(const char *fn) { LOG(LL_ERROR, ("Incomplete Channel JSON: require 'led' and 'relay' and 'button' fields")); goto exit; } - LOG(LL_INFO, ("Channel[%d]: led=%d relay=%d button=%d ", idx, led, relay, button)); + json_scanf(val.ptr, val.len, "{led:%d, led_invert:%B, relay:%d, relay_invert:%B, button:%d}", &led, &led_invert, &relay, &relay_invert, &button); if (!valid_gpio(led)) { LOG(LL_ERROR, ("LED GPIO (%d) out of bounds [%d,%d]", led, GPIO_MIN, GPIO_MAX)); goto exit; @@ -83,9 +85,12 @@ bool channel_init(const char *fn) { LOG(LL_ERROR, ("Too many channels (max is %d)", CHANNEL_MAX)); goto exit; } + LOG(LL_INFO, ("Channel[%d]: led=%d%s relay=%d%s button=%d ", idx, led, led_invert?"(inverted)":"", relay, relay_invert?"(inverted)":"", button)); s_channels[idx].button_gpio = button; s_channels[idx].relay_gpio = relay; + s_channels[idx].relay_invert= relay_invert; s_channels[idx].led_gpio = led; + s_channels[idx].led_invert = led_invert; } ret = true; @@ -103,12 +108,12 @@ exit: if (s_channels[idx].relay_gpio != GPIO_INVALID) { mgos_gpio_set_mode(s_channels[idx].relay_gpio, MGOS_GPIO_MODE_OUTPUT); - mgos_gpio_write(s_channels[idx].relay_gpio, s_channels[idx].relay_state); + mgos_gpio_write(s_channels[idx].relay_gpio, (s_channels[idx].relay_state + s_channels[idx].relay_invert)%2); } if (s_channels[idx].led_gpio != GPIO_INVALID) { mgos_gpio_set_mode(s_channels[idx].led_gpio, MGOS_GPIO_MODE_OUTPUT); - mgos_gpio_write(s_channels[idx].led_gpio, s_channels[idx].relay_state); + mgos_gpio_write(s_channels[idx].led_gpio, (s_channels[idx].relay_state + s_channels[idx].led_invert)%2); } if (s_channels[idx].button_gpio != GPIO_INVALID) { @@ -187,10 +192,10 @@ void channel_set(int idx, bool state) { s_channels[idx].button_last_change = now; s_channels[idx].relay_state = state; if (s_channels[idx].relay_gpio != GPIO_INVALID) { - mgos_gpio_write(s_channels[idx].relay_gpio, state); + mgos_gpio_write(s_channels[idx].relay_gpio, (s_channels[idx].relay_state + s_channels[idx].relay_invert)%2); } if (s_channels[idx].led_gpio != GPIO_INVALID) { - mgos_gpio_write(s_channels[idx].led_gpio, state); + mgos_gpio_write(s_channels[idx].led_gpio, (s_channels[idx].relay_state + s_channels[idx].led_invert)%2); } mqtt_publish_stat("channel", "{idx: %d, relay_state: %d}", idx, channel_get(idx));