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-OnChangeeventexample-InterruptSwitchCounterformega328p'''--------------------------------------------------------------------------------------------------------------------------------'''ThisprogramdemonstratesInterruptuponthebuttonpressonportb.0'''Each microprocessor will have different commands to setup the Interrupt. Refer to datasheet.'''Wheneachinterrupteventoccursacounterisincremented.'''Afer each event the counter is shown on the terminal.'''ThedemonstrationalsoshowthefourstatesabuttoncanbeinUP,PRESSED,DOWNandRELEASED.'''Enjoy'''@authorEvanV'''@licence GPL'''@version1.1a'''@date 20.02.2015'''********************************************************************************#chipmega328p,16#optionexplicit;----- Define Hardware settings'Config hardware UART #define USART_BLOCKING #define USART_BAUD_RATE 9600 #define USART_DELAY 10 ms 'Requiredforswitch_eventmethodDirSwitchIn1In;----- 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 'Requiredforswitch_eventmethod#defineSwitchIn1PORTb.0#definecheck_switchPORTb.0#definestate_switchOFF;----- VariablesDimCURRENT_STATE,OLD_STATE,BTNasByteDimButtonPressCountasBYTEButtonPressCount=0'Required for switch_event method Dim btn_pv; ----- Main body of program commences here. 'Enableportb.0asthesourceoftheinterrupt.Seethedatasheetformoreinformation.'Trigger on change of PB0 PCINT0 = 1 On Interrupt PinChange0 Call ButtonPressed Wait 5 s HSerPrintCRLF 2 HSerPrint "Started" HSerPrintCRLF 'trackbuttonpresses-requiredtomanageserialdisplayonlyold_state=0doforever'determine the state of the switch current_state = switch_event 'ifthecurrentstateisnotthesameasthesavedstatethenprintcurrentstateifcurrent_state<>old_statethenHSerPrint"Changed State: "HSerPrintcurrent_stateHSerPrintCRLF'save state old_state = current_state else HSerPrint "Stable State: " HSerPrint current_state HSerPrintCRLF end if 'ifthecurrentstateisReleasedthenshowthecount.'count is incremented in the Interrupt routine. if current_state = BUTTON_RELEASED then HSerPrint "Button Press Count: (" HserPrint ButtonPressCount HSerPrint ")" HSerPrintCRLF 'RestoreintteruptOnInterruptPinChange0CallButtonPressedendif'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 'Checkportisdepressed/down?Ifyes,thenincrementcounterifcheck_switch=1thenButtonPressCount++OnInterruptPinChange0Ignoreendifendsub'/****************************************************************************'Function:' input_event(void)'' Summary:'ProcessesthesinglebuttonintothestatesUP,DOWN,PRESSED&RELEASED.''Description:' This function helps write user interface state machines by determining when'thebuttonwaspressed,released''Precondition:' None'' Parameters:'None''Returns:' event_t value of the current button events.'ValidresponsesareBUTTON_UP,BUTTON_DOWN,BUTTON_PRESSED,BUTTON_RELEASED''Remarks:' state_switch inverts the port. If high then use state_switch=off'#defineSwitchIn1PORTD.2' Dir SwitchIn1 In'#definecheck_switchRD2' #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 'buttonisnotpressednownorwasitpressedpreviouslyret=BUTTON_UPENDififbtn&!btn_pvthen' button is pressed now but it wasn'tpreviouslyret=BUTTON_PRESSEDEndififbtn&btn_pvthen' button was pressed previously and is still pressed ret = BUTTON_DOWN end if if !btn & btn_pv then 'buttonisnotpressednowbutitwaspreviouslyret=BUTTON_RELEASEDEndIfbtn_pv=btnswitch_event=retEndFunction'Debouncebutton,DebounceswitchFunctioninput_switch()input_switch=falseIfcheck_switch=state_switchThenButtonCount=0DoWhilecheck_switch=state_switchandButtonCount<4wait5msButtonCount=ButtonCount+1LoopendifIfButtonCount>3theninput_switch=trueButtonCount=0endifEndFunction
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.