Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[User Interface and DOC] - Pulldown/pullup in Plugin "Switch input - Switch" #4800

Open
iz8mbw opened this issue Sep 14, 2023 · 10 comments
Open
Labels
Type: Documentation Type: Enhancement Improve something already present Type: Feature Request Add a completely new feature (e.g. controller/plugin) Type: Question Question about how something works with concrete answers

Comments

@iz8mbw
Copy link
Contributor

iz8mbw commented Sep 14, 2023

Hello.
Recently I have done some test and experience using the Plugin "Switch input - Switch" on ESP32 board.
My work was to use a push button switch connected to a pin of the GPIO in order to generate actions/commands.

What I discovered is that just adding a 10 centimeter copper cable to the GPIO (so leave it free on the air) generate a State flapping (floating) between 0 and 1, so it looks like some residual current (or may be better to call "energy") is received (sensed) by the GPIO pin.
I noticed this behavior also depend on the quality of Power Supply, connecting a Power Bank seems that this behavior disappear or is reduced.

This is what I see in the log:

296072: SW : GPIO=18 State=0 Output value=0
296080: EVENT: sw#State=0
296372: SW : GPIO=18 State=0 Output value=1
296380: EVENT: sw#State=1
297072: SW : GPIO=18 State=0 Output value=0
297079: EVENT: sw#State=0
298172: SW : GPIO=18 State=0 Output value=1
298183: EVENT: sw#State=1
299900: SW : GPIO=18 State=0 Output value=0
299912: EVENT: sw#State=0
302972: SW : GPIO=18 State=0 Output value=1
302984: EVENT: sw#State=1
303272: SW : GPIO=18 State=0 Output value=0
303283: EVENT: sw#State=0
304072: SW : GPIO=18 State=0 Output value=1
304083: EVENT: sw#State=1
304272: SW : GPIO=18 State=0 Output value=0
304282: EVENT: sw#State=0
304572: SW : GPIO=18 State=0 Output value=1
304582: EVENT: sw#State=1
304807: SW : GPIO=18 State=0 Output value=0
304819: EVENT: sw#State=0
305172: SW : GPIO=18 State=0 Output value=1
305183: EVENT: sw#State=1
305572: SW : GPIO=18 State=0 Output value=0
305583: EVENT: sw#State=0
305772: SW : GPIO=18 State=0 Output value=1
305782: EVENT: sw#State=1
306145: SW : GPIO=18 State=0 Output value=0
306156: EVENT: sw#State=0
306572: SW : GPIO=18 State=0 Output value=1
306583: EVENT: sw#State=1
306772: SW : GPIO=18 State=0 Output value=0
306784: EVENT: sw#State=0
307304: SW : GPIO=18 State=0 Output value=1
307340: EVENT: sw#State=1
307572: SW : GPIO=18 State=0 Output value=0
307584: EVENT: sw#State=0
308072: SW : GPIO=18 State=0 Output value=1
308083: EVENT: sw#State=1

So also if the push button is not pressed anyway I have a State flapping between 0 and 1.
Well, so in order to fix it I thought to enable the internal pull-down resistor of the ESP32 board, so I went in the Hardware page and I set the GPIO from "Default" to "Input pulldown", then to be sure I also rebooted the board.
I went again in the log and I see the GPIO is still flapping between 0 and 1:

70222: SW : GPIO=18 State=0 Output value=1
70228: EVENT: sw#State=1
70723: SW : GPIO=18 State=0 Output value=0
70729: EVENT: sw#State=0
71223: SW : GPIO=18 State=0 Output value=1
71229: EVENT: sw#State=1
71723: SW : GPIO=18 State=0 Output value=0
71729: EVENT: sw#State=0
72222: SW : GPIO=18 State=0 Output value=1
72233: EVENT: sw#State=1
72722: SW : GPIO=18 State=0 Output value=0
72733: EVENT: sw#State=0
73722: SW : GPIO=18 State=0 Output value=1
73733: EVENT: sw#State=1
74016: SW : GPIO=18 State=0 Output value=0
74032: EVENT: sw#State=0

So only to set the GPIO mode to "Input pulldown" didn't solve.

Then I went in the "Device" page and editing the "Switch input - Switch" and I see there is the option "Internal PullUp:", so I was confused because I need to enable the "PullDown" and not the "PullUp"...
But anyway I tried and I enabled "PullUp" and well, I SOLVED.

So I understood the option to enable or disable the "Internal PullUp:" in fact is related to the GPIO pin settings of the Hardware page.
So if the GPIO pin is configured as "Input pulldown" (in the Hardware page) then when I enable "Internal PullUp:" (in the Device page of the "Switch input - Switch ") it works as PullDown.

So, for what I have discovered, this means the check box to enable or disable "Internal PullUp:" in the Plugin "Switch input - Switch" should be renamed to "Internal PullDown / PullUp:" and add a Note that this setting will follow the GPIO Mode configured in the Hardware page for that GPIO pin.
Currently there is a note for "Inversed Logic:" that say "Note: Will go into effect on next input change.", well we need a new Note for the PullDwon / PullUp that this setting will follow the Mode (PullDwon or PullUp) configured in the Hardware page for that GPIO pin.

Also che be useful to update the DOC (https://espeasy.readthedocs.io/en/latest/Plugin/P001.html) by specify the concept about PullDown and PullUp when this Plugin is used for Switch or Push Button.

More, also here https://espeasy.readthedocs.io/en/latest/Plugin/P001_Switch.html is spcefied "Internal pull-up: Check if you want to use the internal pull-up of the ESP (not all GPIO pins have this internal pull-up.)" so it only specify there is the PullUp and not also the PullDown.

Thanks!

PS: Just a funny note, before I discovered this, in order to solve this flapping of the State, I physically added a 10 kohm resistor between GND and the GPIO pin, so I created the PullDown and I fixed the State flapping. But since it can be used the Internal PullDown resistor of the board and have the same goal, I prefer to use the Internal PullDown.

@iz8mbw iz8mbw changed the title [User Interface] - Pulldown/pullup in Plugin "Switch input - Switch" [User Interface and DOC] - Pulldown/pullup in Plugin "Switch input - Switch" Sep 14, 2023
@tonhuisman
Copy link
Contributor

The internal pull-up/pull-down resistor is a rather high value, around 80-100 kOhm, and in somewhat 'unstable' environments, this isn't enough for a stable, properly defined, signal.
For switches and other on/off states it is usually advised to have a pull-up resistor of 4.7k - 10k, and have the switch/activation signal connect that to GND to activate. This is in confirmation with often used open-collector switches that are only able to pull a signal down, not up, for activation 😃

@iz8mbw
Copy link
Contributor Author

iz8mbw commented Sep 14, 2023

Ciao Ton, ok but if in the Plugin "Switch input - Switch" there is the check box to use these resistors for both PullUp and PullDown anyway it's an error that on the Web interface the text specify only "PullUp".
Then, if 80 kohm resistor can not be enough (since 80 kohm is a too high value), this is another topic.

It can be also specified in the DOC about this internal 80 khom value cannot be enough to have a stable condition, in my case this internal resistor is OK.

@TD-er
Copy link
Member

TD-er commented Sep 14, 2023

So you discovered the way an antenna operates :)

A few best practices:

To make it "hard" for noise to trigger a state change, you should consider 'twisting' the wires.
This way any noise picked up on some part of the wire is cancelled out on the next part.

Some busses, like RS485, use a differential signal, where the receiving end is only looking at the difference between the two lines.
Last week I had measured some of these signals using the analog inputs of my logic analyzer and you could see any noise being picked up on both wires:
image

Since you don't have a differential signal, but just work with "single ended" (voltage measured against GND), you really need to consider to "twist" the cables.
image

The input impedance of the ESP (without pull-up or -down resistor enabled) is near infinite.
Or at least a really high impedance.
Even with the pull-up or -down resistors active, the impedance is in the order of 50k - 100k.
So you hardly need any energy to toggle the logic state of that pin.
Almost any noise picked up by the antenna... ehh wire, is enough to trigger such a logic state change.

So what you need to do is to make sure that it will take more energy to toggle the state change and also reduce the amount of energy picked up.
Twisting cables makes the "loop size" smaller, thus reduces the amount of energy you can pick up.
Using short cables is another good practice.
You can also add some small capacitor close to the GPIO pin and some resistor to either keep it charged or discharged (depending on what switch type you're using)
Just keep an eye on the RC time, so you will be able to detect the shortest required pulse width and reject whatever is shorter.

@TD-er TD-er added Type: Documentation Type: Question Question about how something works with concrete answers Type: Not a bug Issues that later appeared not to be a bug (e.g. user error) labels Sep 14, 2023
@iz8mbw
Copy link
Contributor Author

iz8mbw commented Sep 14, 2023

@TD-er I used a Category 6 ethernet cable (50 cm long) to connect the push button and the GPIO, anyway it flapping (I used a twisted pair).
As I told, also a 10cm cable in the air (like the gpio jumper cables) generates an antenna, so the twisted cable cannot be enough to solve the "antenna" behavior.

As told, for me, the internal PullDown resistor is (for now) OK, maybe the sum of the internal PullDown resistor and the twisted cable is enough.

Thanks for the info but here the topic is the possibility, in ESPEasy, to use the internal PullDown resistor and in the Web Interface (and in the DOC pages) it specified only the PullUp and this generate confusion.

Thanks!

@TD-er
Copy link
Member

TD-er commented Sep 14, 2023

The internal pull-up should only be used on directly connected stuff, like a button on the PCB, or to set a state for a directly connected chip/transistor.

An example use case where a pull-up resistor cannot be used is when some sensor is connected to a pin which needs to be pulled down at boot. (or a pull-down resistor for pins that need to be pulled up)
Some sensors have an enable pin, or you can add some transistor or analog switch chip to keep this external signal disconnected till after boot.

For example a LAN chip with external crystal needs to have this crystal connected to GPIO-0. (on ESP32)
But if you have this crystal enabled during boot, you have a 50/50 chance the ESP may enter flash mode during boot.
So you really need to set the state after boot.

There are numerous other use cases where the pull-up or -down resistor can be useful.

I know ESP32 does allow to set the 'strength' of these pull resistors, but I haven't tried it yet and I also don't know whether it can be set per pin or group of pins.
Also the ESP32 does have some "glitch filter", which does allow to filter out some really high frequency noise in hardware.

So I have planned to have a look at this at some moment, but it may also complicate things as I don't know whether you need to set those strengths again and also what effect this may have on deep sleep current. Also this glitch filtering is based on some hardware timer and I don't know yet whether this makes this timer unavailable for other use cases.
Still this won't turn these into really 'strong' pull resistors and also not filter out low (kHz) frequencies, meaning you still need to add some filtering yourself on the signal.

@iz8mbw
Copy link
Contributor Author

iz8mbw commented Sep 14, 2023

So I have planned to have a look at this at some moment,

Ok, thanks. But what if for now you change this in the UI:
image

so from "Internal PullUp:" to "Internal PullDown / PullUP:"
?

Or, may be more nice, name it as: "Uses Internal pull resistor"

@tonhuisman
Copy link
Contributor

It may depend on the plugin. This checkbox is part of the standard UI, shown based on the device configuration in code, but the actual execution of the code can behave differently from the Switch plugin (that's probably the most 'sophisticated' in this area and most tested).

@TD-er
Copy link
Member

TD-er commented Sep 14, 2023

Yep, adding more options to the bootstates menu should also be implemented in the locations where a pull-up checkbox is used.
And above all, it should be consistent with the current settings.

Right now, the settings file uses an entry for this in the settings as type boolean.
So I have to check how this is actually being implemented by the compiler.
If we're lucky, this has been implemented rather wasteful and thus takes up a full byte.
So we can store upto 8 bits indicating what should be done with that pin.

However, what can be done also depends on which pin is selected as "pin 1" for that task, as not all pins have the same pull-up/down options.
For example the "input only" pins on ESP32 are quite different from the other pins.
And GPIO-16 on ESP8266 is also completely different from the others.

So this takes quite a bit more work and is not just a matter of adding a combo box.
And I would like to do stuff only once and not needing to patch it later :)

@iz8mbw
Copy link
Contributor Author

iz8mbw commented Sep 14, 2023

Ok, yes.
Great and thanks!

@TD-er TD-er added Type: Enhancement Improve something already present Type: Feature Request Add a completely new feature (e.g. controller/plugin) and removed Type: Not a bug Issues that later appeared not to be a bug (e.g. user error) labels Sep 14, 2023
@iz8mbw
Copy link
Contributor Author

iz8mbw commented Sep 14, 2023

Maybe there links can be of interest about internal pull-down/pull-up:

https://people.eecs.berkeley.edu/~boser/courses/49_sp_2019/N_gpio.html

https://linuxhint.com/esp32-pull-up-pins/

It seems the internal pulldown resistor is 17 kohm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Documentation Type: Enhancement Improve something already present Type: Feature Request Add a completely new feature (e.g. controller/plugin) Type: Question Question about how something works with concrete answers
Projects
None yet
Development

No branches or pull requests

3 participants