Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Case statement

Status
Not open for further replies.

Mosaic

Well-Known Member
Hi,
I'd like to evaluate a voltage ladder sampled by an adc to determine a tactile switch press.
Here's what i have:

Code:
Select Case tactile  'assign a swich based on the voltage detected.
		Case > 140, < 150 ' need to evaluate an adc range of 140 to 150. 
		swstate.0 = 1  'sw 0 closed
		Case > 130, < 140
		swstate.1 = 1  'sw 1 closed
		Case > 120, < 130
		swstate.2 = 1  'sw 2 closed
		Case > 105, < 115
		swstate.3 = 1  'sw 3 closed
		Case Else
	EndSelect


It's not evaluating the ranges properly. In the 1st case, only if the >140 fails does it evaluate the < 150. It's using the parameters as an 'OR" I need an 'AND'.

How can I do this?
 
If you are using an ADC to evaluate switch presses.... You don't need to worry about two simultaneous presses

I would do it like this
Code:
swstate = 0
Select Case tactile  'assign a swich based on the voltage detected.
		Case > 140   ' need to evaluate an adc range of 115 to 150. 
		swstate = 1  'sw 0 closed
		Case > 130, ' no its smaller
		swstate = 2  'sw 1 closed
		Case > 120   'no its still smaller
		swstate = 4  'sw 2 closed
		Case > 115  ' ok now we are done
		swstate  = 8  'sw 3 closed
		Case Else
	EndSelect

Cheers for that Eric... I've tested it now
 
Last edited:
That ADC value better go through a good debounce routine first!! It's probably going to need a longer delay time to compensate for multiple possible key changes at the same time. With an on/off debounce the only mistake is a misread on on/off, with multiple possible values like this if you catch a bounce transient you could get an entirely wrong set of multiple keys received than was actually hit.
 
Basic 8 sw parallel debopunce (short & long press) Start & end debouncing.

That ADC value better go through a good debounce routine first!! It's probably going to need a longer delay time to compensate for multiple possible key changes at the same time. With an on/off debounce the only mistake is a misread on on/off, with multiple possible values like this if you catch a bounce transient you could get an entirely wrong set of multiple keys received than was actually hit.

Now that u mention it:

Code:
Proc keydetect()  '16ms or greater is considered debounce time. a person can click and release in about 32 ms. This routine must iterate at least once per 16mS!
'8 channels (bits) @ 1 switch per bit simultaneously processed. Debounced Short press (16 to 512mS) and Long press (>512mS sec)detection
'Both press and release actions are debounced.
'requires a 8mS counter 'dbouncecount', preferably interrupt driven.
'dbkeystate' = closed debounced switches. 'holdkeystate' = closed 'long press' switches. 'keytrans' and 'holdtrans' track the respective switch transitions (both press & release)
'keytrans' and 'holdtrans' (reset every iteration) are useful when ensuring that a single key press is not repetitively detected as a fresh press during its duration (of multiple detection iterations).
Dim temp As Byte
swstate = 0
keytrans = 0
holdtrans = 0  'reset states
Call mapswitches()  'assign switches to swstate bits.
temp = swstate Xor lastkeystate  'check for any changes in sw states.
lastkeystate = swstate  'make old state  = new
If temp <> 0 Then dbouncecount = 0  'reset counter if no switch detected, else permit dbounce count.
If dbouncecount.1 Then  '@ an increment of 1 per 8mS, debounce.1 tests 16ms or greater.
keytrans = lastkeystate Xor dbkeystate  'keytrans bits monitors the switches that have changed state 'short press'  after debounce.
dbkeystate = keytrans Xor dbkeystate  'update debounced byte with current switch (now debounced) states
Endif
'evaluate dbouncestate to determine which keys have been released
temp = dbkeystate And holdkeystate
holdtrans = temp Xor holdkeystate  'update long press (hold) transition byte.
keytrans = holdtrans Xor keytrans  'clear matching 'short press'  debounced transitions, a 'long press' key is different to a 'short press' key
holdkeystate = holdtrans Xor holdkeystate  'toggle long press' keystate to on or off based on its old state & new transition.
temp = dbkeystate Xor holdtrans
If temp = 0 Then Goto done
If dbouncecount.6 = 0 Then Goto done  '512msec not elapsed
temp = dbkeystate Xor holdkeystate  'state changes
holdtrans = temp Or holdtrans  'longpress transitions
holdkeystate = temp Xor holdkeystate  'apply changes.
done:
End Proc                                          
Proc mapswitches()  'assign  swstate bits to matching switch inputs. Organises switches  scattered among input port pins or in an analog volt ladder.
	TRISB.3 = 1
	ANSELH.1 = 1
	Adcin 9, tactile  'sample switch resistance ladder V.
	tactile = 145 - tactile
	Select Case tactile  'assign a swich based on the voltage detected.
		Case < 5
		swstate.0 = 1  'sw 0 closed
		Case < 10
		swstate.1 = 1  'sw 1 closed
		Case < 15
		swstate.2 = 1  'sw 2 closed
		Case < 20
		swstate.3 = 1  'sw 3 closed
		Case Else
	EndSelect
	
	TRISB.3 = 0
	ANSELH.1 = 0
	
End Proc
 
you can otherwise mention a range of value like this...

Code:
while(kp==15)
{
 volt2 = ADC_Read(2);   // Get 10-bit results of AD conversion
 
if(volt2>657&& volt2 < 667)
{
kp =1;
}

if(volt2>580 && volt2 < 590)
{
kp =2;
}
if(volt2>459 && volt2 < 469)
{
kp=3;
}
if(volt2>643 && volt2 < 653)
{

kp=4;
}
if(volt2>558 && volt2 < 568)
{

kp=5;
}
if(volt2>424 && volt2 < 434)
{

kp=6;
}
if(volt2>627 && volt2 < 637)
{

kp=7;
}
if(volt2>534 && volt2 < 544)
{

kp=8;
}
if(volt2>383 && volt2 <392 )
{

kp=9;
}
if(volt2>507 && volt2 < 517)
{

kp=10;
}
if(volt2>609 && volt2 < 615)
{

kp=11;
}
if(volt2>336 && volt2 < 345)
{
kp=12;
}
}

}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top