letscontrolit / ESPEasy

Easy MultiSensor device based on ESP8266/ESP32
http://www.espeasy.com
Other
3.26k stars 2.21k forks source link

PCF8574 Inputs stop responding when other pins used as output. #702

Closed Budman1758 closed 1 year ago

Budman1758 commented 6 years ago

Steps to reproduce

How can we trigger this problem? Set up a PCF8574 with 4 outputs and 4 inputs. Set up 4 as input switches as 4 tasks. Or 3 as in my setup.

Does the problem presist after powering off and on? (just resetting isnt enough sometimes) Yes

Expected behavior

When powered up at first inputs respond as they should. I have 2 reed switches to simulate a door open and closed position indicator. When each switch is actuated I have a rule that writes a line on an OLED display. Works great until ANY of the outputs are triggered.

Actual behavior

When 1 output is triggered 1 of the 2 inputs stops responding. When you trigger another output the second input stops responding. Only way to get the inputs to respond again is to power cycle the setup.

System configuration

-01 module. PCF8574 IO expander. OLED display module (I2C) SI7102 temp and humidity sensor. 4 channel relay board. Temp sensor and OLED module all work fine. Ports 1-4 set as inputs and ports 5-8 connected to relays. 3 tasks for 3 switch inputs to PCF8574.

This is consistent and repeatable with 3 or 4 different PCF8574 chips I have and have tried several different "late model" ESP releases. Right now using >> GIT version: | mega-20180111

I thought I was imaging this but its VERY consistent. After messing around with this for the last 2 days I'm afraid I have no more hair to pull out. Wasn't much to start with tho.....

Let me know what you need as to screenshots or configs.

BTW. The logic is reversed on this chip. It takes a "0" to get a positive output. That normal?? Seems kinda backwards. That had me going for a while......

uzi18 commented 6 years ago

I must confirm, Pcf8574 expander plugin is unreliable sometimes. Did some test in the past on 2.0 firmware, with mixed inputs/outputs but it was sometimes unpredictable. Did not found solution. In keypad plugin it is working ok. Maybe because it is splitted into pins in device configuration.

12.01.2018 8:35 AM "Carl Forster" notifications@github.com napisał(a):

Steps to reproduce

How can we trigger this problem? Set up a PCF8574 with 4 outputs and 4 inputs. Set up 4 as input switches as 4 tasks. Or 3 as in my setup.

Does the problem presist after powering off and on? (just resetting isnt enough sometimes) Yes Expected behavior

When powered up at first inputs respond as they should. I have 2 reed switches to simulate a door open and closed position indicator. When each switch is actuated I have a rule that writes a line on an OLED display. Works great until ANY of the outputs are triggered. Actual behavior

When 1 output is triggered 1 of the 2 inputs stops responding. When you trigger another output the second input stops responding. Only way to get the inputs to respond again is to power cycle the setup. System configuration

-01 module. PCF8574 IO expander. OLED display module (I2C) SI7102 temp and humidity sensor. 4 channel relay board. Temp sensor and OLED module all work fine. Ports 1-4 set as inputs and ports 5-8 connected to relays. 3 tasks for 3 switch inputs to PCF8574.

This is consistent and repeatable with 3 or 4 different PCF8574 chips I have and have tried several different "late model" ESP releases. Right now using >> GIT version: | mega-20180111

I thought I was imaging this but its VERY consistent. After messing around with this for the last 2 days I'm afraid I have no more hair to pull out. Wasn't much to start with tho.....

Let me know what you need as to screenshots or configs.

BTW. The logic is reversed on this chip. It takes a "0" to get a positive output. That normal?? Seems kinda backwards. That had me going for a while......

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/letscontrolit/ESPEasy/issues/702, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHOU5kDfSaMxTGrUPsiyhcjUxLoMc7kks5tJwsvgaJpZM4Rb6UD .

svmac commented 6 years ago

I already described this problem on issue #222 (sorry for my poor english):

PCF8574 documentation states "The I/Os should be HIGH before being used as inputs." (https://www.nxp.com/documents/data_sheet/PCF8574.pdf section 7.3). In function Plugin_019_Write to write an output pin first it reads all pins, then set the pin and write all pins. If coincide an input pin reads LOW, then writes that pin as LOW and that pin leaves to be input pin. That pin always reads LOW until PCF8574 restart (or until explici writes HIGH to that pin; now I make that on rules after write an output pin). I think the solution is to keep a mask in the module and set to HIGH all pins defined as inputs. Then in function Plugin_019_Write apply the mask when read all pins, so all input pins are set to HIGH.

Budman1758 commented 6 years ago

I even tried with external pullups and they had no effect.

uzi18 commented 6 years ago

Yes, because chip tied it into gnd internally

2018-01-12 19:07 GMT+01:00 Carl Forster notifications@github.com:

I even tried with external pullups and they had no effect.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/letscontrolit/ESPEasy/issues/702#issuecomment-357307614, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHOU0Zo7MggYpEcJB9KQmMvPWTBrVorks5tJ5yfgaJpZM4Rb6UD .

Budman1758 commented 6 years ago

Thanks for confirming the problem. I thought I was going crazy for a while there.... :)

Also, whats with the inverted logic? When the pin is "High" (positive voltage) on the device page for the task it shows "0". That makes things confusing for making logic rules.

TD-er commented 6 years ago

If it is really as confusing as you describe, maybe we should hide the abstraction level from the plugin user and make it "easy" again. If I remember correctly, the chip just arrived in the mail last week.

Budman1758 commented 6 years ago

Once you realise the logic is backwards it's not that big a deal. My question is why is it backwards in the first place? Kinda goes against the whole "high" vs "low" logic scheme used everywhere else.

TD-er commented 6 years ago

I remember the chip logic was a bit counter-intuitive.

You have to write a "0" to it to bind the pin to ground. This means if you connect a LED via a resistor to the Vcc, the LED will go on when writing a 0 to the pin.

So write a 0 to force as an output. Write a 1 to allow it to be an input.

So connect a pin via a pull-up resistor to the Vcc. If you write a 1 to it, the pin will be pulled high by the resistor and you can pull it down to ground via a switch. Then it is an input you can read. (switch "open" is signal is high)

When you write a 0 to it, the level will be pulled to gnd, so the signal is low. This also means you cannot use it as an input since the pin is connected to GND.

A very descriptive picture about this "strange" IC:

Budman1758 commented 6 years ago

On my setup you had to type "0" in your command to make the output high. (positive voltage output). pcfgpio,0 >> relay on pcfgpio,1 >> relay off

The relay is +voltage to turn on.

TD-er commented 6 years ago

But how is your relay connected? I imagine exactly like the LED in the drawing I posted? So write a 0 and the pin will be connected to ground and thus a current will flow from Vcc through the relais, through the IC to the GND.

Write a 1 and the pin of the chip will be floating and thus no current will flow.

Budman1758 commented 6 years ago

Sorry. I had part of that backwards. PCF8574 outputs are high and relay is off. Write "0" and relay goes on.

I had thought my relay board were "high" trigger. Turns out they are "low" trigger. So I guess the logic is right. Still have the original issue tho.......

svmac commented 6 years ago

I think this is not a strange IC, but it have open collector outputs (see https://en.m.wikipedia.org/wiki/Open_collector) that is a common and simple way to make input/output pins. The problem is in the plugin, on how it makes the output. I see 3 solutions: 1) don’t mix input and output on the same IC. Use all inputs or all outputs IC. 2) every time writes an output pin, must write 1 on every pin assigned as input 3) correct the plugin

uzi18 commented 6 years ago

Just provide one more command to set where is input and remember it in plugin.

14.01.2018 1:04 PM "svmac" notifications@github.com napisał(a):

I think this is not a strange IC, but it have open collector outputs (see https://en.m.wikipedia.org/wiki/Open_collector) that is a common and simple way to make input/output pins. The problem is in the plugin, on how it makes the output. I see 3 solutions:

  1. don’t mix input and output on the same IC. Use all inputs or all outputs IC.
  2. every time writes an output pin, must write 1 on every pin assigned as input
  3. correct the plugin

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/letscontrolit/ESPEasy/issues/702#issuecomment-357507081, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHOU6DAAj-Rsho3c3YpqMbROWscgvpyks5tKe1HgaJpZM4Rb6UD .

psy0rz commented 6 years ago

i've ordered this chip myself, cant test anything now :)

Budman1758 commented 6 years ago

Should have told me ya needed one. I would send you a couple for free if you can fix the plugin. I've got 20 of them. :)

psy0rz commented 6 years ago

i live in the netherlands, and they are only $1.30 for 5 pcs. with free shipping on aliexpress ;)

uzi18 commented 6 years ago

I'm working on fix for this and #222, almost there. @psy0rz @TD-er, what is idea behind set/getPinState, do we need also store there input state?

psy0rz commented 6 years ago

should be fixed, please reopen if this problem still exists.

beaulif commented 6 years ago

the problem still exists. I try with 4 output (relay active gnd) and 4 input (door switch to gnd), input work well but output works only 2 time after that is it randomly.

uzi18 commented 6 years ago

what versions did you test? What is your last version when it work as expected? show your configuration and test case please

niedz., 5.08.2018, 03:02 użytkownik Gijs Noorlander < notifications@github.com> napisał:

Reopened #702 https://github.com/letscontrolit/ESPEasy/issues/702.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/letscontrolit/ESPEasy/issues/702#event-1771436495, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHOU5RUo4z-1To6sUoyRn7-R_bELNIuks5uNkQkgaJpZM4Rb6UD .

beaulif commented 6 years ago

i try this version ESP_Easy_mega-20180802_normal_ESP8266_4096.bin. for input i use 4 door switch to gnd image

for output i use relay arduino actif low with optocoupler Vcc=3.3volt JDVcc=5volt see shematic of relay: image

uzi18 commented 6 years ago

and esp configuration?

beaulif commented 6 years ago

esp config? for output relay i use this command: active relay 1= http://192.168.0.30/control?cmd=PCFPulse,17,0,4250 active relay 2= http://192.168.0.30/control?cmd=PCFPulse,18,0,4250 active relay 3= http://192.168.0.30/control?cmd=PCFPulse,19,0,4250 active relay 4= http://192.168.0.30/control?cmd=PCFPulse,20,0,4250

image image image image

uzi18 commented 6 years ago

We fixed pcfgpio command, but did not check pcfpulse command ok now we know where to search, for me it is not related to this issue.

@TD-er is it not related to new timers?

beaulif commented 6 years ago

the input works well but, not the output. After activating relay 1 for 4.5 sec the other relays remain active.No matter which relay I activate the others remains activated after the delay.

this afternoon I did another test with a MCP23017 and everything works well I can use my relays and my door contact without problem.

I think that it would be necessary to modify the plugin of the PCF8574 to freeze the input output at initialization.

sorry for my poor english

uzi18 commented 6 years ago

thx for info, will try to find solution

uzi18 commented 6 years ago

What if you execute once:

PCFgpio,17,1
PCFgpio,18,1
PCFgpio,19,1
PCFgpio,20,1

and next execute pcfpulse commands, is it ok than?

TD-er commented 6 years ago

@uzi18 It is very unlikely the new timers cause these issues. I would expect something in parsing of commands.

uzi18 commented 6 years ago

I see here different problem, but we will wait for tests with pcfgpio commands before pcfpulse. @TD-er only pcflongpulse use system timers. pcfpulse use delay() function here.

TD-er commented 6 years ago

Well then those should be using the timers too. Let's make sure they fail the same ;)

TD-er commented 6 years ago

@uzi18 I wass thinking about your remark. Can you take a look when the jobs are being scheduled and what their IDs are in the scheduler? If the on/off jobs are scheduled at the same time (or at least the second one before the first has been processed) and share the same ID, then the first one will be removed from the scheduler.

uzi18 commented 6 years ago

@beaulif we need your feedback here @TD-er i'm thinking about something more simple - if pcfgpio is not marked as output state is unpredictable and for now we wait for feedback or will test it at the evening...

beaulif commented 6 years ago

ok i did the tests asked. PCFgpio ok pcfpulse and pcflongpulse do not work, after sending a pulse to 1 relay all other relays remain activated.

uzi18 commented 6 years ago

@TD-er @beaulif sorry can't reproduce this, everything works fine

uzi18 commented 6 years ago

@TD-er small PR #1635 is ready to marge :D

TD-er commented 6 years ago

@uzi18 I just resolved the merge conflict.

uzi18 commented 6 years ago

thx, my git repo is some commits behind ;)

uzi18 commented 6 years ago

@TD-er still learning how to work with ... platformio - any hint how to upload specific target? upload always choose esp32dev target ...

TD-er commented 6 years ago

When using Atom as editor, you can click in the lower left bottom. This will open a window with all the settings.

I usually start typing there like "upload normal" to get a smaller selection to choose from. Just make sure to select the right one :)

And I found the detection of the uart settings to work best when I press and hold flash and short press reset and then release the flash after a few seconds. (NodeMCU board) PlatformIO sometimes does not detect the UART settings right the first time.

uzi18 commented 6 years ago

@beaulif please test tommorows build/release if will be available

clumsy-stefan commented 6 years ago

there seems to be another issue with the PCF GPIO. if you connect active-high SSR's to the PCF the change of state is never actively sent back.

I defined a task as switch-input pin1 wich shows default 1, when then setting this pin via pcfgpio,1,0 the task stays on 1 and no event is created.. also if I switch back then to 1 no event is created.

as I understand the ten_per_second function it should create a event whenever the level of the respective pin changed.

if I do a "status,pcf,1" it shows me the correct value though (so only the switch input task is not updated...)

interestingly I don't have this issue with low-level triggered normal relay's....

Of course it's easy to work around with a inputswitchstate and taskrun statement... but that's not a really clean solution...

beaulif commented 6 years ago

@beaulif please test tommorows build/release if will be available

ok it is work now for pcfpulse and pcflongpulse thank's

uzi18 commented 6 years ago

@clumsy-stefan please show me how You connect this ssr (drawing) maybe it is pcf hardware design problem? @TD-er do we need to generate event for gpio - output pin? Switch/mcp/pcf does not generate such events.

clumsy-stefan commented 6 years ago

the SSR inputs are connected directly to the PCF's I/O, GND-GND, VCC - 5V Wemos D1 Mini same GND and 5V PCF same GND and 5V plus SCL/SDA for I2C

uzi18 commented 6 years ago

any link for such inputs??

clumsy-stefan commented 6 years ago

SSR: https://www.sainsmart.com/products/4-channel-5v-solid-state-relay-module PCF8547: https://www.aliexpress.com/item/10PCS-LOT-PCF8574-IO-Expansion-Board-I-O-Expander-I2C-Bus-Evaluation-Development-Module/32441083879.html?spm=2114.search0104.3.15.37d46dbaBXXdxW&ws_ab_test=searchweb0_0,searchweb201602_5_10152_10151_10065_10344_10068_10342_10343_10340_10341_10696_10084_10083_5011815_10618_10307_5723615_10134_5011715_10059_100031_10103_10624_10623_10622_10621_10620,searchweb201603_1,ppcSwitch_5&algo_expid=6f45c29f-18fb-4269-b38b-732cc0906a05-2&algo_pvid=6f45c29f-18fb-4269-b38b-732cc0906a05&priceBeautifyAB=0 Wemos D1 Mini: https://wiki.wemos.cc/products:d1:d1_mini

uzi18 commented 6 years ago

why we need to generate such event?

TD-er commented 6 years ago

@uzi18

do we need to generate event for gpio - output pin? Switch/mcp/pcf does not generate such events.

I have not really looked at the code of this plugin. Which event do you mean? sendData for example is normally used to update controllers to send a state (often from 10/sec or 50/sec calls) and SensorSendTask, which does eventually call sendData , is being called on those plugins dat need to do a PLUGIN_READ and apply formula's and stuff. These are all functions that send out an event.

Is there some other case here what is sending events?

uzi18 commented 6 years ago

look at the post of stefan, he want to generate event about gpio goes 1 or 0 when he execute pcfgpio command, for. me it is something new to consideration, thats why I am asking you what do You think about it. for me it is dangerous as it will relaunch rules every time gpio will change.

TD-er commented 6 years ago

I have also very recently learned about these events and how they are sent and being dealt with. For example my notes of yesterday when looking into the MessageDelay:

DeviceTimer:  (per Plugin, run each <interval> seconds)

Initial schedule at boot and when connected to WiFi/MQTT:

    void schedule_task_device_timer_at_init(task_index)
        schedule_task_device_timer(task_index, runAt);

Called from the Scheduler:  

    void process_task_device_timer
        if (TaskDeviceTimer[task_index] != 0)
            schedule_task_device_timer(task_index, newtimer);
        SensorSendTask(task_index);

    void SensorSendTask(byte TaskIndex)
        if (PluginCall(PLUGIN_READ...
            Process TaskDeviceFormula
            sendData

    void sendData(event)
      per controller:
        CPlugin_ptr[event->ProtocolIndex](CPLUGIN_PROTOCOL_SEND, event, dummyString);

      PluginCall(PLUGIN_EVENT_OUT, event, dummyString);    => Not being used!!!!

Called by a lot of plugins from:
  10/sec
  50/sec
    sendData(event)

This sendData does pause the entire system for the set MessageDelay. So I totally agree sending lots of events can be very tricky. On the other hand, I don't know if they are needed at some controller.

I really would like to make the proper GPIO handler to deal with these changes at 1 place, for all GPIO's. I don't think the controllers need to be updated on every GPIO change, except when some controller is subscribing to it, but then use something like a dummy device. A proper fix to me would be to use these extra GPIO's just the same as normal GPIOs and then a plugin like Switch can decide if it is needed to send an event.

The general/central (pick your name) GPIO handler can just schedule such a plugin to have a look at the pins, because one has changed and then decide to send an event. Sending an event on all changes looks to me like a bad fix for this problem.