mirror of https://github.com/arendst/Tasmota.git
update mcp230xx to allow inverted output
Created pinmode 6 to allow setting inverted output, so it can easily be used with active low relay boards... Also changerd some of the output to make it more readable...
This commit is contained in:
parent
8a61c25218
commit
41b594ae53
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -107,7 +130,7 @@ void MCP230xx_ApplySettings(void) {
|
|||
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
|
||||
|
@ -128,12 +151,12 @@ void MCP230xx_ApplySettings(void) {
|
|||
|
||||
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,7 +256,7 @@ 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) {
|
||||
|
@ -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) {
|
||||
|
@ -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") {
|
||||
|
@ -326,7 +351,7 @@ 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)) {
|
||||
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
|
||||
|
@ -336,7 +361,14 @@ 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,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} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
const char HTTP_SNS_MCP230xx_OUTPUT[] PROGMEM = "%s{s}MCP230XX D%d{m}%s{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
||||
void MCP230xx_UpdateWebData(void) {
|
||||
uint8_t gpio1 = MCP230xx_readGPIO(0);
|
||||
|
@ -361,8 +393,10 @@ void MCP230xx_UpdateWebData(void) {
|
|||
}
|
||||
uint16_t gpio = (gpio2 << 8) + gpio1;
|
||||
for (uint8_t pin = 0; pin < mcp230xx_pincount; pin++) {
|
||||
if (Settings.mcp230xx_config[pin].pinmode == 5) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_MCP230xx_OUTPUT, mqtt_data, pin, (gpio>>pin)&1);
|
||||
if (Settings.mcp230xx_config[pin].pinmode >= 5) {
|
||||
char stt[4];
|
||||
sprintf(stt,ConvertNumTxt((gpio>>pin)&1,Settings.mcp230xx_config[pin].pinmode));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_MCP230xx_OUTPUT, mqtt_data, pin, stt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,13 +415,15 @@ void MCP230xx_OutputTelemetry(void) {
|
|||
if (mcp230xx_type == 2) gpiob=MCP230xx_readGPIO(1);
|
||||
gpiototal=((uint16_t)gpiob<<8) | gpioa;
|
||||
for (uint8_t pinx = 0;pinx < mcp230xx_pincount;pinx++) {
|
||||
if (Settings.mcp230xx_config[pinx].pinmode == 5) outputcount++;
|
||||
if (Settings.mcp230xx_config[pinx].pinmode >= 5) outputcount++;
|
||||
}
|
||||
if (outputcount) {
|
||||
char stt[4];
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"MCP230_OUT\": {"), GetDateAndTime(DT_LOCAL).c_str());
|
||||
for (uint8_t pinx = 0;pinx < mcp230xx_pincount;pinx++) {
|
||||
if (Settings.mcp230xx_config[pinx].pinmode == 5) {
|
||||
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"OUTD%i\":%i,"),mqtt_data,pinx,(gpiototal>>pinx)&1);
|
||||
if (Settings.mcp230xx_config[pinx].pinmode >= 5) {
|
||||
sprintf(stt,ConvertNumTxt(((gpiototal>>pinx)&1),Settings.mcp230xx_config[pinx].pinmode));
|
||||
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"OUTD%i\":%s,"),mqtt_data,pinx,stt);
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data,sizeof(mqtt_data),PSTR("%s\"END\":1}}"),mqtt_data);
|
||||
|
@ -449,4 +485,3 @@ boolean Xsns29(byte function)
|
|||
|
||||
#endif // USE_MCP230xx
|
||||
#endif // USE_I2C
|
||||
|
||||
|
|
Loading…
Reference in New Issue