Hi, let me just start out by saying I'm very new at this and some of the questions I ask might be a little "basic"
Long story short, the results I get from the example code are wildly inaccurate. When left alone, the button shows pressed ALMOST ALL THE TIME. This occurs whether I have the state_switch set to off or on.
I'll include everything down below:
a) the slightly modified code
b) the terminal output
c) breadboard setup
All I want to do is know how to reliably detect a button push so that I can execute some other code I've got.
Here are the questions I have:
1) Should the state_switch be OFF or ON?
2) What is the input_event function for?
3) Where would I use input_switch function to debounce?
4) What could be causing the phantom button presses?
5) How can I prevent them?
6) Do I have everything wired ok?
Thanks
----- the code
'''A demonstration program for GCGB and GCB.
''' Interrupt - OnChange event example - Interrupt Switch Counter for mega328p
'''--------------------------------------------------------------------------------------------------------------------------------
'''This program demonstrates Interrupt upon the button press on portb.0
'''Each microprocessor will have different commands to setup the Interrupt. Refer to datasheet.
'''When each interrupt event occurs a counter is incremented.
'''Afer each event the counter is shown on the terminal.
'''The demonstration also show the four states a button can be in UP, PRESSED, DOWN and RELEASED.
'''Enjoy
'''@author EvanV
'''@licence GPL
'''@version 1.1a
'''@date 20.02.2015
'''********************************************************************************
#chip mega328p, 16
#option explicit
; ----- Define Hardware settings
'Config hardware UART
#define USART_BLOCKING
#define USART_BAUD_RATE 9600
#define USART_DELAY 10 ms
'Required for switch_event method
Dir SwitchIn1 In
; ----- Constants
'Required for switch_event method
#Define BUTTON_UP 0
#Define BUTTON_PRESSED 1
#Define BUTTON_DOWN 2
#Define BUTTON_RELEASED 3
#Define BUTTON_UNKNOWN 4
'Required for switch_event method
#define SwitchIn1 PORTb.0
#define check_switch PORTb.0
#define state_switch OFF
;----- Variables
Dim CURRENT_STATE, OLD_STATE, BTN as Byte
Dim ButtonPressCount as BYTE
ButtonPressCount = 0
'Required for switch_event method
Dim btn_pv
; ----- Main body of program commences here.
'Enable portb.0 as the source of the interrupt. See the datasheet for more information.
'Trigger on change of PB0
PCINT0 = 1
On Interrupt PinChange0 Call ButtonPressed
Wait 5 s
HSerPrintCRLF 2
HSerPrint "Started"
HSerPrintCRLF
'track button presses - required to manage serial display only
old_state = 0
do forever
'determine the state of the switch
current_state = switch_event
'if the current state is not the same as the saved state then print current state
if current_state <> old_state then
HSerPrint "Changed State: "
HSerPrint current_state
HSerPrintCRLF
'save state
old_state = current_state
else
HSerPrint "Stable State: "
HSerPrint current_state
HSerPrintCRLF
end if
'if the current state is Released then show the count.
'count is incremented in the Interrupt routine.
if current_state = BUTTON_RELEASED then
HSerPrint "Button Press Count: ("
HserPrint ButtonPressCount
HSerPrint ")"
HSerPrintCRLF
' Restore intterupt
On Interrupt PinChange0 Call ButtonPressed
end if
'print only if the button is Pressed. Formatting display only.
if current_state = BUTTON_PRESSED then
HSerPrintCRLF
HSerPrint "PRESS!"
HSerPrintCRLF
end if
loop
end
; ----- Support methods. Subroutines and Functions
sub ButtonPressed
'Check port is depressed/down? If yes, then increment counter
if check_switch = 1 then
ButtonPressCount++
On Interrupt PinChange0 Ignore
end if
end sub
'/****************************************************************************
' Function:
' input_event(void)
'
' Summary:
' Processes the single button into the states UP, DOWN, PRESSED & RELEASED.
'
' Description:
' This function helps write user interface state machines by determining when
' the button was pressed, released
'
' Precondition:
' None
'
' Parameters:
' None
'
' Returns:
' event_t value of the current button events.
' Valid responses are BUTTON_UP, BUTTON_DOWN, BUTTON_PRESSED, BUTTON_RELEASED
'
' Remarks:
' state_switch inverts the port. If high then use state_switch=off
' #define SwitchIn1 PORTD.2
' Dir SwitchIn1 In
' #define check_switch RD2
' #define state_switch OFF
'
' ***************************************************************************/
function switch_event()
dim ret As byte
Dim btn as Byte
btn = check_switch = state_switch
if !btn & !btn_pv then
' button is not pressed now nor was it pressed previously
ret = BUTTON_UP
END if
if btn & !btn_pv then
' button is pressed now but it wasn't previously
ret = BUTTON_PRESSED
End if
if btn & btn_pv then
' button was pressed previously and is still pressed
ret = BUTTON_DOWN
end if
if !btn & btn_pv then
' button is not pressed now but it was previously
ret = BUTTON_RELEASED
End If
btn_pv = btn
switch_event = ret
End Function
' Debounce button, Debounce switch
Function input_switch ( )
input_switch = false
If check_switch = state_switch Then
ButtonCount = 0
Do While check_switch = state_switch and ButtonCount < 4
wait 5 ms
ButtonCount = ButtonCount + 1
Loop
end if
If ButtonCount > 3 then
input_switch = true
ButtonCount = 0
end if
End Function
A4 Green to SDA display 1 to Orange SDA display 2
A5 Yellow to SCL display 1 to Yellow SDA display 2
5V Orange to VCC display 1
5V Orange to VCC display 2
A pins side GND Black to GND display 1
A pins side GND Black to GND display 2
D pins side GND to switch
D8 to switch
not that it's much help, but I've included a couple of pictures as well:
Last edit: George Alvarez 2017-11-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is probably my fault. In the header of the example is does not provide one important statement.... add a suitable resistor to pull up the port to which the switch is attached.
Hi, thanks for responding. A great product/project you have here.
I was hoping to get away with the internal resistor only, but I guess you're saying that doesn't work. OK, I'll hook it up and report back. I think I understand what it does.
What about that debouncing code? As far as I can tell, it's not actually used. Maybe I missed the call to the function, but I don't see it anywhere.
Thanks again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First I tried a pull-down resistor,10K ohm between ground pin on the Nano and the switch. This did not behave much differently. Then I tried 2.2K, that didn't work either. Then I kept going down, my next value without having to go to the store was 680 Ohms. They all acted pretty much the same, where at first, BUTTON_UP (0) was the usual state. But by the 10th false positive button press, I never saw a 0 again.
The 10K pull-up resistor, on the other hand, works flawlessly. No false positives in 1500 cycles, and always responsive to a button click, even on the quickest clicks using my cheapest (i.e. electronically noisiest) button!
So, I'm very happy with this, as I can now proceed with the rest of my project. Thank you for your help with this, and for all the work you do on this too.
However, I'm still left with some of my original questions:
1) Why would I use state_switch ON vs. OFF? Can you provide a practical example?
2) What is the input_event function for? Is this merely the old comments for new and improved switch_event function that performs the same function?
3) Where would I use input_switch function to debounce? In other words, where would I call this function in the code? I still don't see where it is ever called.
4) What could be causing the phantom button presses? Never mind. I think I have a sense of this.
5) How can I prevent them? Totally answered! Thank you.
6) Do I have everything wired ok? It seems like I do.
Thanks again!
George
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) Why would I use state_switch ON vs. OFF? Can you provide a practical example?
Some boards, like the Microchip boards have the switch pulled low. So, you can invert.
2) What is the input_event function for? Is this merely the old comments for new and improved switch_event function that performs the same function?
Old comments... when this was ported this was left iin. Delete.
3) Where would I use input_switch function to debounce? In other words, where would I call this function in the code? I still don't see where it is ever called.
This can be used, optional
4) What could be causing the phantom button presses? Never mind. I think I have a sense of this.
5) How can I prevent them? Totally answered! Thank you.
6) Do I have everything wired ok? It seems like I do.
Welcome.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, let me just start out by saying I'm very new at this and some of the questions I ask might be a little "basic"
Long story short, the results I get from the example code are wildly inaccurate. When left alone, the button shows pressed ALMOST ALL THE TIME. This occurs whether I have the state_switch set to off or on.
I'll include everything down below:
a) the slightly modified code
b) the terminal output
c) breadboard setup
All I want to do is know how to reliably detect a button push so that I can execute some other code I've got.
Here are the questions I have:
1) Should the state_switch be OFF or ON?
2) What is the input_event function for?
3) Where would I use input_switch function to debounce?
4) What could be causing the phantom button presses?
5) How can I prevent them?
6) Do I have everything wired ok?
Thanks
----- the code
----- terminal output
'Required for switch_event method
Define BUTTON_UP 0
Define BUTTON_PRESSED 1
Define BUTTON_DOWN 2
Define BUTTON_RELEASED 3
Define BUTTON_UNKNOWN 4
Started
Changed State: 2
Changed State: 3
Button Press Count: (1)
Changed State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Changed State: 1
PRESS!
Changed State: 3
Button Press Count: (2)
Changed State: 0
Stable State: 0
Stable State: 0
Changed State: 1
PRESS!
Changed State: 3
Button Press Count: (3)
Changed State: 0
Changed State: 1
PRESS!
Changed State: 2
Stable State: 2
Stable State: 2
Changed State: 3
Button Press Count: (4)
Changed State: 1
PRESS!
Changed State: 2
Changed State: 3
Button Press Count: (5)
Changed State: 0
Stable State: 0
Stable State: 0
Changed State: 1
PRESS!
Changed State: 3
Button Press Count: (6)
Changed State: 0
Changed State: 1
PRESS!
Changed State: 2
Stable State: 2
Stable State: 2
Stable State: 2
Changed State: 3
Button Press Count: (7)
Changed State: 0
Changed State: 1
PRESS!
Changed State: 2
Changed State: 3
Button Press Count: (8)
Changed State: 0
Stable State: 0
Stable State: 0
Changed State: 1
PRESS!
Changed State: 3
Button Press Count: (9)
Changed State: 0
Changed State: 1
PRESS!
Changed State: 2
Stable State: 2
Stable State: 2
Changed State: 3
Button Press Count: (10)
----- breadboard setup
Arduino Nano clone w/ ATMega328P
Nano pin color wire to ...
A4 Green to SDA display 1 to Orange SDA display 2
A5 Yellow to SCL display 1 to Yellow SDA display 2
5V Orange to VCC display 1
5V Orange to VCC display 2
A pins side GND Black to GND display 1
A pins side GND Black to GND display 2
D pins side GND to switch
D8 to switch
not that it's much help, but I've included a couple of pictures as well:
Last edit: George Alvarez 2017-11-26
oops!
Last edit: George Alvarez 2017-11-26
Welcome.
A good post!
This is probably my fault. In the header of the example is does not provide one important statement.... add a suitable resistor to pull up the port to which the switch is attached.
So, do you have a pull-up (or, pull-down) resistor fitted? https://en.wikipedia.org/wiki/Pull-up_resistor
Hi, thanks for responding. A great product/project you have here.
I was hoping to get away with the internal resistor only, but I guess you're saying that doesn't work. OK, I'll hook it up and report back. I think I understand what it does.
What about that debouncing code? As far as I can tell, it's not actually used. Maybe I missed the call to the function, but I don't see it anywhere.
Thanks again.
Anobium, here's my report:
First I tried a pull-down resistor,10K ohm between ground pin on the Nano and the switch. This did not behave much differently. Then I tried 2.2K, that didn't work either. Then I kept going down, my next value without having to go to the store was 680 Ohms. They all acted pretty much the same, where at first, BUTTON_UP (0) was the usual state. But by the 10th false positive button press, I never saw a 0 again.
The 10K pull-up resistor, on the other hand, works flawlessly. No false positives in 1500 cycles, and always responsive to a button click, even on the quickest clicks using my cheapest (i.e. electronically noisiest) button!
Like this:
Started
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
then I click my button:
Changed State: 1
PRESS!
Changed State: 2
Changed State: 3
Button Press Count: (8)
Changed State: 0
Stable State: 0
Stable State: 0
Stable State: 0
Stable State: 0
So, I'm very happy with this, as I can now proceed with the rest of my project. Thank you for your help with this, and for all the work you do on this too.
However, I'm still left with some of my original questions:
1) Why would I use state_switch ON vs. OFF? Can you provide a practical example?
2) What is the input_event function for? Is this merely the old comments for new and improved switch_event function that performs the same function?
3) Where would I use input_switch function to debounce? In other words, where would I call this function in the code? I still don't see where it is ever called.
4) What could be causing the phantom button presses? Never mind. I think I have a sense of this.
5) How can I prevent them? Totally answered! Thank you.
6) Do I have everything wired ok? It seems like I do.
Thanks again!
George
1) Why would I use state_switch ON vs. OFF? Can you provide a practical example?
Some boards, like the Microchip boards have the switch pulled low. So, you can invert.
2) What is the input_event function for? Is this merely the old comments for new and improved switch_event function that performs the same function?
Old comments... when this was ported this was left iin. Delete.
3) Where would I use input_switch function to debounce? In other words, where would I call this function in the code? I still don't see where it is ever called.
This can be used, optional
4) What could be causing the phantom button presses? Never mind. I think I have a sense of this.
5) How can I prevent them? Totally answered! Thank you.
6) Do I have everything wired ok? It seems like I do.
Welcome.