Homemade Claw Machine Pt. 2
One thing i noticed when connecting the arcade controls, the ground is common but each 5v line coming to the board....but to make the inputs go high,wwhen the button is pressed how do i pull the voltage up on those lines? I couldnt figure it out, so i rewired it so that the pins on the shift register are pulled high, and then when the button is pressed they are pulled low. this made sense, i figured i must be missinng something...
Well I got the arcade stick , button and coin mech connected to the board. So now its time to look at the code, Right now its a bit sluggish to respond to controls. The reason is i am using a simple event loop to handle input. Basically the code looks like this:
LOOP {
FOR ( i = 1 TO 7 ) {
// i is the number of each input line
input_status = READ INPUT i
if ( i = 0 ) {
HANDLE THE EVENT FOR WHAT EVER BUTTON IS PRESSED
}
}
}
hope this makes sense to any non-programmer reading this. The problems with this approach should
be immediately obvious, though.
1) button events are handled in the order they are connected to the board, not in the order of importance
2) if an event handler takes a long time, any inputs that happen while in the event handler routine
get missed
3) any inputs that happen on a pin while checking a another pin get missed. For example lets say we check pin 0 and its high ( inputs on the shift register are pulled up to +5v and brought low when the inputs are in use), so we move on to the next pin, but then pin 0 changes to low, we have to wait until we've checked all the rest of the pins and hope that the button connected to pin 0 is still being pressed when we get back to it.
All of this causes problems mainly causing the program to be slow to respond to input or possibly miss inputs. for something like a coin drop, that could be really bad.
So as an experienced programmer I know the best way to handle this would be to use "interrupts". An interrupt is a function of a microprocessor that interrupts program flow in response to some kind of event. It causes control to be passed to another part of the code which is designated as the "interrupt handler" once this completes the program goes back to where it was before the interrupt was "raised".
The arudino controller has only two interrupt pins, both of which im using for the shift register. furthermore the shift register has no ability to raise an interrupt when the pin status changes. now im starting to understand why they are used for dip switches and not user input, very inefficient.
so someone points me to the MCP23017 which is an I/O expansion IC that works sort of similar to the shift register but is more complex and can raise an interrupt when one of the inputs change.
I havent got one yet, so i continue on with the code for when it arrives. Now the problem with interrupts is bounce, when a switch is thrown it wont go exactly from high to low, it will "bounce" a bit
first, vacillating back from low to high a few times before settling. in the loop (polling) model shown above this doesnt matter, we just make a small delay before reading the input to wait for it to settle down. in an interrupt handler the problem is each one of these will
raise the interrupt, thats no good, 1 coin bounce could cause a bunch of credits on the machine. You dont want to put in a delay because interrupt handlers need to be executed as fast as possible to prevent them from blocking other parts of the code or even blocking other interrupts from firing.
So to fix that you add a capacitor across the switch (which the folks at united textiles have thoughtfully already done for me). Doing a little digging on that problem I came across a tutorial that discussed an inverter chip called a inverting schmitt trigger that will take whatever logical value passed in and invert it. so if you have a high value being pulled low, the schmitt trigger will return 0->1 instead of 1->0
ah ha! that explains why the controls are wired that way, because its how to fix the "bounce " problem
using the microcontroller interrupt. OK things are starting to make sense
Well I got the arcade stick , button and coin mech connected to the board. So now its time to look at the code, Right now its a bit sluggish to respond to controls. The reason is i am using a simple event loop to handle input. Basically the code looks like this:
LOOP {
FOR ( i = 1 TO 7 ) {
// i is the number of each input line
input_status = READ INPUT i
if ( i = 0 ) {
HANDLE THE EVENT FOR WHAT EVER BUTTON IS PRESSED
}
}
}
hope this makes sense to any non-programmer reading this. The problems with this approach should
be immediately obvious, though.
1) button events are handled in the order they are connected to the board, not in the order of importance
2) if an event handler takes a long time, any inputs that happen while in the event handler routine
get missed
3) any inputs that happen on a pin while checking a another pin get missed. For example lets say we check pin 0 and its high ( inputs on the shift register are pulled up to +5v and brought low when the inputs are in use), so we move on to the next pin, but then pin 0 changes to low, we have to wait until we've checked all the rest of the pins and hope that the button connected to pin 0 is still being pressed when we get back to it.
All of this causes problems mainly causing the program to be slow to respond to input or possibly miss inputs. for something like a coin drop, that could be really bad.
So as an experienced programmer I know the best way to handle this would be to use "interrupts". An interrupt is a function of a microprocessor that interrupts program flow in response to some kind of event. It causes control to be passed to another part of the code which is designated as the "interrupt handler" once this completes the program goes back to where it was before the interrupt was "raised".
The arudino controller has only two interrupt pins, both of which im using for the shift register. furthermore the shift register has no ability to raise an interrupt when the pin status changes. now im starting to understand why they are used for dip switches and not user input, very inefficient.
so someone points me to the MCP23017 which is an I/O expansion IC that works sort of similar to the shift register but is more complex and can raise an interrupt when one of the inputs change.
I havent got one yet, so i continue on with the code for when it arrives. Now the problem with interrupts is bounce, when a switch is thrown it wont go exactly from high to low, it will "bounce" a bit
first, vacillating back from low to high a few times before settling. in the loop (polling) model shown above this doesnt matter, we just make a small delay before reading the input to wait for it to settle down. in an interrupt handler the problem is each one of these will
raise the interrupt, thats no good, 1 coin bounce could cause a bunch of credits on the machine. You dont want to put in a delay because interrupt handlers need to be executed as fast as possible to prevent them from blocking other parts of the code or even blocking other interrupts from firing.
So to fix that you add a capacitor across the switch (which the folks at united textiles have thoughtfully already done for me). Doing a little digging on that problem I came across a tutorial that discussed an inverter chip called a inverting schmitt trigger that will take whatever logical value passed in and invert it. so if you have a high value being pulled low, the schmitt trigger will return 0->1 instead of 1->0
ah ha! that explains why the controls are wired that way, because its how to fix the "bounce " problem
using the microcontroller interrupt. OK things are starting to make sense
6 Comments
Recommended Comments
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now