Allow LED and Relay logic level to be inverted

This commit is contained in:
Pim van Pelt
2018-11-04 14:10:28 +01:00
parent b29edab495
commit 5a39c618ce
2 changed files with 12 additions and 5 deletions

View File

@ -12,7 +12,9 @@
struct channel_t { struct channel_t {
uint8_t button_gpio; uint8_t button_gpio;
uint8_t led_gpio; uint8_t led_gpio;
bool led_invert;
uint8_t relay_gpio; uint8_t relay_gpio;
bool relay_invert;
bool relay_state; bool relay_state;
double button_last_change; double button_last_change;
}; };

View File

@ -57,6 +57,8 @@ bool channel_init(const char *fn) {
// Traverse Array // Traverse Array
while ((h = json_next_elem(json, strlen(json), h, ".channels", &idx, &val)) != NULL) { while ((h = json_next_elem(json, strlen(json), h, ".channels", &idx, &val)) != NULL) {
int led = -1, relay = -1, button = -1; 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)); LOG(LL_DEBUG, ("[%d]: [%.*s]", idx, val.len, val.ptr));
if (val.len == 0 || !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")); LOG(LL_ERROR, ("Incomplete Channel JSON: require 'led' and 'relay' and 'button' fields"));
goto exit; 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)) { if (!valid_gpio(led)) {
LOG(LL_ERROR, ("LED GPIO (%d) out of bounds [%d,%d]", led, GPIO_MIN, GPIO_MAX)); LOG(LL_ERROR, ("LED GPIO (%d) out of bounds [%d,%d]", led, GPIO_MIN, GPIO_MAX));
goto exit; goto exit;
@ -83,9 +85,12 @@ bool channel_init(const char *fn) {
LOG(LL_ERROR, ("Too many channels (max is %d)", CHANNEL_MAX)); LOG(LL_ERROR, ("Too many channels (max is %d)", CHANNEL_MAX));
goto exit; 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].button_gpio = button;
s_channels[idx].relay_gpio = relay; s_channels[idx].relay_gpio = relay;
s_channels[idx].relay_invert= relay_invert;
s_channels[idx].led_gpio = led; s_channels[idx].led_gpio = led;
s_channels[idx].led_invert = led_invert;
} }
ret = true; ret = true;
@ -103,12 +108,12 @@ exit:
if (s_channels[idx].relay_gpio != GPIO_INVALID) { if (s_channels[idx].relay_gpio != GPIO_INVALID) {
mgos_gpio_set_mode(s_channels[idx].relay_gpio, MGOS_GPIO_MODE_OUTPUT); 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) { if (s_channels[idx].led_gpio != GPIO_INVALID) {
mgos_gpio_set_mode(s_channels[idx].led_gpio, MGOS_GPIO_MODE_OUTPUT); 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) { 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].button_last_change = now;
s_channels[idx].relay_state = state; s_channels[idx].relay_state = state;
if (s_channels[idx].relay_gpio != GPIO_INVALID) { 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) { 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)); mqtt_publish_stat("channel", "{idx: %d, relay_state: %d}", idx, channel_get(idx));