Using a BCD Switch to "tune" up and down

vshortt

Senior Member
Hi all, I did a quick search and didn't find anything so I thought I'd post.

I'd like to use a 16 position BCD swith to "tune" a radio I'm working on. simply put, at the switch is turned clockwise, the radio tunes UP in frequency, as the switch is turned counter clockwise, it tunes DOWN.

Is there a simple snipped of code out there that would make this task easy?

Thanks

Victor
 

graynomad

Senior Member
You can just read the values from the switch and use some logic to decide which direction the switch was turned (I assume it rolls over from F to 0 which has to be handled as well).

I don't have any code but something like

if new_val < old_val direction = down
if new_val > old_val direction = up
if new_val = 0 AND old_val = F direction = down
if new_val = F AND old_val = 0 direction = up

I'm sure with some thought this could be made more elegant but that's the general idea.
 

vshortt

Senior Member
You can just read the values from the switch and use some logic to decide which direction the switch was turned (I assume it rolls over from F to 0 which has to be handled as well).

I don't have any code but something like

if new_val < old_val direction = down
if new_val > old_val direction = up
if new_val = 0 AND old_val = F direction = down
if new_val = F AND old_val = 0 direction = up

I'm sure with some thought this could be made more elegant but that's the general idea.
Yes, that works well. Base on the "up" or "down" motion of the switch, I'm adding or subtracting from another number (b3)

However, I have so much contact bounce in this BCD switch, It's almost impossible to get the number to go up or down.

for example:

when you turn the switch "up" the number will go from 100 to 101 then back to 100... or from 100 to 101 to 100 to 99 to 100... it "shutters" because of the contact bounce.

Is ther a way to filter for this?
 

Chavaquiah

Senior Member
graynomad's method is the most straightforward, except you should check the extreme (0-F and F-0) conditions first.

But, in case the Picaxe does not pick every intermediate step, you could just check the general direction. This would assume that, for instance, a change from 1 to 4 would be "up" and from 1 to 10 would be "down".

Code:
dif = newval - oldval // 16
if dif > 8 then
   'down
else
   'up, up and away
endif
 

hippy

Ex-Staff (retired)
Checking for 'significant difference to last' may not work well for a switch if a change of just one is desired and may often happen. What one can do is, pause, check switch, if reading is not the same as last, pause and check again, and repeat until you get two or more consecutive readings the same.
 

vshortt

Senior Member
Checking for 'significant difference to last' may not work well for a switch if a change of just one is desired and may often happen. What one can do is, pause, check switch, if reading is not the same as last, pause and check again, and repeat until you get two or more consecutive readings the same.
I'm still getting all sorts of "bad" data as described above. Hippy, I put your idea to use, and it helped. I think it's a limitation of the switch I'm using. Time to order a better switch I think.
 

BeanieBots

Moderator
I've had some very ropey push buttons which have sliding contacts that give really long and persistant 'bounce'
Try adding a 1k and 100nF filter between contact and PICAXE input as well as the code delay that Hippy has described.
 

boriz

Senior Member
“16 position BCD swith”

If it were BCD it would be 10 position?

I’d use a rotary quadrature encoder (code here: http://www.picaxeforum.co.uk/showthread.php?t=15803), otherwise..

If you have really bad bounce, try this. Put a 100nF capacitor-to-ground on each of the four picaxe input pins. Connect the four pins on the switch through 1K resistors to the Picaxe pins. Forming a low pass filter on each input.

With this setup it should take approximately 100uS for the pin to read a change after the switch has settled. Change the resistor value to suit. Higher for greater bounce rejection (but slower response time), lower for less debounce (but faster response).
 

Dippy

Moderator
I was wondering that too...
And BCD and 16 pos didn't sound right either.
Maybe Vshort could clarify please.

I would have thought that a rotary switch (as in genuine clickety-click switch) was a bad way to go for a volume control that could be twiddled regularly and vigorously. Was that the only thing you had in the drawer?

With the switch I'd have used an interrupt-timer to check for changes in value, then process direction and magnitude.
That's what I did with a rotary switch PIC interface and it worked really well.
 

vshortt

Senior Member
I was wondering that too...
And BCD and 16 pos didn't sound right either.
Maybe Vshort could clarify please.

I would have thought that a rotary switch (as in genuine clickety-click switch) was a bad way to go for a volume control that could be twiddled regularly and vigorously. Was that the only thing you had in the drawer?

With the switch I'd have used an interrupt-timer to check for changes in value, then process direction and magnitude.
That's what I did with a rotary switch PIC interface and it worked really well.
Okay, Sorry for the Hiatus. I've been a little under the weather.

Yes, this is a true BCD Switch. NKK Part number FR01-AC16 (Datasheet here) You can see the BCD Truth table on G7. Perhaps calling it a "16 position" switch isn't the right term. I say that because the switch has 16 different "clicks" on it and it's capable of generating 0 - F in Binary. Does that clarify?

This isn't going to be used as a volume switch, rather it' being used as a tuning knob for an aviation band radio receiver. Each "click" tunes up .05mhz between the 108 and 118mhz band.

I have it working smoothly now. Here's how:

Common on the BCD goes to ground. Each of the 4 "byte" pins goes to a pin on the picaxe. That same pin is the driven high through a 10K resistor. - problem solved.

Before, I was running 5v to the switch "common", wiring up each "byte" pin to the picaxe and having all sorts of problems as described above. Reverse the circuit and it works perfectly. I don't fully understand why though. Would someone like to help me understand this?

Here's a rudimentary schematic

 
Last edited:

boriz

Senior Member
Switches like that are absolute mechanical position encoders. They are usually used in gangs and read by the logic only after you have dialled-in your absolute number. Probably why you’re getting all that contact bounce. Your application is different and only needs to determine the direction of the click, which the MCU reads on the fly.

Your using a HEX switch (It’s not BCD*) to do the job of an easier to use, more reliable, cheaper, rotary encoder. Perhaps you just happen to have some HEX switches lying around? You’re certainly making this harder than it needs to be. But hey, I’m always up for a bit of recycling.

If you stick with the HEX switch, then you really only need to read the state of the first two bits. That will give you the simple direction information you need: 00-01-10-11 etc. And save you four components + some wiring.

*BCD stands for Binary Coded Decimal. Digits 0-9.
 

lanternfish

Senior Member
It would seem that had you used pull-down resistors on your first circuit it would have worked. Pull-up/-down resitors are inportant on inputs where an indeterminate state might occur e.g 0V or no voltage; PICAXES prefer 0V or 5V on the inputs.
 
Top