I have a Raspberry Pi running Raspbian via NOOBS. I have a button wired to pins 1 and 11. I'm attempting to use GPIO's .add_event_detect and RPIO.RISING to call a function upon the button press. (The callback turns on an led for 2 seconds, and then turns it off.)
I'm finding that the RPIO.RISING function is calling the callback on both the button press (pin 11 goes from 0 to 1) AND the button release (pin 11 goes from 1 to 0). The light is being turned on twice, exactly as it would if I were using RPIO.BOTH.
I don't think that this is a hysteresis / noisy signal issue, because I can depress the button for many seconds, and then let go and see the callback called again.
Here is the example code:
import RPi.GPIO as GPIO ## Import GPIO library
import time
#configure all of the inputs / outputs properly
def config():
#initalize the GPIO pin numbering
GPIO.setmode(GPIO.BOARD) ## Use board pin numbering
#setup output pins
GPIO.setup(8, GPIO.OUT) ## Setup GPIO Pin 7 to OUT
GPIO.setup(10,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
#initialize the inputs for the button
GPIO.setup(11, GPIO.IN)
#create the button-watching function
GPIO.add_event_detect(11, GPIO.RISING, callback=execute_lights, bouncetime=800)
#the light-turning-on function. One press turns yellow. Second press turns green, then off.
def execute_lights(channel):
print "executing lights: "
#Turn on the light we want
GPIO.output(8,True)
#turn green off after 2 seconds
time.sleep(2)
GPIO.output(8,False)
Is there a software workaround that I can use to address this issue?
For whatever reason the implementation of bounctime is very strange.
If you hold and release your button WITHIN your set bounce time of 800ms, it should work OK. If you hold it longer, then you will get triggering on the release, sometimes. I had the same issue, thinking 'bounctime' was the time that the 'system' ignored all other inputs...like the 'settling' time for a switch. It's not. So as long as u press and release your button WITHIN your set bouncetime, you should fine it works OK.
Nick
Related
please.
I am having weird behavior with STM32F105RB (64pins) board, the issue is on GPIO PB8, PB15, PB9 and PB3.
GPIO_InitTypeDef BOARDPINS;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
BOARDPINS.GPIO_Pin=(GPIO_Pin_9);
BOARDPINS.GPIO_Mode=GPIO_Mode_Out_PP;
BOARDPINS.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &BOARDPINS);
DISABLEJTAG();
The Problem:
Each time i configured one of these as OUTPUT PUSH PULL (PB8, PB15, PB9, PB3) and toggle a pin, they all act like there is a shot circuit. all these three pins will toggle together.
My Diagnosis:
I tested for continuity (shot circuit) among these pins by taking off power and physically test pair of these GPIOs. but no shot was detected.
I checked the datasheet and reference manual but did not see any special feature associated with these pins.
Every other pin with exception of these four toggles individually, no issue.
My based IDE is Truestudio 9.3.0, i tried using eclipse with arm plugins and also tried Arduiono 1.18.19. none got it solved.
Now, I am asking
What could be wrong?
Is there feature is need to disable?
Can you please tell me what's the best way to catch a low state (or falling-edge more precisely) of GPIO in an endless script?
To be clear I will run this script at boot (in the bg) and everytime when a user will push a button (connected to this GPIO) this will put this pin at LOW state. I want to detect each one of them and perform actions at every push.
I already have this code but it will consume to much CPU I think... I need sth like an interrupt in my mind :
import RPi.GPIO as GPIO
#Set GPIO numbering scheme to pinnumber
GPIO.setmode(GPIO.BCM)
#setup pin 4 as an input
GPIO.setup(4,GPIO.IN)
# To read the state
While true:
state = GPIO.input(4)
if state:
print('on')
else:
print('off')
EDIT
Here the pinout by BCM or BOARD, I will work with BCM
As you can the the pin number is 4 because my push button is on GPIO4.
Still get off all the time with your code or constant detection of edge event with the code of #jp-jee
EDIT
#!/usr/bin/env python3
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4,GPIO.IN)
def Callback(channel):
print('pushed')
GPIO.add_event_detect(4, GPIO.FALLING, callback = Callback, bouncetime = 300)
while(True):
time.sleep(1)
Now my code print always pushed when the button is released and print nothing when I push it...
Take a look at the documentation of raspberry-gpio-python.
What you want is GPIO.add_event_detect(channel, GPIO.RISING) in combination with a callback function.
Since you're using a button, you also need to consider bouncing.
In the end, you will end up with something like this (taken from the linked website):
def my_callback(channel):
print('This is a edge event callback function!')
GPIO.add_event_detect(channel, GPIO.FALLING, callback=my_callback, bouncetime=200)
Have you tried to use interrupts?
import time
import RPi.GPIO as GPIO
GPIO.setup(4, GPIO.IN)
def Callback(channel):
state = GPIO.input(channel)
if state:
print('on')
else:
print('off')
GPIO.add_event_detect(4, GPIO.FALLING, callback = Callback, bouncetime = 300)
while(True):
time.sleep(1)
I have a raspberry pi 3 running a program made in Xojo.
My goal is to have two flow sensors which display the amount of water that flows though each sensor on the screen.
I have a program that works for one flow sensor, it uses the GPIO library and a custom module called 'InterruptModule'. I followed a tutorial to make this program.
Tutorial: https://einhugur.com/blog/index.php/xojo-gpio/connecting-button-with-gpio-and-using-interupts/#comment-14
This program works successfully for both flow sensors, but only one at a time. I.e if I change the input pin and run the program again it works.
HOWEVER, when I try combine the two it responds can't differentiate between the two inputs.
I have tried with two GPIO modules and two custom 'InterruptModule' modules but it still counts the inputs under whichever sensor is defined first.
See my attempt here.
Screenshot of Xojo code
One way to differentiate between the two interrupts is to create two separate callback method.
Example:
Const kPin = 14
If GPIO.WiringPiISR(kPin, GPIO.EDGE_RISING, Addressof InteruptModule.ButtonDownInterupt1) = -1 then
MsgBox "Could not register for Interupt1 on kPin14"
End If
Const kPin = 18
If GPIO.WiringPiISR(kPin, GPIO.EDGE_RISING, Addressof InteruptModule.ButtonDownInterupt2) = -1 then
MsgBox "Could not register for Interupt2 on kPin18"
End If
In this example, each pin interruption would have its own callback method with different code to work with each pin.
I am a novice at electronics as well as psoc so forgive me here... I have an application that uses a control register with 7 outputs... From what I can understand, when I call I_Control_Reg_Write(0) I turn it off, and if I call I_Control_Reg_Read() first and use the value I read from that and call I_Control_Reg_Write(value) that it will turn this Control Register back on?
To give you more insight on what I am doing.... when program first boots up, it is doing this...
TX_ena_Write(0);
I_Control_Reg_Write(0x02);
uint8_t mytemp = I_Control_Reg_Read();
I_Control_Reg_Write (mytemp & 0x0f);
Then when turning the registers off I am doing this...
g_RegValue = I_Control_Reg_Read();
I_Control_Reg_Write(0);
To turn it on,
I_Control_Reg_Write(g_RegValue);
Which the code chunks above work if I turn off the register for 3 seconds, and turn in on for 1 second... But once I leave it off for more than 3 seconds, I can't seem to turn it back on....
I have a sensor with the interrupt output connected to a input pin on my RaspberryPi. My goal is to trigger an event from the sensor interrupt. The data sheet for my sensor says that once an interrupt is triggered on the sensor, the interrupt status register will have the appropriate bit set to 1 and stay that way until it is cleared; while the status register has a status bit of 1, the interrupt pad on the sensor will be pulled down.
My problem is that I can see the status register correctly reflect an interrupt when I physically trigger the sensor. But when I read the pin from my Pi, I never see any change reflected. Here's the gist of my code:
import Sensor
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN, pull_up_down = GPIO.PUD_UP)
s = Sensor.start()
while True:
print 'sensor int reg: ', s.readIntReg() # I do not clear interrupt
print 'pin value: ', GPIO.input(11)
The first print will change according to my interaction with the sensor as expected. The second print shows the pin holds 1 or 0 depending on whether it is set to pull up or down, respectively.
It seems like the problem lies in that whenever the interrupt fires, the sensor is pulling the pin down and the Pi is pulling it up... How should I handle this?
The sensor is the VCNL4010 [https://www.adafruit.com/products/466]
I suppose you have the gpio driver installed and active on the Pi?
Then you'll probably never see the interrupt triggering from the Python level since the kernel driver will service it (and reset the flag) already in the background.
I added a 10k external pull-up resistor with 3.3V and that did the trick... not sure why the internal pull-up on the Pi didn't do the same, perhaps I configured it wrong.
UPDATE: That turned out not to be the issue at all. I was neglecting to explicitly set the sensor to free run mode. Part of my code had the unintended side effect of setting that mode so in tweaking things for test sometimes it worked. The pull-up on the Pi works fine.