kolpi
Posts: 4
Joined: Fri Oct 23, 2015 10:01 pm

button multipress with long cable - lamp interference!

Sat Oct 24, 2015 2:24 pm

I'm new to raspberry and also want to detect single, double and triple press of one button wired to the Pi 2 meters away. The button is a momentary switch with two wires. The wire is 2x0.75mm and repurposed from a lamp.

I used the code in this thread but removed things I didn't need. Here is the code I use

Code: Select all

#!/usr/bin/python
import time, commands, os
from time import sleep
import RPi.GPIO as GPIO
from subprocess import Popen

GPIO.setmode(GPIO.BOARD)
gpio_button = 5
GPIO.setup(gpio_button,GPIO.IN,pull_up_down=GPIO.PUD_UP) 
GPIO.add_event_detect(gpio_button,GPIO.FALLING)
GPIO.setwarnings(False)

def triplePress():
  print ("triple press")

def doublePress():
  print ("double press")
  devnull = open(os.devnull, 'wb') 
  Popen(['nohup', '/home/pi/actionB.sh'], stdout=devnull, stderr=devnull)  

def singlePress():
  print ("single press")
  devnull = open(os.devnull, 'wb') 
  Popen(['nohup', '/home/pi/actionA.sh'], stdout=devnull, stderr=devnull)  

def longPress():
  print ("long press")

while True:
   if GPIO.event_detected(gpio_button):
      GPIO.remove_event_detect(gpio_button)
      now = time.time()
      count = 1
      GPIO.add_event_detect(gpio_button,GPIO.RISING)
      while time.time() < now + 1: 
         if GPIO.event_detected(gpio_button):
            count +=1
            time.sleep(.25) # debounce time
      if count == 1:
          longPress()
      elif count == 2:
          singlePress()
      elif count == 3:
          doublePress()
      elif count == 4:
         triplePress()
      GPIO.remove_event_detect(gpio_button)
      GPIO.add_event_detect(gpio_button,GPIO.FALLING)
Button presses are detected. I see the printed text "single press" and so on and the actionA and actionB scripts run.

But there is one problem: when I turn the flourescent ceiling light in the next room on and off the actions are also triggered! That ceiling light is not wired to the Pi. There must be some sort of interference going on. If I shut down the python script that controls the buttons everything else on the Pi runs fine without any interference from the ceiling lamp. So there is something with this specific script and wiring that causes the issue.

I tried to post yesterday but my first post never went through. Since then I've googled and read a lot of posts about using long wires to buttons in raspi. Many say that when the switch is open long wires can become a kind of antenna that pick up interference and make the input pin go back and forth between 1 and 0 (the term is that it "floats"). That would explain why starting the lamp triggers the script actions.

From searching I've seen these suggested solutions: add a resistor before the switch; add an external "pull up" resistor between input and 3V; I switched from another gpio pin to pin 5 since some said it differs by having a forced pull up resistor (but others say any gpio pin should work when the pin's internal resistor is set to pull up like I do in the code above); add a capacitor between input pin and 3V; and some much more complex suggestions.

I have tried these wirings (I hope the illustration is understandable):

1) input pin5 --- (2 meter wire) --- switch --- (2 meter wire) --- pi ground
2) input pin5 --- 10K resistor --- switch --- ground
3) input pin5 --- 1K resistor --- switch --- ground

4) input pin5 --- branch1: switch --- ground
--- branch2: 10K resistor --- 3V

5) input pin5 --- branch1: switch --- ground
--- branch2: 1K resistor --- 3V

In test 1, 3, 4 and 5 I have the same problem. The button works but turning on the lamp sometimes also triggers the script.
In case 2 nothing happened, neither on button press nor when the lamp is switched on.

I don't have any capacitors so haven't tried that yet. I've spend over 4 hours searching and testing. Please help me solve this problem. If capacitor is the solution please describe in detail what capacitor to use and where and in what direction to add it.

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13092
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: button multipress with long cable - lamp interference!

Sat Oct 24, 2015 3:15 pm

I have tried these wirings (I hope the illustration is understandable):
its not an "illustration" and it is also not understandable (not making any sense), there is a reason schematic diagrams were invented!

your schematic diagram should look like this:
Image
note the diagram isn't perfect as it uses the symbol for GND for VCC (3V3) instead of a small black arrow, but its the best I could find with a one minute GOOGLE.

if you have a lot of interference the following might help:
  • lower the pullup resistance, but make it no lower than say 470 ohm
  • twist the wires going to the switch
  • put a small capacitor (typically 100nF) between the GPIO pin and GND
  • In extreme cases loop the twisted wire through a ferrite core, close to the GPIO.
  • in software: code the key detection routine such that it ignores very short impulses

kolpi
Posts: 4
Joined: Fri Oct 23, 2015 10:01 pm

Re: button multipress with long cable - lamp interference!

Sat Oct 24, 2015 7:00 pm

your schematic diagram should look like this
(O_o)
Pardon me but what are the chances that someone new to raspberry electronics will be able to produce a diagram like that when asking the first question? If you wish new forum users to use a special wording or software when describing wiring in questions then it may be a good idea to mention that in the post "First time posters - please read!" and link to a tutorial on such drawings.

In my illustrations I meant "---" to symbolize a wire between the items to the right and left of "---". So illustration (1) would read "wire input pin number 5 to one leg on the switch. Wire the other leg of the switch to a ground pin on the raspberry".

(2) and (3) reads the same but with a resistor inserted between pin number 5 and the switch.

(4) and (5) were supposed to have the text "-- branch1" and "-- branch2" vertically aligned on the two lines. But I suspect the forum software cleared the indendation I had put before "-- branch2".
What I meant with (4) was that we connect two wires to pin number 5 (or rather one wire that we branch on a breadboard into two). Call these the branch wires. Branch wire 1 goes from pin 5 to one leg of the switch. Wire the other leg of the switch to a ground pin. Branch wire 2 goes from pin 5 to a 10K resistor. Wire the other leg of that resistor to a 3V pin. I think (but may be wrong) that this is called adding a "pull up" resistor.

Anyway, I have done some more tests on my own and it appears that the problem is linked to the parts of the code that does "GPIO.add_event_detect" and looks for "GPIO.RISING" and "GPIO.FALLING". I rewrote the code to only check if GPIO.input is true or false and have not so far had the problem again.Update: I was wrong, this wasn't the cause and the code here didn't work. See my next post further below for new code. The button now also appears to work reliably when simply wiring pin 5 to one leg of the switch and the other switch leg to ground. No external resistors used, no external pull up to 3V. However the modified code so far only detects single and double presses, not triple press or longpress. I will need to test more but here is what I have right now.

Code: Select all

import RPi.GPIO as GPIO
import time, commands, os
from subprocess import Popen

GPIO.setmode(GPIO.BOARD)
button = 5
GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
end = 0.7

def double():
  devnull = open(os.devnull, 'wb') 
  Popen(['nohup', '/home/pi/actionB.sh'], stdout=devnull, stderr=devnull)  
def single():
  devnull = open(os.devnull, 'wb') 
  Popen(['nohup', '/home/pi/actionA.sh'], stdout=devnull, stderr=devnull)  

while True:
    input_state = GPIO.input(button)
    if input_state == False:   #pressed
        now = time.time()
        press, release = 0, 0
        while now+end > time.time():  #look for release + 2nd press
          input_state = GPIO.input(button)
          release = 1 if input_state == True else release           #released?
          press = 1 if input_state == False and release else 0   #2nd press?
          if release and press:
            print('double -------')
            double()
            break
        if not (release and press):
         print('single')
         single()
        press, release = 0, 0
        time.sleep(0.5)
I'm very eager to hear if there are any problems with this code or if I could improve it in some way.
if you have a lot of interference the following might help:
lower the pullup resistance, but make it no lower than say 470 ohm
twist the wires going to the switch
put a small capacitor (typically 100nF) between the GPIO pin and GND
In extreme cases loop the twisted wire through a ferrite core, close to the GPIO.
in software: code the key detection routine such that it ignores very short impulses
Thank you. I will get back to that list in case I need to use the add_event_detect RISING/FALLING stuff after all.

Instead of manually stripping the wires from the white plastic they're in and then twisting them is there some other kind of wire that is notably better to use to avoid interference? Would using two wires in a repurposed shielded ethernet cable be better?

One last note. The list you give only increases to the number of "maybe causes" I already felt a bit overwhelmed by after searching and reading before the OP. What would be most useful is advice on which possible cause is most likely and what to try first when troubleshooting problems like this. Detecting the state of a switch at the end of a long wire could be useful in a number of different projects. But I didn't find any comprehensive guide to dealing with interference issues in such cases. I only found a number of posts on specific issues where responders suggested this or that (different things in different threads) and where a lot of stuff was presupposed that a new users would likely not yet know. Perhaps someone - a Raspberry Superhero! - who knows the ins and outs of this and who uses that great power and wisdom to produce such a comprehensive guide. :)
Last edited by kolpi on Thu Oct 29, 2015 12:19 pm, edited 1 time in total.

boyoh
Posts: 1468
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: button multipress with long cable - lamp interference!

Sat Oct 24, 2015 8:26 pm

A little bit of know how ,on what is causing the problems you are having, And how you are dealing with them,

Flurecent lights are well known for causing inductive spikes , due to highly inductive ballast unit to ignight the lamp
some lights have suppressors fitted to circulate this out of exsistance, You are dealing with this with good wiring practice
Try using a supply with a spike filter built in,to your project, there are plenty of filter sockets about

Push button switches, some times the contacts bounce, this can differ from switch to switch, this can give you repetitive signals.
There are various ways to eliminate this A de-bounce circuit, or in the the code, Some times it is the process of elimination
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13092
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: button multipress with long cable - lamp interference!

Sun Oct 25, 2015 5:19 pm

Pardon me but what are the chances that someone new to raspberry electronics will be able to produce a diagram like that when asking the first question?
I don't assume that, but even a rough sketch made with microsoft paint, or a photo of something you drew on a napkin would be better.
also when I said your description made no sense to me, I meant it, I tried to understand it, but there were too many strange conflicting things in it, for example what does:
2) input pin5 --- 10K resistor --- switch --- ground

3) input pin5 --- 1K resistor --- switch --- ground
mean? did you really wire 10K and 1K in parallel? Why?

P_Monty
Posts: 57
Joined: Sat Dec 27, 2014 2:45 pm
Location: Wiltshire, UK

Re: button multipress with long cable - lamp interference!

Sun Oct 25, 2015 7:44 pm

I took that to mean two separate cases - one had a 1k resistor in series with the switch, the other had a 10k.

Can't draw it on my tablet to demonstrate...

boyoh
Posts: 1468
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: button multipress with long cable - lamp interference!

Sun Oct 25, 2015 8:38 pm

I think one of the problems your are having, is you are trying to solve the problems with code

many of your problems are not using the correct value components/resistors in your project.

Do a bit of practical work on a breadboard , gain a little electronic circuit building , and learn Ohms Law.

A 0/12v power supply and a multi meter will be very handy for you, You will then understand how to

interface with Pi in/puts & out/puts safely
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13092
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: button multipress with long cable - lamp interference!

Mon Oct 26, 2015 11:43 pm

but for the love of god, do NOT put a voltage greater than 3V3 on a GPIO, or you will cause a "latch up" which can totally destroy the SoC, (the PI's main chip) after which you can put your PI in the trash.
Rule 101, the PI is NOT 5V tolerant, in fact it is not even 4V tolerant.
So don't go connecting your 0 to 12V power supply directly to any GPIO pin, that could be fatal for your PI!

User avatar
rpdom
Posts: 17173
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: button multipress with long cable - lamp interference!

Tue Oct 27, 2015 8:01 am

Where I've got a Pi and a switch with a long wire in an electrically noisy environment, I've isolated the switch circuit from the Pi by using the switch to drive the LED in an opto-isolator and connected the output transistor of that to the gpio via a couple of resistors. The LED needs a relatively large voltage (2V or so) and won't be affected by any stray EMF (unless in an incredibly noisy environment).

It might seem like overkill, but it works and protects the Pi from electrical spikes on the long wire.

boyoh
Posts: 1468
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: button multipress with long cable - lamp interference!

Wed Oct 28, 2015 10:03 am

mahjongg wrote:but for the love of god, do NOT put a voltage greater than 3V3 on a GPIO, or you will cause a "latch up" which can totally destroy the SoC, (the PI's main chip) after which you can put your PI in the trash.
Rule 101, the PI is NOT 5V tolerant, in fact it is not even 4V tolerant.
So don't go connecting your 0 to 12V power supply directly to any GPIO pin, that could be fatal for your PI!
You will then understand how to interface with the Pi in/puts & out/puts safely
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13092
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: button multipress with long cable - lamp interference!

Wed Oct 28, 2015 11:06 pm

boyoh wrote:
mahjongg wrote:but for the love of god, do NOT put a voltage greater than 3V3 on a GPIO, or you will cause a "latch up" which can totally destroy the SoC, (the PI's main chip) after which you can put your PI in the trash.
Rule 101, the PI is NOT 5V tolerant, in fact it is not even 4V tolerant.
So don't go connecting your 0 to 12V power supply directly to any GPIO pin, that could be fatal for your PI!
You will then understand how to interface with the Pi in/puts & out/puts safely
is this a question?

kolpi
Posts: 4
Joined: Fri Oct 23, 2015 10:01 pm

Re: button multipress with long cable - lamp interference!

Thu Oct 29, 2015 12:07 pm

Sorry for the delayed response. The problem came back soon after my last post I'm afraid. But I've since then worked around it again and it has worked without issues since set up last sunday. My previous change from checking GPIO.RISING/GPIO.FALLING to checking GPIO.input TRUE/FALSE didn't solve it. The solution was to add code steps that verified each press and release had a certain minimum duration. That was one of the items on Mahjongg's list of things to try so thank you for that.

I suppose the extra steps can be done with either rising/falling or true/false type of checking. Here is how I did it

Code: Select all

import RPi.GPIO as GPIO
import time, commands, os
from subprocess import Popen

GPIO.setmode(GPIO.BOARD)
bu = 5  #input pin for one leg of the button, the other button leg goes to ground
GPIO.setup(bu, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #enable pull up resistor 
# GPIO.input(bu) will be FALSE while button press, TRUE while released
end, mini = 0.5, 0.05   
#look (end) seconds for double press
#if a press lasts < (mini) seconds assume noise and ignore

def double():
  devnull = open(os.devnull, 'wb') # in python < 3.3
  Popen(['nohup', '/home/pi/actionB.sh'], stdout=devnull, stderr=devnull)
def single():
  devnull = open(os.devnull, 'wb') # in python < 3.3
  Popen(['nohup', '/home/pi/actionA.sh'], stdout=devnull, stderr=devnull)

p, r, pold  = 1, 0, 0
while True:
    abort = 0
    if not GPIO.input(bu):  #pressed
      now = time.time()
      while now+mini > time.time():
        if GPIO.input(bu):   #too short press, assume noise
          abort = 1 #do nothing
          break
      if not abort:
        p = time.time()  #press verified
    
    abort = 0
    if GPIO.input(bu):    #released
      now2 = time.time()
      while now2+mini > time.time():
        if not GPIO.input(bu):   #too short release, assume noise
          abort = 1
          break
      if not abort:
        if p > r:      #first release after press sequence
          pold = p     #last press
        r = time.time()  #release verified

    if pold+end > time.time() and p > r:  #press release press within (end) seconds
      print('double press')
      p, r, pold = 1, 0, 0
      double()
      time.sleep(1)
    elif pold > 1 and pold == p and pold+end < time.time():  #one press over (end) seconds ago
      print('single press')
      p, r, pold = 1, 0, 0
      single()
      time.sleep(1)
Not elegant but it works. It still only checks single press and double press, no triple press. Long press is treated as a single press. As before any feedback on the code or how to improve it is very much appreciated.

Like before the wiring is simply from pin 5 to one leg of the switch and from the other switch leg to ground. Nothing else. The code then uses the internal pull up resistor. If it is wise to add something more to this (resistors somewhere?) for the long term "health" of the Pi device then please tell me.
boyoh wrote: Flurecent lights are well known for causing inductive spikes , due to highly inductive ballast unit to ignight the lamp some lights have suppressors fitted to circulate this out of exsistance, You are dealing with this with good wiring practice Try using a supply with a spike filter built in,to your project, there are plenty of filter sockets about
That may well be the cause. But as long as my code works without issues I won't change any hardware. But in case someone else finds this through search and want to try it can you explain more. Do you mean the power supply for the Pi? If so what kind of supply? Can you post a link to and a screenshot of such a product.
mahjongg wrote:there were too many strange conflicting things in it, for example what does:
2) input pin5 --- 10K resistor --- switch --- ground
3) input pin5 --- 1K resistor --- switch --- ground
mean? did you really wire 10K and 1K in parallel? Why?
Like P_Monty said, that was a numbered list of separate tests I had done. I later referred to them "test 1", "case 2" but realize I could've made that more clear.
rpdom wrote:Where I've got a Pi and a switch with a long wire in an electrically noisy environment, I've isolated the switch circuit from the Pi by using the switch to drive the LED in an opto-isolator and connected the output transistor of that to the gpio via a couple of resistors. The LED needs a relatively large voltage (2V or so) and won't be affected by any stray EMF (unless in an incredibly noisy environment).
I have trouble picturing how to wire that. Probably because I'm new to optoisolators. If the switch circuit is isolated from the Pi does that separate circuit then need an additional power source?
rpdom wrote:It might seem like overkill, but it works and protects the Pi from electrical spikes on the long wire.
Would you say that the wiring and code I now have is lacking in such protection and if so what would the risks with that be?

User avatar
rpdom
Posts: 17173
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: button multipress with long cable - lamp interference!

Thu Oct 29, 2015 8:21 pm

kolpi wrote:I have trouble picturing how to wire that. Probably because I'm new to optoisolators. If the switch circuit is isolated from the Pi does that separate circuit then need an additional power source?
I use the 5V from the Pi to power the switch side of the circuit.

Simply, the switch side is something like:

5V---[Switch]---[1K resistor]---[Opto-isolator LED]---Ground

The Pi side is

3V3---[Opto-isolator transistor]---[GPIO]---[10K resistor]---Ground

When the switch is closed the LED lights (but you can't see, as it is inside the package), the transistor is turned on and the GPIO is pulled up to 3.3V.

boyoh
Posts: 1468
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: button multipress with long cable - lamp interference!

Thu Oct 29, 2015 9:10 pm

As I said before, you are trying to eliminate all your problems with (CODE ) You said you did not

want to change any hardware, The reason is you don't understand electronics, and , this you must learn

What good is coding , If you do not have secure well designed circuit to code...Get a book on electronics

on starter circuits to build. You will soon learn how to use opto Isolators . You are half way there knowing

how to code
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

drgeoff
Posts: 10765
Joined: Wed Jan 25, 2012 6:39 pm

Re: button multipress with long cable - lamp interference!

Thu Oct 29, 2015 11:09 pm

Perhaps 90% of coders know Sweet Fanny Adams about electronics, hardware, Ohm's law etc.

Does that mean it is not necessary to know such things in order to be a good coder? Or does it mean that 90% are not good coders? :)

boyoh
Posts: 1468
Joined: Fri Nov 23, 2012 3:30 pm
Location: Selby. North Yorkshire .UK

Re: button multipress with long cable - lamp interference!

Fri Oct 30, 2015 10:06 am

drgeoff wrote:Perhaps 90% of coders know Sweet Fanny Adams about electronics, hardware, Ohm's law etc.

Does that mean it is not necessary to know such things in order to be a good coder? Or does it mean that 90% are not good coders? :)

drgeoff, I read your post with interest, I admire a good programmer, I think if a programmer knows

what's on the other side of the fence, he will be able to sort out problems on that side.

I've followed men of your posts all very good, you have solved many programming and electronic

problems, so you know both sides, And I bet you get a lot of enjoyment from that. I must admit

I'm not a programmer , I try to help with electronics, I was 80yrs before I knew the Raspberry P existed

at that age your brain gets puddled The only way to learn electronics is building and testing circuits.

and good books,,,,,,,,,,,,Regards BoyOh
BoyOh ( Selby, North Yorkshire.UK)
Some Times Right Some Times Wrong

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 13092
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: button multipress with long cable - lamp interference!

Fri Oct 30, 2015 1:12 pm

drgeoff wrote:Perhaps 90% of coders know Sweet Fanny Adams about electronics, hardware, Ohm's law etc.

Does that mean it is not necessary to know such things in order to be a good coder? Or does it mean that 90% are not good coders? :)
No, a coder needs to know nothing about electronics, but any coder who adds interface logic to his hardware needs to know what he is doing, as he went into the world of electronics, he needs to know about it.

By the way, a quick google delivered this picture of a good opto-coupler isolated switch input.
For 99% of cases this would be overkill, but in an industrial application where the switch might be hundreds of meters from the "computer" this is a good solution. Note for this picture, VCC MUST be the 3.3V supply, and the 5V source can be the 5V from the GPIO header instead of a battery. The wire pair to the switch should be a twisted wire pair, with the opto isolator and its components close to the PI.

Return to “Troubleshooting”