From 48b6ee20ed8d2229d30db22e42941156ffb152f0 Mon Sep 17 00:00:00 2001 From: MadDoct <32080323+MadDoct@users.noreply.github.com> Date: Tue, 14 Aug 2018 00:13:56 +0100 Subject: [PATCH] add pinmode 6 for inverted output and changed some data output --- sonoff/xsns_29_mcp230xx.ino | 131 +++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/sonoff/xsns_29_mcp230xx.ino b/sonoff/xsns_29_mcp230xx.ino index 79e95f03a..04b06457f 100644 --- a/sonoff/xsns_29_mcp230xx.ino +++ b/sonoff/xsns_29_mcp230xx.ino @@ -1,5 +1,5 @@ /* - xsns_29_mcp230xx.ino - Support for I2C MCP23008/MCP23017 GPIO Expander (INPUT ONLY!) + xsns_29_mcp230xx.ino - Support for I2C MCP23008/MCP23017 GPIO Expander (INPUT AND OUTPUT) Copyright (C) 2018 Andre Thomas and Theo Arends @@ -62,12 +62,35 @@ uint8_t mcp230xx_int_en = 0; uint16_t mcp230xx_tele_count = 0; #endif -const char MCP230XX_SENSOR_RESPONSE[] PROGMEM = "{\"Sensor29-D%i\":{\"MODE\":%i,\"PULL-UP\":%i,\"STATE\":%i}}"; +const char MCP230XX_SENSOR_RESPONSE[] PROGMEM = "{\"Sensor29-D%i\":{\"MODE\":%i,\"PULL-UP\":\"%s\",\"STATE\":\"%s\"}}"; #ifdef USE_MCP230xx_OUTPUT -const char MCP230XX_CMND_RESPONSE[] PROGMEM = "{\"S29cmnd-D%i\":{\"C\":\"%s\",\"R\":%i}}"; +const char MCP230XX_CMND_RESPONSE[] PROGMEM = "{\"S29cmnd-D%i\":{\"COMMAND\":\"%s\",\"STATE\":\"%s\"}}"; #endif // USE_MCP230xx_OUTPUT +const char* ConvertNumTxt(uint8_t statu, uint8_t pinmod=0) { +#ifdef USE_MCP230xx_OUTPUT +if (pinmod==6) { + if (statu < 2) statu = abs(statu-1); +} +#endif // USE_MCP230xx_OUTPUT + switch (statu) { + case 0: + return "OFF"; + break; + case 1: + return "ON"; + break; +#ifdef USE_MCP230xx_OUTPUT + case 2: + return "TOGGLE"; + break; +#endif // USE_MCP230xx_OUTPUT + default: + break; + } +} + uint8_t MCP230xx_readGPIO(uint8_t port) { return I2cRead8(mcp230xx_address, MCP230xx_GPIO + port); } @@ -78,9 +101,9 @@ void MCP230xx_ApplySettings(void) { uint8_t reg_gppu = 0; uint8_t reg_gpinten = 0; uint8_t reg_iodir = 0xFF; -#ifdef USE_MCP230xx_OUTPUT +#ifdef USE_MCP230xx_OUTPUT uint8_t reg_portpins = 0x00; -#endif +#endif for (uint8_t idx = 0; idx < 8; idx++) { switch (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].pinmode) { case 0 ... 1: @@ -92,7 +115,7 @@ void MCP230xx_ApplySettings(void) { int_en=1; break; #ifdef USE_MCP230xx_OUTPUT - case 5: + case 5 ... 6: reg_iodir &= ~(1 << idx); if (Settings.flag.save_state) { // Firmware configuration wants us to use the last pin state reg_portpins |= (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].saved_state << idx); @@ -102,12 +125,12 @@ void MCP230xx_ApplySettings(void) { } } break; -#endif // USE_MCP230xx_OUTPUT +#endif // USE_MCP230xx_OUTPUT default: break; } #ifdef USE_MCP230xx_OUTPUT - if (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].pullup && (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].pinmode != 5)) { + if (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].pullup && (Settings.mcp230xx_config[idx+(mcp230xx_port*8)].pinmode < 5)) { reg_gppu |= (1 << idx); } #else @@ -119,21 +142,21 @@ void MCP230xx_ApplySettings(void) { I2cWrite8(mcp230xx_address, MCP230xx_GPPU+mcp230xx_port, reg_gppu); I2cWrite8(mcp230xx_address, MCP230xx_GPINTEN+mcp230xx_port, reg_gpinten); I2cWrite8(mcp230xx_address, MCP230xx_IODIR+mcp230xx_port, reg_iodir); -#ifdef USE_MCP230xx_OUTPUT +#ifdef USE_MCP230xx_OUTPUT I2cWrite8(mcp230xx_address, MCP230xx_GPIO+mcp230xx_port, reg_portpins); -#endif +#endif } mcp230xx_int_en=int_en; } void MCP230xx_Detect() { + uint8_t buffer; + if (mcp230xx_type) { return; } - uint8_t buffer; - for (byte i = 0; i < sizeof(mcp230xx_addresses); i++) { mcp230xx_address = mcp230xx_addresses[i]; I2cWrite8(mcp230xx_address, MCP230xx_IOCON, 0x80); // attempt to set bank mode - this will only work on MCP23017, so its the best way to detect the different chips 23008 vs 23017 @@ -233,11 +256,11 @@ void MCP230xx_Show(boolean json) void MCP230xx_SetOutPin(uint8_t pin,uint8_t pinstate) { uint8_t portpins; uint8_t port = 0; - char cmnd[7]; + char cmnd[7], stt[4]; if (pin > 7) port=1; portpins = MCP230xx_readGPIO(port); if (pinstate < 2) { - if (pinstate) portpins |= (1 << pin-(port*8)); else portpins &= ~(1 << pin-(port*8)); + if (pinstate) portpins |= (1 << pin-(port*8)); else portpins &= ~(1 << pin-(port*8)); } else { portpins ^= (1 << pin-(port*8)); } @@ -245,20 +268,10 @@ void MCP230xx_SetOutPin(uint8_t pin,uint8_t pinstate) { if (Settings.flag.save_state) { // Firmware configured to save last known state in settings Settings.mcp230xx_config[pin].saved_state=portpins>>(pin-(port*8))&1; } - switch (pinstate) { - case 0: - sprintf(cmnd,"OFF"); - break; - case 1: - sprintf(cmnd,"ON"); - break; - case 2: - sprintf(cmnd,"TOGGLE"); - break; - default: - break; - } - snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_CMND_RESPONSE, pin, cmnd,(portpins >> (pin-(port*8)))&1); + uint8_t pinmo = Settings.mcp230xx_config[pin].pinmode; + sprintf(cmnd,ConvertNumTxt(pinstate, pinmo)); + sprintf(stt,ConvertNumTxt((portpins >> (pin-(port*8))&1), pinmo)); + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_CMND_RESPONSE, pin, cmnd, stt); } #endif // USE_MCP230xx_OUTPUT @@ -275,7 +288,9 @@ void MCP230xx_Reset(uint8_t pinmode) { Settings.mcp230xx_config[pinx].b7=0; } MCP230xx_ApplySettings(); - snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,99,pinmode,pullup,99); + char pulluptxt[4]; + sprintf(pulluptxt,ConvertNumTxt(pullup)); + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,99,pinmode,pulluptxt,""); } bool MCP230xx_Command(void) { @@ -291,7 +306,7 @@ bool MCP230xx_Command(void) { if (data == "RESET4") { MCP230xx_Reset(4); return serviced; } #ifdef USE_MCP230xx_OUTPUT if (data == "RESET5") { MCP230xx_Reset(5); return serviced; } -#endif +#endif _a = data.indexOf(","); pin = data.substring(0, _a).toInt(); if (pin < mcp230xx_pincount) { @@ -300,17 +315,27 @@ bool MCP230xx_Command(void) { uint8_t port = 0; if (pin > 7) port = 1; uint8_t portdata = MCP230xx_readGPIO(port); - snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,Settings.mcp230xx_config[pin].pinmode,Settings.mcp230xx_config[pin].pullup,portdata>>(pin-(port*8))&1); + char pulluptxtr[4],pinstatustxtr[4]; + sprintf(pulluptxtr,ConvertNumTxt(Settings.mcp230xx_config[pin].pullup)); +#ifdef USE_MCP230xx_OUTPUT + uint8_t pinmod = Settings.mcp230xx_config[pin].pinmode; + sprintf(pinstatustxtr,ConvertNumTxt(portdata>>(pin-(port*8))&1,pinmod)); + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,pinmod,pulluptxtr,pinstatustxtr); +#else + sprintf(pinstatustxtr,ConvertNumTxt(portdata>>(pin-(port*8))&1)); + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,Settings.mcp230xx_config[pin].pinmode,pulluptxtr,pinstatustxtr); +#endif //USE_MCP230xx_OUTPUT return serviced; } #ifdef USE_MCP230xx_OUTPUT - if (Settings.mcp230xx_config[pin].pinmode == 5) { + if (Settings.mcp230xx_config[pin].pinmode >= 5) { + uint8_t pincmd = Settings.mcp230xx_config[pin].pinmode - 5; if (cmnd == "ON") { - MCP230xx_SetOutPin(pin,1); + MCP230xx_SetOutPin(pin,abs(pincmd-1)); return serviced; } if (cmnd == "OFF") { - MCP230xx_SetOutPin(pin,0); + MCP230xx_SetOutPin(pin,pincmd); return serviced; } if (cmnd == "T") { @@ -318,7 +343,7 @@ bool MCP230xx_Command(void) { return serviced; } } -#endif // USE_MCP230xx_OUTPUT +#endif // USE_MCP230xx_OUTPUT } _b = data.indexOf(",", _a + 1); if (_a < XdrvMailbox.data_len) { @@ -326,17 +351,24 @@ bool MCP230xx_Command(void) { pinmode = data.substring(_a+1, _b).toInt(); pullup = data.substring(_b+1, XdrvMailbox.data_len).toInt(); #ifdef USE_MCP230xx_OUTPUT - if ((pin < mcp230xx_pincount) && (pinmode < 6) && (pullup < 2)) { -#else // not USE_MCP230xx_OUTPUT + if ((pin < mcp230xx_pincount) && (pinmode < 7) && (pullup < 2)) { +#else // not USE_MCP230xx_OUTPUT if ((pin < mcp230xx_pincount) && (pinmode < 5) && (pullup < 2)) { -#endif // USE_MCP230xx_OUTPUT +#endif // USE_MCP230xx_OUTPUT Settings.mcp230xx_config[pin].pinmode=pinmode; Settings.mcp230xx_config[pin].pullup=pullup; MCP230xx_ApplySettings(); uint8_t port = 0; if (pin > 7) port = 1; uint8_t portdata = MCP230xx_readGPIO(port); - snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,pinmode,pullup,portdata>>(pin-(port*8))&1); + char pulluptxtc[4], pinstatustxtc[4]; + sprintf(pulluptxtc,ConvertNumTxt(pullup)); +#ifdef USE_MCP230xx_OUTPUT + sprintf(pinstatustxtc,ConvertNumTxt(portdata>>(pin-(port*8))&1,Settings.mcp230xx_config[pin].pinmode)); +#else // not USE_MCP230xx_OUTPUT + sprintf(pinstatustxtc,ConvertNumTxt(portdata>>(pin-(port*8))&1)); +#endif // USE_MCP230xx_OUTPUT + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,pinmode,pulluptxtc,pinstatustxtc); } else { serviced = false; } @@ -351,7 +383,7 @@ bool MCP230xx_Command(void) { #ifdef USE_MCP230xx_DISPLAYOUTPUT -const char HTTP_SNS_MCP230xx_OUTPUT[] PROGMEM = "%s{s}MCP230XX D%d{m}%d{e}"; // {s} =