esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 36 forks source link

GPIO switch toggles ON and OFF (powercycle) at start and reset. #715

Closed amishv closed 5 years ago

amishv commented 5 years ago

Operating environment/Installation (Hass.io/Docker/pip/etc.):

HA on Synology Docker ESP (ESP32/ESP8266, Board/Sonoff):

ESP8266 (nodemcu - multiple versions) Affected component:

https://esphome.io/components/switch/gpio.html https://esphome.io/components/pcf8574.html Description of problem: I have 8 switches configured using PCF8754 using inverted logic. On the power on all the switches are toggled on and then off for a brief moment (enough the make relay chatter and lights blink). Ideally the switches should remain in the restore default condition as defined in YAML

Problem-relevant YAML-configuration entries:

PASTE YAML FILE HERE
i2c:
  sda: D2
  scl: D1
  scan: False

pcf8574:
  - id: 'pcf8574_hub'
    address: 0x20
    pcf8575: False

# Individual outputs
switch:
  - platform: gpio
    name: "Garden Roof Light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      # Use pin number 0
      number: 0
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S1  
  - platform: gpio
    name: "Study  Light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 1
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S2
  - platform: gpio
    name: "Study ceiling light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 2
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S3
  - platform: gpio
    name: "Study Fan"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 3
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True    
    id: S4 
  - platform: gpio
    name: "Garden fan"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 4
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S5  
  - platform: gpio
    name: "Garden Ceiling light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 5
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S6
  - platform: gpio
    name: "Garden tube light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 6
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True
    id: S7
  - platform: gpio
    name: "Study tube light"
    restore_mode: ALWAYS_OFF
    pin:
      pcf8574: pcf8574_hub
      number: 7
      # One of INPUT, INPUT_PULLUP or OUTPUT
      mode: OUTPUT
      inverted: True    
    id: S8

Logs (if applicable):

PASTE DEBUG LOG HERE
[19:15:42][I][app:096]: esphome version 1.13.6 compiled on Oct  2 2019, 19:15:13
[19:15:42][C][wifi:372]: WiFi:
[19:15:42][C][wifi:254]:   SSID: 'redacted'
[19:15:42][C][wifi:255]:   IP Address: 192.168.0.108
[19:15:42][C][wifi:257]:   BSSID: redacted
[19:15:42][C][wifi:258]:   Hostname: 'study'
[19:15:42][C][wifi:262]:   Signal strength: -75 dB ▂▄▆█
[19:15:42][C][wifi:263]:   Channel: 7
[19:15:42][C][wifi:264]:   Subnet: 255.255.255.0
[19:15:42][C][wifi:265]:   Gateway: 192.168.0.1
[19:15:42][C][wifi:266]:   DNS1: 192.168.0.1
[19:15:42][C][wifi:267]:   DNS2: 0.0.0.0
[19:15:42][C][i2c:028]: I2C Bus:
[19:15:42][C][i2c:029]:   SDA Pin: GPIO4
[19:15:42][C][i2c:030]:   SCL Pin: GPIO5
[19:15:42][C][i2c:031]:   Frequency: 50000 Hz
[19:15:42][C][pcf8574:021]: PCF8574:
[19:15:42][C][pcf8574:022]:   Address: 0x20
[19:15:42][C][pcf8574:023]:   Is PCF8575: NO
[19:15:42][C][switch.gpio:042]: GPIO Switch 'Garden Roof Light'
[19:15:42][C][switch.gpio:043]:   Pin: GPIO0 (Mode: OUTPUT, INVERTED)
[19:15:42][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Study  Light'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO1 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Study ceiling light'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO2 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Study Fan'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO3 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Garden fan'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO4 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Garden Ceiling light'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO5 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Garden tube light'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO6 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][switch.gpio:042]: GPIO Switch 'Study tube light'
[19:15:43][C][switch.gpio:043]:   Pin: GPIO7 (Mode: OUTPUT, INVERTED)
[19:15:43][C][switch.gpio:059]:   Restore Mode: Always OFF
[19:15:43][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'study Motion'
[19:15:43][C][gpio.binary_sensor:015]:   Device Class: 'motion'
[19:15:43][C][gpio.binary_sensor:016]:   Pin: GPIO12 (Mode: INPUT)
[19:15:43][C][logger:137]: Logger:
[19:15:43][C][logger:138]:   Level: DEBUG
[19:15:43][C][logger:139]:   Log Baud Rate: 115200
[19:15:43][C][logger:140]:   Hardware UART: UART0
[19:15:43][C][dht:017]: DHT:
[19:15:43][C][dht:018]:   Pin: GPIO14 (Mode: INPUT)
[19:15:43][C][dht:022]:   Model: DHT11
[19:15:43][C][dht:027]:   Update Interval: 15.0s
[19:15:43][C][dht:029]:   Temperature 'study Temperature'
[19:15:43][C][dht:029]:     Unit of Measurement: '°C'
[19:15:43][C][dht:029]:     Accuracy Decimals: 1
[19:15:43][C][dht:029]:     Icon: 'mdi:thermometer'
[19:15:43][C][dht:030]:   Humidity 'study Humidity'
[19:15:43][C][dht:030]:     Unit of Measurement: '%'
[19:15:43][C][dht:030]:     Accuracy Decimals: 0
[19:15:43][C][dht:030]:     Icon: 'mdi:water-percent'
[19:15:43][C][ota:029]: Over-The-Air Updates:
[19:15:43][C][ota:030]:   Address: study.local:8266
[19:15:43][C][ota:032]:   Using Password.
[19:15:43][C][api:103]: API Server:
[19:15:43][C][api:104]:   Address: study.local:6053
[19:15:43][C][wifi_signal.sensor:009]: WiFi Signal 'study Wifi'
[19:15:43][C][wifi_signal.sensor:009]:   Unit of Measurement: 'dB'
[19:15:43][C][wifi_signal.sensor:009]:   Accuracy Decimals: 0
[19:15:43][C][wifi_signal.sensor:009]:   Icon: 'mdi:wifi'
[19:15:44][D][dht:048]: Got Temperature=28.0°C Humidity=88.0%
[19:15:44][D][sensor:092]: 'study Temperature': Sending state 28.00000 °C with 1 decimals of accuracy

Additional information and things you've tried:

glmnet commented 5 years ago

Can you upload an empty program and check what happens?

I mean, if there is an electrical condition that makes the relays go on before the ESPHome code is running, then you'll have to check for a solution on the hardware side and by no means will you solve this by software.

So, if you load an empty esphome code, e.g. with just the uptime sensor, and your lights turn on, that means the outputs cannot be changed by software.

amishv commented 5 years ago

Hi @glmnet,

Thanks for the advice. I uploaded an empty fie and there was no flicker this time. Please find the logs below

INFO Successfully connected to study.local [21:27:23][I][app:096]: esphome version 1.13.6 compiled on Oct 3 2019, 21:26:46

[21:27:23][C][wifi:255]: IP Address: 192.168.0.108

[21:27:23][C][wifi:262]: Signal strength: -39 dB ▂▄▆█ [21:27:23][C][wifi:263]: Channel: 7 [21:27:23][C][wifi:264]: Subnet: 255.255.255.0 [21:27:23][C][wifi:265]: Gateway: 192.168.0.1 [21:27:23][C][wifi:266]: DNS1: 192.168.0.1 [21:27:23][C][wifi:267]: DNS2: 0.0.0.0

[21:27:23][C][logger:138]: Level: DEBUG [21:27:23][C][logger:139]: Log Baud Rate: 115200 [21:27:23][C][logger:140]: Hardware UART: UART0 [21:27:23][C][ota:029]: Over-The-Air Updates: [21:27:23][C][ota:030]: Address: study.local:8266 [21:27:23][C][ota:032]: Using Password. [21:27:23][C][api:103]: API Server: [21:27:23][C][api:104]: Address: study.local:6053 [21:27:32][D][api:573]: Client 'Home Assistant 0.98.3 (##.##.##.##)' connected successfully! [21:28:43][D][api:573]: Client 'Home Assistant 0.98.3 (##.##.##.##)' connected successfully! [21:28:45][D][api:075]: Disconnecting Home Assistant 0.98.3 (##.##.##.##)'

glmnet commented 5 years ago

ahhh I wish I had that module to try. But then this is a software issue.

amishv commented 5 years ago

@glmnet ,

I was facing the same issue with the regular gpio and referenced https://github.com/esphome/issues/issues/165#issuecomment-477330751.

So I decided to use I2c ex pander, as, I assumed, it will only work if the correct I2C signals are given but this seems like a code issue.

glmnet commented 5 years ago

I don't know exactly what might be wrong, this seems like a simple issue but it is really more complicated than it seems.

I have your problem solved though, I have many nodes which uses relay boards with inverted inputs, I drive them via an Arduino so I programmed everything and got it working at the end, struggled but got it working. Curiously I first tried programming the Arduino to "mimic" a PCF8574 and could not get it working facing issues similar to yours here, so I decided to implement "my own logic". I dare to say though, if there is a problem on the software, it's got to be at the PCF8574 implementation, as I am using the rest of ESPHome logic and it's great.

If you want to give the Arduino approach a try I wrote a cookbook which is still in review phase. Note this link is a PR version, so it will go down when the PR gets merged.

amishv commented 5 years ago

I tried with changing the I2C pin definition so that there is no I2C communiation, sure enough there was no chatter. thought other sensors worked fine the GPIO did not start or chatter.

[22:17:52][C][i2c:028]: I2C Bus: [22:17:52][C][i2c:029]: SDA Pin: GPIO5 [22:17:52][C][i2c:030]: SCL Pin: GPIO4 [22:17:52][C][i2c:031]: Frequency: 50000 Hz

[22:17:52][C][pcf8574:022]: Address: 0x20 [22:17:52][C][pcf8574:023]: Is PCF8575: NO [22:17:52][E][pcf8574:025]: Communication with PCF8574 failed! [22:17:52][C][switch.gpio:042]: GPIO Switch 'Garden Roof Light' [22:17:52][C][switch.gpio:043]: Pin: GPIO0 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Study Light' [22:17:52][C][switch.gpio:043]: Pin: GPIO1 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Study ceiling light' [22:17:52][C][switch.gpio:043]: Pin: GPIO2 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Study Fan' [22:17:52][C][switch.gpio:043]: Pin: GPIO3 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Garden fan' [22:17:52][C][switch.gpio:043]: Pin: GPIO4 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Garden Ceiling light' [22:17:52][C][switch.gpio:043]: Pin: GPIO5 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Garden tube light' [22:17:52][C][switch.gpio:043]: Pin: GPIO6 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][switch.gpio:042]: GPIO Switch 'Study tube light' [22:17:52][C][switch.gpio:043]: Pin: GPIO7 (Mode: OUTPUT, INVERTED) [22:17:52][C][switch.gpio:059]: Restore Mode: Always OFF [22:17:52][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'study Motion' [22:17:52][C][gpio.binary_sensor:015]: Device Class: 'motion' [22:17:52][C][gpio.binary_sensor:016]: Pin: GPIO12 (Mode: INPUT)

[22:17:52][C][logger:138]: Level: DEBUG [22:17:52][C][logger:139]: Log Baud Rate: 115200 [22:17:52][C][logger:140]: Hardware UART: UART0

[22:17:52][C][dht:018]: Pin: GPIO14 (Mode: INPUT) [22:17:52][C][dht:022]: Model: DHT11 [22:17:52][C][dht:027]: Update Interval: 15.0s

[22:17:52][C][dht:029]: Unit of Measurement: '°C' [22:17:52][C][dht:029]: Accuracy Decimals: 1

[22:17:52][C][dht:030]: Unit of Measurement: '%' [22:17:52][C][dht:030]: Accuracy Decimals: 0

[22:17:52][C][ota:029]: Over-The-Air Updates: [22:17:52][C][ota:030]: Address: study.local:8266 [22:17:52][C][ota:032]: Using Password. [22:17:52][C][api:103]: API Server:

glmnet commented 5 years ago

Yes, most likely the PCF8574 driver is not configuring the output correctly at the beginning.

amishv commented 5 years ago

I feel that the following may be causing the issue in pcf8574.cpp.

void PCF8574Component::setup() { ESP_LOGCONFIG(TAG, "Setting up PCF8574..."); if (!this->readgpio()) { ESPLOGE(TAG, "PCF8574 not available under 0x%02X", this->address); this->mark_failed(); return; }

this->writegpio(); this->readgpio(); }

But unable to compile as esphome overwrites the file

glmnet commented 5 years ago

you'll have to setup a development environment, check contributin

amishv commented 5 years ago

@glmnet ,

Thanks, I took the Quick & dirty way to directly make the changes in the Esphome directory. I was able to reproduce the same effect in relays directly connected to GPIO, so it seems that I might have to try gpio_switch.cpp.

Since, I am working on live system, will setup a test board tomorrow and test.

Thanks a lot.

amishv commented 5 years ago

I have further isolated the problem in a test setup. @glmnet I removed the gpio switch entries and retained the binary sensors of pcf8574. The binary sensors are working fine and there is no chattering at the start. This certainly is an issue with the gpio switch.

I am observing the same behaviour in the GPIO switch directly attached to D0, D1,...

i2c: sda: D2 scl: D1 scan: False

pcf8574:

Individual outputs

sensor:

binary_sensor:

switches

attached logs [21:47:06][I][app:096]: esphome version 1.13.6 compiled on Oct 4 2019, 21:46:20

[21:47:06][C][wifi:255]: IP Address: 192.168.0.103 [21:47:06][C][wifi:257]: BSSID: 1Redacted

[21:47:06][C][wifi:262]: Signal strength: -43 dB ▂▄▆█ [21:47:06][C][wifi:263]: Channel: 7 [21:47:06][C][wifi:264]: Subnet: 255.255.255.0 [21:47:06][C][wifi:265]: Gateway: 192.168.0.107 [21:47:06][C][wifi:266]: DNS1: 192.168.0.107 [21:47:06][C][wifi:267]: DNS2: 0.0.0.0 [21:47:06][C][i2c:028]: I2C Bus: [21:47:06][C][i2c:029]: SDA Pin: GPIO4 [21:47:06][C][i2c:030]: SCL Pin: GPIO5 [21:47:06][C][i2c:031]: Frequency: 50000 Hz

[21:47:06][C][pcf8574:022]: Address: 0x20 [21:47:06][C][pcf8574:023]: Is PCF8575: NO [21:47:06][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Bedroom Ceiling light Switch' [21:47:06][C][gpio.binary_sensor:015]: Device Class: 'light' [21:47:06][C][gpio.binary_sensor:016]: Pin: GPIO5 (Mode: INPUT_PULLUP, INVERTED) [21:47:06][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Bedroom light Switch' [21:47:06][C][gpio.binary_sensor:015]: Device Class: 'light' [21:47:06][C][gpio.binary_sensor:016]: Pin: GPIO4 (Mode: INPUT_PULLUP, INVERTED) [21:47:06][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Bedroom Tube Light Switch' [21:47:06][C][gpio.binary_sensor:015]: Device Class: 'light' [21:47:06][C][gpio.binary_sensor:016]: Pin: GPIO6 (Mode: INPUT_PULLUP, INVERTED) [21:47:06][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Bedroom Fan Switch' [21:47:06][C][gpio.binary_sensor:016]: Pin: GPIO7 (Mode: INPUT_PULLUP, INVERTED) [21:47:06][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Bedroom_Motion' [21:47:06][C][gpio.binary_sensor:015]: Device Class: 'motion' [21:47:06][C][gpio.binary_sensor:016]: Pin: GPIO12 (Mode: INPUT)

[21:47:06][C][logger:138]: Level: DEBUG [21:47:06][C][logger:139]: Log Baud Rate: 115200 [21:47:06][C][logger:140]: Hardware UART: UART0

[21:47:06][C][dht:018]: Pin: GPIO14 (Mode: INPUT) [21:47:06][C][dht:022]: Model: DHT11 [21:47:06][C][dht:027]: Update Interval: 15.0s

[21:47:06][C][dht:029]: Unit of Measurement: '°C' [21:47:06][C][dht:029]: Accuracy Decimals: 1

[21:47:06][C][dht:030]: Unit of Measurement: '%' [21:47:06][C][dht:030]: Accuracy Decimals: 0

[21:47:06][C][ota:029]: Over-The-Air Updates: [21:47:06][C][ota:030]: Address: bedroom.local:8266 [21:47:06][C][ota:032]: Using Password. [21:47:06][C][api:103]: API Server: [21:47:06][C][api:104]: Address: bedroom.local:6053

amishv commented 5 years ago

Success: I was able to overcome this issue by commenting out writ in the following code of PCF8574.cpp.

The datasheet https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwjpttyiiIPlAhW7IbcAHXZ6B4AQFjAAegQIABAC&url=http%3A%2F%2Fwww.ti.com%2Flit%2Fgpn%2Fpcf8574a&usg=AOvVaw3zeEe3lSBYL1bduIIIDSWh say that

The device features an 8-bit quasi-bidirectional I/O port (P0–P7), including latched outputs with high-current drive capability for directly driving LEDs. Each quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal.

Hence, the following code should have been `void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) { switch (mode) { case PCF8574_INPUT: this->ddrmask &= ~(1 << pin); this->portmask &= ~(1 << pin); break; case PCF8574_INPUT_PULLUP: this->ddrmask &= ~(1 << pin); this->portmask |= (1 << pin); break; case PCF8574_OUTPUT: this->ddrmask |= (1 << pin); this->portmask &= ~(1 << pin); break; default: break; }

//this->writegpio(); }`

`void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {}

glmnet commented 5 years ago

So you’re not configuring the chip io port mode then?

amishv commented 5 years ago

My understanding is that there are no equivalent of data direction register (DDR) and Portx Data Register (PORTx) in PCF 8574.

All the pins are quasi-bidirectional I/O port and quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal. So this implementation of DDR and PORT is not needed. It seems there are other methods too where this is implemented and needs to be cleaned up, IMO

amishv commented 5 years ago

It looks like the DDR and PORTx is being used internally and Esphome is needs that to remember the I/O. Only the write the status to PCF is redundant. this->write_gpio_();

glmnet commented 5 years ago

Is it redundant or actually causing this issue?

Can you do a full test that this does not break anything? I.e. Input and input pull up?

amishv commented 5 years ago

@glmnet , I have tried multiple combinations and finally found that DDR and PORTx value is needed for Aurdino library. However, PCF8574 does not need any input output configuration hence writing initial settings is causing the issue. We need to set the data direction and the port register for the Aurdino library, but sending these values to 8574 causes the pin to recycle. And, since each pin is handled individually there is a time lag for each relay to switch on and off. This is visible in the connected devices.

amishv commented 5 years ago

I have updated eight nodes and now the problem of chattering on reboot is gone. I have tested it by switching off the wifi, that caused the nodes to reboot after 5 min. Done with this will work on the issue with direct connect GPIO.

amishv commented 5 years ago

@glmnet ,

I have created a PR #744 with the change.

OttoWinter commented 5 years ago

Closing per https://github.com/esphome/esphome/pull/744