Closed maxx-ukoo closed 4 years ago
did you try INPUT_PULLUP ?
Dear @glmnet dear @maxx-ukoo today i ran into an similar issue: I use the PCF8574 in input mode with external resistors 4k7 mounted. The configuration setting i use was 'mode: INPUT' for all 8 ports (non inverse). If you wire one of the input channels of the PCF8574 to ground (gnd) and power on the board (incl. the esp8266) then the input is fixed to gnd even if you cut the wire later on! You will also get no update in case of high/low voltage changes. That means the port seams to be "disabled".
If the port is not connected (but pulled up by default using external resistors) and the circuit is powered on, everythink works as expected! The port then reflects every change...
Then i tried to use the INPUT_PULLUP mode: Now everything works as expected even if there are two pullups now in parallel...
If in INPUT mode: Could it be that the port is set to outputmode when connected to ground instead of presenting an input port?
Looks like a duplicate of https://github.com/esphome/issues/issues/460 - can someone confirm?
@S-Przybylski,
Can you please provide the voltage on the *INT pin (pin 13 in N package, pin 1 on other packages) for both the cases? This looks like an uncleared interrupt problem. The same could be true for #460 As per the datasheet:
The PCF8574A device provides an open-drain output (INT) that can be connected to the interrupt input of a microcontroller. An interrupt is generated by any rising or falling edge of the port inputs in the input mode. After time, t iv , INT is valid. Resetting and reactivating the interrupt circuit is achieved when data on the port is changed to the original setting or data is read from, or written to, the port that generated the interrupt.
@S-Przybylski, Also, please quote the wifi signal strength Signal strength: -68 dB ▂▄▆█
Dear @amishv my signal strength is -68 dB. After some minutes the logs shows values around -64 dB ... 'WiFi_signal_central': Sending state -64.00000 dB with 0 decimals of accuracy
I currently use interfaces of a german producer (horter), which also be able to forward the INT (inverse) to a individual GPIO and displays the status of each input, the I2C bus (high/low) and also of the INT using LEDs. Yes i can try to measure the voltage, but i just tried a easy method instead. Here are my testcase result using the LED, if i power on the ESP8266 with the PCF8574 board: Prerequisites:
Test 1. Initial situation: no input is wird to ground Observation: The interrupt LED does not light up; all port are working as excepted after boot. The LEDs on the input lines are off (inverted). Each time of a voltage change on any input leads to a flicker of the interrupt LED and the selected input LED reflects the correct input value.
Test 2. Initial situation: Port with input configuration (no internal pullup) is wired to ground Observation: The interrupt LED does light up for a short time. Any later voltage change on this input is not reflected by the interrupt line (no flicker) and! also not reflected by this input LED! It stays on (indicates a gnd level). All other are working as excepted (tested after boot).
Test 3. Initial situation: Port with input pull_up configuration (in parallel with fixed pullup) is wired to ground Observation: The interrupt LED does light up for a short time. Any later voltage change on the input side is reflected by the interrupt line (short flicker) and also reflected by the selected input LED: light is on for gnd and off for vcc.
One notice the the boards: I have connected the same interfaces (boards) directly to a Raspi3b: Here the Node-Red-implementation works a designed (but is not stable -> thats the reason why i want to move to esphome)... All ports are working, independently if the input is set to gnd or vcc at startup.
@S-Przybylski, Can you please provide the voltage on the *INT pin (pin 13 in N package, pin 1 on other packages) for both the cases? This looks like an uncleared interrupt problem. The same could be true for #460 As per the datasheet: The PCF8574A device provides an open-drain output (INT) that can be connected to the interrupt input of a microcontroller. An interrupt is generated by any rising or falling edge of the port inputs in the input mode. After time, t iv , INT is valid. Resetting and reactivating the interrupt circuit is achieved when data on the port is changed to the original setting or data is read from, or written to, the port that generated the interrupt.
How i should connect interupt pin from PCF857X to esp? I didn't find anything about this interupt in documentation - https://esphome.io/components/pcf8574.html On start i see correct pin state, but for update state we need check state on interupt level. Does esphome do this?
Dear @maxx-ukoo Extender like PCF8574 or MCP23008/17 do have the abillity to either wire the interrupt directly to one GPIO or be used by software polling only instead. As i understand the esp8266 implementation, here is polling in use. That means, that the interrupt is reset by software polling.
In my node-red project on a raspi i definitly use the interrupt line to get a sign if a input changes.... This saves cpu power...
Your question regarding the voltage: I can try to do that later
For me it seems to be a software initialisation issue
As i understand the esp8266 implementation, here is polling in use.
Correct, it is polling.
In my node-red project on a raspi i definitly use the interrupt line to get a sign if a input changes.... This saves cpu power...
Well these are very low-power devices anyway and reading i2c data does not take up a lot of time - the WiFi modem on the other hand uses way more power. Plus you have to connect one pin less.
@maxx-ukoo ,
I asked for the *INT pin voltage only to be sure that the chip is functioning normally and the interrupt is getting cleared after every I/O operation. I was looking for the pulse train on INT pin.
I have set up a new node (all my present node are online) today to reproduce this issue over the weekend.
@maxx-ukoo ,
I asked for the *INT pin voltage only to be sure that the chip is functioning normally and the interrupt is getting cleared after every I/O operation. I was looking for the pulse train on INT pin.
I have set up a new node here are the test results. All inputs (without pull-up) were tied to ground at startup.
There is no anomaly observed.
esphome: name: testboard platform: ESP8266 board: nodemcuv2
logger:
i2c: sda: D2 scl: D1 scan: False
pcf8574:
binary_sensor:
platform: gpio name: "Switch1" id: Switch1 pin: pcf8574: pcf8574_hub number: 4
mode: INPUT_PULLUP inverted: True device_class: light on_press: then:
platform: gpio name: "Switch2" id: Switch2 pin: pcf8574: pcf8574_hub number: 5
mode: INPUT_PULLUP inverted: True device_class: light on_press: then:
platform: gpio name: "Switch3" id: Switch3 pin: pcf8574: pcf8574_hub number: 6
mode: INPUT_PULLUP inverted: True device_class: light on_press: then:
platform: gpio name: "Switch4" id: Switch4 pin: pcf8574: pcf8574_hub number: 7
mode: INPUT_PULLUP inverted: True on_press: then:
[19:49:05][I][app:028]: Running through setup()... [19:49:05][C][pcf8574:010]: Setting up PCF8574... [19:49:05][D][binary_sensor:033]: 'Switch1': Sending state ON [19:49:05][D][binary_sensor:033]: 'Switch2': Sending state ON [19:49:05][D][binary_sensor:033]: 'Switch3': Sending state ON [19:49:05][D][binary_sensor:033]: 'Switch4': Sending state ON [19:49:05][I][app:060]: setup() finished successfully! [19:49:05][I][app:096]: esphome version 1.13.6 compiled on Oct 18 2019, 19:48:36 [19:49:05][C][i2c:028]: I2C Bus: [19:49:05][C][i2c:029]: SDA Pin: GPIO4 [19:49:05][C][i2c:030]: SCL Pin: GPIO5 [19:49:05][C][i2c:031]: Frequency: 50000 Hz [19:49:05][C][pcf8574:022]: Address: 0x20 [19:49:05][C][pcf8574:023]: Is PCF8575: NO [19:49:05][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch1' [19:49:05][C][gpio.binary_sensor:015]: Device Class: 'light' [19:49:05][C][gpio.binary_sensor:016]: Pin: GPIO4 (Mode: INPUT_PULLUP, INVERTED) [19:49:05][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch2' [19:49:05][C][gpio.binary_sensor:015]: Device Class: 'light' [19:49:05][C][gpio.binary_sensor:016]: Pin: GPIO5 (Mode: INPUT_PULLUP, INVERTED) [19:49:05][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch3' [19:49:05][C][gpio.binary_sensor:015]: Device Class: 'light' [19:49:05][C][gpio.binary_sensor:016]: Pin: GPIO6 (Mode: INPUT_PULLUP, INVERTED) [19:49:05][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch4' [19:49:05][C][gpio.binary_sensor:016]: Pin: GPIO7 (Mode: INPUT_PULLUP, INVERTED) [19:49:05][C][logger:138]: Level: DEBUG [19:49:05][C][logger:139]: Log Baud Rate: 115200 [19:49:05][C][logger:140]: Hardware UART: UART0 [19:56:36][D][binary_sensor:033]: 'Switch1': Sending state OFF [19:56:36][D][binary_sensor:033]: 'Switch2': Sending state OFF [19:56:36][D][binary_sensor:033]: 'Switch4': Sending state OFF [19:56:36][D][binary_sensor:033]: 'Switch3': Sending state OFF [19:56:45][D][binary_sensor:033]: 'Switch1': Sending state ON [19:56:45][D][main:191]: The state of sw 1 is 1 [19:56:45][D][binary_sensor:033]: 'Switch3': Sending state ON [19:56:45][D][main:197]: The state of sw 3 is 1 [19:56:45][D][binary_sensor:033]: 'Switch1': Sending state OFF [19:56:45][D][binary_sensor:033]: 'Switch3': Sending state OFF [19:56:45][D][binary_sensor:033]: 'Switch3': Sending state ON [19:56:45][D][main:197]: The state of sw 3 is 1 [19:56:45][D][binary_sensor:033]: 'Switch1': Sending state ON [19:56:45][D][main:191]: The state of sw 1 is 1 [19:56:45][D][binary_sensor:033]: 'Switch1': Sending state OFF [19:56:45][D][binary_sensor:033]: 'Switch1': Sending state ON [19:56:45][D][main:191]: The state of sw 1 is 1 [19:56:52][D][binary_sensor:033]: 'Switch4': Sending state ON [19:56:52][D][main:200]: The state of sw 4 is 1 [19:56:52][D][binary_sensor:033]: 'Switch4': Sending state OFF [19:56:53][D][binary_sensor:033]: 'Switch4': Sending state ON [19:56:53][D][main:200]: The state of sw 4 is 1 [19:56:53][D][binary_sensor:033]: 'Switch4': Sending state OFF [19:56:53][D][binary_sensor:033]: 'Switch4': Sending state ON [19:56:53][D][main:200]: The state of sw 4 is 1 [19:56:53][D][binary_sensor:033]: 'Switch4': Sending state OFF [19:56:54][D][binary_sensor:033]: 'Switch4': Sending state ON [19:56:54][D][main:200]: The state of sw 4 is 1 [19:56:54][D][binary_sensor:033]: 'Switch4': Sending state OFF [19:56:55][D][binary_sensor:033]: 'Switch4': Sending state ON [19:56:55][D][main:200]: The state of sw 4 is 1 [19:56:55][D][binary_sensor:033]: 'Switch4': Sending state OFF
Dear @amishv for me it seems that your configuration always uses input_pullup instead of input only.
The testcase will be:
I am realy interrested if you get the same results i have!
@S-Przybylski ,
I can confirm now, input_pullup does not reproduce this issue. here is the log. I already had a problem with 8754 as it is Quasi bidirectional bus it does not need setting like input_pullup .
[22:16:11][C][i2c:028]: I2C Bus: [22:16:11][C][i2c:029]: SDA Pin: GPIO4 [22:16:11][C][i2c:030]: SCL Pin: GPIO5 [22:16:11][C][i2c:031]: Frequency: 50000 Hz
[22:16:11][C][pcf8574:022]: Address: 0x20 [22:16:11][C][pcf8574:023]: Is PCF8575: NO [22:16:11][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch1' [22:16:11][C][gpio.binary_sensor:015]: Device Class: 'light' [22:16:11][C][gpio.binary_sensor:016]: Pin: GPIO4 (Mode: INPUT) [22:16:11][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch2' [22:16:11][C][gpio.binary_sensor:015]: Device Class: 'light' [22:16:11][C][gpio.binary_sensor:016]: Pin: GPIO5 (Mode: INPUT) [22:16:11][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch3' [22:16:11][C][gpio.binary_sensor:015]: Device Class: 'light' [22:16:11][C][gpio.binary_sensor:016]: Pin: GPIO6 (Mode: INPUT) [22:16:11][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch4' [22:16:11][C][gpio.binary_sensor:016]: Pin: GPIO7 (Mode: INPUT)
[22:16:11][C][logger:138]: Level: DEBUG [22:16:11][C][logger:139]: Log Baud Rate: 115200 [22:16:11][C][logger:140]: Hardware UART: UART0
Maybe, we need to check Aurdino Library for 8574???
I was able to correct this by removing redundant code from PCF8574Component::pin_mode The datasheet say it is a Quasi bidirectional port and does not support pullup.
void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) { switch (mode) { case PCF8574_OUTPUT: this->ddrmask |= (1 << pin); this->portmask &= ~(1 << pin); break; default: this->ddrmask &= ~(1 << pin); this->portmask |= (1 << pin); break; }
Below are the logs.
[15:20:04][I][app:028]: Running through setup()... [15:20:04][C][pcf8574:010]: Setting up PCF8574... [15:20:04][D][binary_sensor:033]: 'Switch1': Sending state ON [15:20:04][I][app:060]: setup() finished successfully! [15:20:04][I][app:096]: esphome version 1.13.6 compiled on Oct 19 2019, 15:19:09 [15:20:04][C][i2c:028]: I2C Bus: [15:20:04][C][i2c:029]: SDA Pin: GPIO4 [15:20:04][C][i2c:030]: SCL Pin: GPIO5 [15:20:04][C][i2c:031]: Frequency: 50000 Hz
[15:20:04][C][pcf8574:022]: Address: 0x20 [15:20:04][C][pcf8574:023]: Is PCF8575: NO [15:20:04][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch1' [15:20:04][C][gpio.binary_sensor:016]: Pin: GPIO4 (Mode: INPUT)
[15:20:04][C][logger:138]: Level: DEBUG [15:20:04][C][logger:139]: Log Baud Rate: 115200 [15:20:04][C][logger:140]: Hardware UART: UART0 [15:20:10][D][binary_sensor:033]: 'Switch1': Sending state OFF [15:20:11][D][binary_sensor:033]: 'Switch1': Sending state ON [15:20:11][D][main:092]: The state of sw 1 is 1 [15:20:13][D][binary_sensor:033]: 'Switch1': Sending state OFF [15:20:13][D][binary_sensor:033]: 'Switch1': Sending state ON [15:20:13][D][main:092]: The state of sw 1 is 1 [15:20:20][D][binary_sensor:033]: 'Switch1': Sending state OFF
[15:20:23]logger:116]: Log initialized [15:20:23][I][app:028]: Running through setup()... [15:20:23][C][pcf8574:010]: Setting up PCF8574... [15:20:23][D][binary_sensor:033]: 'Switch1': Sending state OFF [15:20:23][I][app:060]: setup() finished successfully! [15:20:23][I][app:096]: esphome version 1.13.6 compiled on Oct 19 2019, 15:19:09 [15:20:23][C][i2c:028]: I2C Bus: [15:20:23][C][i2c:029]: SDA Pin: GPIO4 [15:20:23][C][i2c:030]: SCL Pin: GPIO5 [15:20:23][C][i2c:031]: Frequency: 50000 Hz
[15:20:23][C][pcf8574:022]: Address: 0x20 [15:20:23][C][pcf8574:023]: Is PCF8575: NO [15:20:23][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Switch1' [15:20:23][C][gpio.binary_sensor:016]: Pin: GPIO4 (Mode: INPUT)
[15:20:23][C][logger:138]: Level: DEBUG [15:20:23][C][logger:139]: Log Baud Rate: 115200 [15:20:23][C][logger:140]: Hardware UART: UART0 [15:20:26][D][binary_sensor:033]: 'Switch1': Sending state ON [15:20:26][D][main:092]: The state of sw 1 is 1 [15:20:26][D][binary_sensor:033]: 'Switch1': Sending state OFF [15:20:26][D][binary_sensor:033]: 'Switch1': Sending state ON [15:20:26][D][main:092]: The state of sw 1 is 1
Dear @amishv i am a little bit confused by now. I just reviewed the specs of the pcf8574 (ti). Could you check/confirm?
@S-Przybylski , Thanks for the bulleted points, this was precisely my point.
I do not find any hint, that input_pullup (for me this is a mode where the input pin is connected to vcc using a internal resistor) can be set up. This is for me quite ok, because my boards have external resistors to vcc installed. Is input_pullup a valid mode at all?
There are no configurable resistors in PCF8574 comparable to AVR. It is a quasi bidirectional pins (port, if you please).
Why does input do not function if a input is wired to gnd, but input_pullup does? Does your change fix this?
Yes, there are further routine in aurdino library which depend on DDR and PORT which are relevant to AVR. we need to set them correctly as we are emulating AVR in Esphome.
Do you provide a pull request for the change?
I have already pasted the solution, I am having issues with github as there were multiple updates today. However if you can test by modifying the lcd_display.cpp & lcd_display.h in the directory
/home/
Why do you use the name switch for binary_sensors? I expect binary_sensors instead
I guess, that is how In wanted to distinguish with the switches that they were handling like
`binary_sensor:
will be related to
switch:id: S2`
Hope that helped.
Oh, do I understand correctly that the PCF8574 doesn't really support input pullup?
Oh, do I understand correctly that the PCF8574 doesn't really support input pullup?
Yes Please.
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.
Submitted pull request https://github.com/esphome/esphome/pull/782
Dear @OttoWinter what i find out was (hoppfully this is right), that the initalization need to configure all input and output ports. All ports which are not defined should be set to output port by default. And yes i don't see any internal pullup (vcc) resitors in place - referring scheme page 12: http://www.ti.com/lit/ds/symlink/pcf8574.pdf
My investigation regarding the current implementation: Input_pullup works while input not.
Dear @OttoWinter could we adapt the setting for input in the same way input_pullup works as a workaround until the module is revised? Then the module works from input side as expected!
Today i have successfully tested this little change in pcf8574.cpp: this->portmask &= ~(1 << pin); --> this->portmask |= (1 << pin);
void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
switch (mode) {
case PCF8574_INPUT:
this->ddr_mask_ &= ~(1 << pin);
// this->port_mask_ &= ~(1 << pin);
this->port_mask_ |= (1 << pin);
break;
case PCF8574_INPUT_PULLUP:
this->ddr_mask_ &= ~(1 << pin);
this->port_mask_ |= (1 << pin);
break;
case PCF8574_OUTPUT:
this->ddr_mask_ |= (1 << pin);
this->port_mask_ &= ~(1 << pin);
break;
default:
break;
}
Operating environment/Installation (Hass.io/Docker/pip/etc.):
Custom ESP32 board with i2C PCF8575 module
Affected component: https://esphome.io/components/pcf8574.html
Description of problem: i have 2 buttons - one directly attached to ESP32 io, second to PCF8575 expander. I able to see state update in logs for gpio attached button, but not for PCF8575 attached
Problem-relevant YAML-configuration entries:
Logs (if applicable):
Additional information and things you've tried: