Button Debouncing for the Masses!
Kye
Posts: 2,200
I couldn't seem to find any button debouncer drivers up in the Obex.
So...
http://obex.parallax.com/objects/585/
I wrote a pretty nice one that has every feature you would ever need.
It gives the user the ability to:
Get the debounced button state.
Get how long the debounced button has been in that state in milliseconds.
Get if the debounced button was pressed. (Returns true once per press)
Get if the debounced button was released. (Returns true once per release)
The driver runs on a seperate cog and handles eight buttons at a time.
The deounce period is over 10 milliseconds so you shouldn't have any odd button behaviour.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
So...
http://obex.parallax.com/objects/585/
I wrote a pretty nice one that has every feature you would ever need.
It gives the user the ability to:
Get the debounced button state.
Get how long the debounced button has been in that state in milliseconds.
Get if the debounced button was pressed. (Returns true once per press)
Get if the debounced button was released. (Returns true once per release)
The driver runs on a seperate cog and handles eight buttons at a time.
The deounce period is over 10 milliseconds so you shouldn't have any odd button behaviour.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Comments
T o n y
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-MH
Here's my debouncing object:
-- obex.parallax.com/objects/489/
Like yours, it runs in its own cog, but with mine you specify a debounce period (10 to 100ms, defaults to 25). The button(s) state(s) must remain constant for the entire period to be considered valid. It will work with any number of inputs (up to 32) and you can specify active-high or active-low.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
Post Edited (JonnyMac) : 3/9/2010 5:51:37 PM GMT
Wow that's great !
Thanks!!!
When you search for "button" yours does not come up.
I was going to write mine in asm to support all 32 I/Os at once... but doing it in ASM would have been very painful due to all the array acesses I am using in the spin code.
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
If you get a chance to look at my code you'll find it's very simple because I am looking at all inputs at once for a given period (though I actually sample 8x per millisecond to ensure the input is clean). What I probably need to add is a mechanism to read a specific group of [noparse][[/noparse]debounced] pins, similar to result := ina[noparse][[/noparse]msb..lsb].
While a tad off topic... I know you know how to do this, but you may find these subroutines convenient; I have a couple projects that need to use arrays in pasm and I'm putting these to work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
Since I'm supporting more features than just button states it means the ASM will have to be pretty complex to handle everything the spin code was doing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
As for the nop, the instruction pipeline of the Propeller requires an instruction between the movd or movs and the actual mov -- not my rules, it's how the chip works. If you want to do arrays in assembly, which I need at the moment for a lighting controller, this is how it's done. I simply created subroutines that make my life in this particular program a little easier.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
I'll let you in on a little piece of interesting info about all my drivers. Look at the compiled byte image for my drivers. You'll notice an interesting pattern.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
I thought about implementing that type of feature. I know everyone else does it. But I've been designing all my drivers for use on a standard platform where the pinout cannot change and I will only be using one of each.
I have starting including a warning in my drivers about this. I have also included warning about not acessing the driver library with multiple cores at once.
Most, if not all the code on the OBEX i've seen has no default support for multiprocessor acess.
@mpark - I spend alot of time optimizing my drivers. One way to get myself to make the code as clean and as optimized as possible is to set a random hard to reach goal that forces you to look for better ways of doing things to make your code faster.
What I've been doing is forcing all my drivers to have a flat executable byte image that uses every byte allocated for the driver in longs. This execrise has greatly improved my coding skills as well as shrinking my code and making it much faster.
Did you know that 0, and 1, require only one byte to be represented in spin while 2 - 255 require 2 bytes. Numbers greater than that require 3 or four bytes while (-1) requires only one byte again?
There's alot of interesting things you learn about spin by looking at the compiled byte image.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
-Phil
For now, there is at least a disclaimer.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 3/11/2010 6:52:24 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
This is why some people compilers that provide a "de-compiled" listing of the spin code. Not only do you see what it is doing, but you see why it is doing it.
There's a lot of interesting things you can learn about spin by looking at the interpreter source and program list files.
Did you know that the compiler has several ways of encoding constants and will iterate through them looking for the smallest way to do it?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
@JonnyMac - But who's right? I didn't make the pins in my drivers constants for no reason. I'll add more features later on.
...
Almost done with the full featured FAT Engine. Just gotta test the code out the code for a few days and I'll post up the newest version. Hopefully there won't be any problems. Its much more improved than before.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Likely EVERYONE ELSE who is trying to explain that developing your drivers/apps with flexibility would make them significantly more usable/desirable, particularly for those who are trying to learn from the fruits of your efforts. You are producing some nice stuff, but you should heed the advise of the much more experienced people who are so willing to help you improve your offerings. Use your talents wisely!
...
Okay, this post has gone way off topic.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Everyone, of course -- depends on context. That said, I think most professionals would agree that when you create an object for public use (i.e., release to ObEx -- and in your case, amply promoted as available and "easy to use") it can be re-used without having to edit the file. Otherwise, it's not much more convenient than doing a copy-paste-edit of code one needs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
I don't tend to squeeze out every single byte possible out of driver code I write, but some people forget that we program a microcontroller. It's not a PC where you have enough RAM and disc-space so that you don't have to take care of single bytes - even if those single bytes sum up to megabytes for a program in the end.
Beginners should learn that they have to read the drivers comments! And it definitely is not a mistake to teach efficient coding straight from the beginning and not code every driver for the beginners comfort. For example the text LCD driver I added to the object exchange recently does not have a single SPIN-wrapper function which would make things easier. You have to understand how that LCD controller works and you have to do some bit-shifts to pass all the needed parameters in one long.
Last but not least we should keep in mind that coding style is also a matter of taste. One likes it this way, one likes it another way ... One style is better for readability, one style is better for performance, one is better for code size. No matter what code ends up in the object exchange, you can learn from it the one way or the other. In the worst case you learn which way you don't like and you end up re-writing the driver.
That said ... how would it be to have code groups in the object exchange. I think there are now 3 drivers out for HD44780-style text LCDs. Would be nice to have all on one page which describes the differences and gives their ratings.
Post Edited (MagIO2) : 3/11/2010 8:14:59 PM GMT
Okay, JonnyMac, I attached my q-encoder driver with updated support for variable pin assingments.
What do you think?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
G general audience PG13 not for newbies R guidance required X some code may not be appropriate XX uses many raw/bare Propeller tricks XXX hard core programmers only ... NR not rated of course [noparse]:)[/noparse]
MagIO is fully correct on style. Although if someone is paying for your source code, it's best to follow their rules.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Short answers? Not available at this time since I think you deserve more information than you requested.
Today's system depends on some other person feeling excited or qualified to judge.
The number of downloads today seems to be a fair indication of interest at least.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Short answers? Not available at this time since I think you deserve more information than you requested.
-Phil
Nicely done. You have, in fact, done yourself and anyone that uses your object a favor. Let me give you a real-world example. I've designed a couple of Propeller-based products for EFX-TEK but when I turned the initial schematic over to my business partner (another former Parallaxian, John Barrowman), I didn't assign specific pins except for the programming and I2C port. This let John route the boards in the cleanest possible manner. Once the board was routed I simply plugged the final pin #s into my initialization code and away we went.
In your career you will have the opportunity to work with a lot of programmers, many will not be at your level. Even those that are, however, will appreciate that you haven't created work for them to use your drivers in the manner they'd like to.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
I need to add locks to my file system driver. That said, I plan on just using the lock number of whatever processor gets taken by a cognew I need to call to run the ASM block driver.
I'm thinking this method won't have two many problems. But would it be a bad idea to do this?
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
-Phil
The cog number or lock number? Or should I make another function for this? I'm trying to make the fact that I'm using locks transparent.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,