Sign in

username:

password:



Not a member?

Search lpc2000



Search tips

Subscribe to lpc2000



lpc2000 by Keywords

2106 | ADC | ARM7 | Atmel | Bootloader | CAN | CrossStudio | CrossWorks | DDS | ECos | Ethernet | ETM | FIFO | FLASH | FPGA | GCC | GDB | GNU | GNUARM | GPIO | I2C | IAP | IAR | JTAG | Kickstart | LCD | Linux | LPC | LPC-E2294 | LPC2000 | LPC2100 | LPC2104 | Lpc2106 | Lpc210x | LPC2114 | LPC2119 | LPC2124 | LPC2129 | Lpc2138 | LPC213x | LPC21xx | LPC2210 | LPC2212 | LPC2214 | LPC2292 | LPC2294 | LPC2xxx | LPC3128 | MCB2100 | Olimex | Philips | PWM | Rowley | RTC | RTOS | SPI | SSP | UART | UART0 | UART1 | ULINK | USB | Watchdog | Wiggler

Ads

Discussion Groups

Discussion Groups | LPC2000 | Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236)

Discussion group dedicated to the Philips LPC2000 family of ARM MCUs

Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 12 19:16:30 2008

I was wondering if anyone has used this product, or can offer a few
lines of code to point me in the right direction? I am just learning
ARM7 development, and can get the LEDs blinking, etc. (thanks to this
group), but am not sure how to read the state of the button to know
if it is up, down, or pressed. Do I simply attach outputs 1 and 2
(labelled on breakout board) to GPIO and read something from the
pins, or would they have to go through the ADC (which I tried and get
odd values from)? For reference sake, I am using an Olimex LPC-P2148
connected to the breakout board as follows:

C: 3.3v power
1: connected to P1.24
2: connected to P1.25
T: Ground (Is this right?)

http://www.sparkfun.com/commerce/images/products/NavSwitchBreakout-01-
L.jpg

Sorry if this is a basic question, but there isn't a lot of useful
information on the web for absolute beginners (though the
Hitex 'Insiders Guide' is a gold mine, along with this site).
Unfortunately, the datasheet (link on page below) is no help at all
to me (and barely readable, as well).

http://www.sparkfun.com/commerce/product_info.php?products_id=8236

Kevin
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )


Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 12 19:27:49 2008

Hi Kevin,

the connection should be:

C to GND (Common)
T ist the switchbutton output, 1 and 2 are for the two directions of the=20
navigation handle. Connect 1, 2 and T to 3 input pins on the =B5C. Also con=
nect=20
a resistor (4k7 or bigger) from each of the 1, 2 and T connections to VCC=20
(the supply voltage of the =B5C). These R's are called PullUp and are neede=
d to=20
have the input pins in a defined state when there ist no activity. That is,=
=20
reading 0 when no button/switch is closed, and 1 when it is pushed. You can=
=20
reverse GND and VCC, that is, connect C to VCC and connect the three R's fr=
om=20
GND to 1, 2 and T. In this case it acts as a PullDown and the logic is=20
inverted: 1 for inactive and 0 for active when you read it.

Make sure to debounce the input, either in code or by hardware. Code is=20
simplest. When the state changes on any of the inputs, wait a bit and read=
=20
again. If still in the same, new state accept it. If not, discard it since =
it=20
was bouncing.

Greetings,

Chris

Am Samstag, 13. September 2008 schrieb Kevin Townsend:
> I was wondering if anyone has used this product, or can offer a few
> lines of code to point me in the right direction? I am just learning
> ARM7 development, and can get the LEDs blinking, etc. (thanks to this
> group), but am not sure how to read the state of the button to know
> if it is up, down, or pressed. Do I simply attach outputs 1 and 2
> (labelled on breakout board) to GPIO and read something from the
> pins, or would they have to go through the ADC (which I tried and get
> odd values from)? For reference sake, I am using an Olimex LPC-P2148
> connected to the breakout board as follows:
>
> C: 3.3v power
> 1: connected to P1.24
> 2: connected to P1.25
> T: Ground (Is this right?)
>
> http://www.sparkfun.com/commerce/images/products/NavSwitchBreakout-01-
> L.jpg
>
> Sorry if this is a basic question, but there isn't a lot of useful
> information on the web for absolute beginners (though the
> Hitex 'Insiders Guide' is a gold mine, along with this site).
> Unfortunately, the datasheet (link on page below) is no help at all
> to me (and barely readable, as well).
>
> http://www.sparkfun.com/commerce/product_info.php?products_id=3D8236
>
> Kevin

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 12 19:29:46 2008

Forgot to say: the PullUp/Down resistors are needed only if the board that you
use does not provide them already. So, check the docs for the board and see
if there are PullUp/Down resistors on it already.

Greets,

Chris

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - rtstofer - Sep 12 19:41:38 2008

I'm pretty sure T is a switch that closes when the button is depressed
inward. What you have is just 3 simple switches and it will take 3
GPIO inputs.

I would put 3 ea 10k pull-up resistors on the switch inputs. The "C"
connection goes to ground.

Pick 3 GPIOs, set them to input and you should be good to go. You
could also make the connection to External Interrupt pins so that you
could get an interrupt on each activation.

You might want to put 0.01 ufd ceramic capacitors between the inputs
and ground in an attempt to debounce the switch. Also Google for
'software switch debouncing'.

Richard

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 12 19:45:47 2008

Chris:

Thanks for the quick and helpful reply. I appreciate it a lot.

Kevin
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - "J.C. Wren" - Sep 12 19:49:44 2008

Better yet, just go read this: http://www.ganssle.com/debouncing.pdf
It's everything you need to know.

--jc

On Fri, Sep 12, 2008 at 7:41 PM, rtstofer wrote:

> I'm pretty sure T is a switch that closes when the button is depressed
> inward. What you have is just 3 simple switches and it will take 3
> GPIO inputs.
>
> I would put 3 ea 10k pull-up resistors on the switch inputs. The "C"
> connection goes to ground.
>
> Pick 3 GPIOs, set them to input and you should be good to go. You
> could also make the connection to External Interrupt pins so that you
> could get an interrupt on each activation.
>
> You might want to put 0.01 ufd ceramic capacitors between the inputs
> and ground in an attempt to debounce the switch. Also Google for
> 'software switch debouncing'.
>
> Richard
>
>
>
[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 12 20:44:36 2008

> navigation handle. Connect 1, 2 and T to 3 input pins on the =B5C.=20
Also connect=20
> a resistor (4k7 or bigger) from each of the 1, 2 and T connections=20
to VCC=20
> (the supply voltage of the =B5C). These R's are called PullUp and are=20
needed to=20
> have the input pins in a defined state when there ist no activity.=20

I was able to get everything working (thanks again to everyone), and=20
understood the benefit of adding the resistors, but I didn't quite=20
get where the resistor should be attached. If T on the switch is=20
connected to P1.25 on the board, as below, where would the two ends=20
of the resistor get plugged in?

(SWITCH) =B0 T ---------------- P1.25 =B0 (2148 BOARD)

For reference sake, I'm able to read the pin state with the following=20
code:

#include
#include

int main(void)
{
IODIR1 &=3D 0x03800000; // Set P1.23...25 as inputs
=20=20
while (1)
{
// Check button state
if (!(IOPIN1 & 0x02000000)) // P1.25 Pressed (T on breakout=20
board)
{
debug_printf("Select Button Pressed (P1.25)\n");
}
=20=20=20=20
if (!(IOPIN1 & 0x01000000)) // Down Button (P1.24) Pressed (2 on=20
breakout board)
{
debug_printf("Down Button Pressed (P1.24)\n");
}
=20=20=20=20
if (!(IOPIN1 & 0x00800000)) // P1.23 Pressed (1 on breakout board)
{
debug_printf("Up Button Pressed (P1.23)\n");
}
}
}
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - "J.C. Wren" - Sep 12 20:54:45 2008

Let's see if changing the font actually works :) Otherwise, you may want t=
o
copy'n'paste this into a DOS shell or something with a fixed width font.
3.3
---
|
R
R (10K resistor)
R
|
|-----------O-----------------> To port pin
|
|
O|
|- (switch)
O|
|
|
|
GND

Yay! ASCII art, so old school. Anyways, the 10K resistor pulls the port
pin high to 3.3 volts. When you press the switch, you take the port pin to
ground, but you're not shorting out the 3.3V supply because of the 10K
resistor. You get about 330 microamps of current through the resistor.

--jc

On Fri, Sep 12, 2008 at 8:44 PM, Kevin Townsend wrote:

> > navigation handle. Connect 1, 2 and T to 3 input pins on the =B5C.
> Also connect
> > a resistor (4k7 or bigger) from each of the 1, 2 and T connections
> to VCC
> > (the supply voltage of the =B5C). These R's are called PullUp and are
> needed to
> > have the input pins in a defined state when there ist no activity.
>
> I was able to get everything working (thanks again to everyone), and
> understood the benefit of adding the resistors, but I didn't quite
> get where the resistor should be attached. If T on the switch is
> connected to P1.25 on the board, as below, where would the two ends
> of the resistor get plugged in?
>
> (SWITCH) =B0 T ---------------- P1.25 =B0 (2148 BOARD)
>
> For reference sake, I'm able to read the pin state with the following
> code:
>
> #include
> #include int main(void)
> {
> IODIR1 &=3D 0x03800000; // Set P1.23...25 as inputs
>
> while (1)
> {
> // Check button state
> if (!(IOPIN1 & 0x02000000)) // P1.25 Pressed (T on breakout
> board)
> {
> debug_printf("Select Button Pressed (P1.25)\n");
> }
>
> if (!(IOPIN1 & 0x01000000)) // Down Button (P1.24) Pressed (2 on
> breakout board)
> {
> debug_printf("Down Button Pressed (P1.24)\n");
> }
>
> if (!(IOPIN1 & 0x00800000)) // P1.23 Pressed (1 on breakout board)
> {
> debug_printf("Up Button Pressed (P1.23)\n");
> }
> }
> }
>
>=20=20
>
[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 12 21:14:47 2008

Hi Kevin,

JC explainid it with a small ascii-art drawing already.

Some notes about the code... You might get multiple pressed/release message=
s=20
the way you did it, because you dont account for the debouncing. Mechanical=
=20
switches bounce when toggled. That means that for a short period of time,=20
when the state changes, it rapidly toggles serveral times between open and=
=20
closed, until it settles to the new state.

You might not see it immediatly, since you call the debug_printf function=20
directly after reading the pins, which delays a bit until the cycle in the=
=20
code repeats. But if you act directly on the change, with a very short piec=
e=20
of code, you will get the bouncing effect.

So, in pseudo-code, do something like:

#define KEYMASK 0x03800000

unsigned int keys, newkeys, oldkeys

IODIR1 &=3D KEYMASK;

keys =3D newkeys =3D oldkeys =3D 0;

while(1)
{
newkeys =3D (IOPIN1 & KEYMASK); // read port, mask pins used for keys

if(oldkeys !=3D newkeys) // state changed
{
delay_miliseconds(1); // delay a bit for debounce
keys =3D (IOPIN & KEYMASK); // read port again and mask keys

if(keys =3D=3D newkeys) // if new state is stable
{
process_keys(keys); // process the input
}

oldkeys =3D keys; // set oldkeys to actual state for next detection
}
}

i used two variables to read the new keystate in, keys and newkeys. You mig=
ht=20
get away with only one, and use "if(keys =3D=3D (IOPIN & KEYMASK))" instead=
, but=20
be aware that this _might_ be optimized away by the compiler, thus making t=
he=20
code not work propperly. Normally that should not happen, but you never kno=
w=20
if there is a bug somewhere in the optimization stuff. GCC is known to=20
introduce such nasty things occasionally. In any case, its just pseudo code=
=20
anyways, to show the general flow of things.

Greetings,

Chris

Am Samstag, 13. September 2008 schrieb Kevin Townsend:
> > navigation handle. Connect 1, 2 and T to 3 input pins on the =B5C.
>
> Also connect
>
> > a resistor (4k7 or bigger) from each of the 1, 2 and T connections
>
> to VCC
>
> > (the supply voltage of the =B5C). These R's are called PullUp and are
>
> needed to
>
> > have the input pins in a defined state when there ist no activity.
>
> I was able to get everything working (thanks again to everyone), and
> understood the benefit of adding the resistors, but I didn't quite
> get where the resistor should be attached. If T on the switch is
> connected to P1.25 on the board, as below, where would the two ends
> of the resistor get plugged in?
>
> (SWITCH) =B0 T ---------------- P1.25 =B0 (2148 BOARD)
>
> For reference sake, I'm able to read the pin state with the following
> code:
>
> #include
> #include int main(void)
> {
> IODIR1 &=3D 0x03800000; // Set P1.23...25 as inputs
>
> while (1)
> {
> // Check button state
> if (!(IOPIN1 & 0x02000000)) // P1.25 Pressed (T on breakout
> board)
> {
> debug_printf("Select Button Pressed (P1.25)\n");
> }
>
> if (!(IOPIN1 & 0x01000000)) // Down Button (P1.24) Pressed (2 on
> breakout board)
> {
> debug_printf("Down Button Pressed (P1.24)\n");
> }
>
> if (!(IOPIN1 & 0x00800000)) // P1.23 Pressed (1 on breakout board)
> {
> debug_printf("Up Button Pressed (P1.23)\n");
> }
> }
> }

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 12 22:14:46 2008

Christian/JC:

Thanks again for your help. I've modified the code as follows, and
thought I would post it here just in case someone in the future comes
across this thread via Google, etc. I'm not sure about the delayMS
function, but the basic idea is there anyway, and it seems to work on
my dev board.

I appreciate both of you taking the time to help me out with such
basic problems.

Kevin

#include

// Toggle LEDs depending on state of external 3-way switch (Olimex
LPC-P2148)

#define SELECTKEY 0x02000000 // P1.25 (T on breakout board)
#define UPKEY 0x00800000 // P1.23 (1 on breakout board)
#define DOWNKEY 0x01000000 // P1.24 (2 on breakout board)
#define KEYMASK 0x03800000 // P1.23...25
#define LED1 0x00000400 // LED1 on Olimex LPC-P2148 (P1.10)
#define LED2 0x00000800 // LED2 on Olimex LPC-P2148 (P1.11)
#define LEDMASK 0x00000c00 // P1.10...11

unsigned int keys, newkeys, oldkeys;

void process_keys()
{
if (!(IOPIN1 & SELECTKEY)) // P1.25 pressed (T on breakout board)
{
IOCLR0 = LEDMASK; // Turn both LEDs on
}
else if (!(IOPIN1 & DOWNKEY)) // P1.24 Pressed (2 on breakout board)
{
IOCLR0 = LED1; // Turn LED1 on
IOSET0 = LED2; // Turn LED2 off
}
else if (!(IOPIN1 & UPKEY)) // P1.23 Pressed (1 on breakout
board)
{
IOCLR0 = LED2; // Turn LED2 on
IOSET0 = LED1; // Turn LED1 off
}
else // Nothing Pressed
{
IOSET0 = LEDMASK; // Turn both LEDs off
}
}

void delayMS(unsigned char ms)
{
unsigned long us = 1000*ms;

while (us--)
{
__asm volatile("nop");
}
}

int main(void)
{
IODIR1 &= KEYMASK; // Set P1.23...25 as inputs
IODIR0 |= LEDMASK; // Set P0.10 and P0.11 (LED1/LED2 on Olimex
LPC-P2148) as outputs
IOSET0 = LEDMASK; // Turn both LEDs off

// Set default debouncing values
keys = newkeys = oldkeys = 0;

while (1)
{
newkeys = (IOPIN1 & KEYMASK); // read port, mask pins used for
keys

if (oldkeys != newkeys) // key state changed
{
delayMS(1);
keys = (IOPIN1 & KEYMASK); // read port again and mask keys

if(keys == newkeys) // if new state is stable
{
process_keys(keys); // process the input
}

oldkeys = keys; // set oldkeys to actual state
for next detection
}
}
}

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 12 22:22:00 2008

Hi Kevin,

you should not work on the IOPIN register in the process_keys(), but on the
variable holding the key state. The reason is that the state on the IOPIN can
change anytime. So, in rare conditions, you might lose a keypress. Usually it
shouldnt be a problem, but you never know what the user does. Imagine a very
short keypress. While the main loop correctly detected that, the key may have
been released by the time it gets prcessed. As said, very rare, but possible.
After all, the state is saved in the keys variable already, so use it ;)
Thats also the reason why i save the oldkeys by using the keys variable's
content, instead of doing another read from IOPIN.

Besides that it looks just fine.

Greetings,

Chris

P.S.: Since you have process_keys() as function without arguments, just call
it from the mainloop as process_keys(), instead of process_keys(keys)...

Am Samstag, 13. September 2008 schrieb Kevin Townsend:
> Christian/JC:
>
> Thanks again for your help. I've modified the code as follows, and
> thought I would post it here just in case someone in the future comes
> across this thread via Google, etc. I'm not sure about the delayMS
> function, but the basic idea is there anyway, and it seems to work on
> my dev board.
>
> I appreciate both of you taking the time to help me out with such
> basic problems.
>
> Kevin
>
> #include // Toggle LEDs depending on state of external 3-way switch (Olimex
> LPC-P2148)
>
> #define SELECTKEY 0x02000000 // P1.25 (T on breakout board)
> #define UPKEY 0x00800000 // P1.23 (1 on breakout board)
> #define DOWNKEY 0x01000000 // P1.24 (2 on breakout board)
> #define KEYMASK 0x03800000 // P1.23...25
> #define LED1 0x00000400 // LED1 on Olimex LPC-P2148 (P1.10)
> #define LED2 0x00000800 // LED2 on Olimex LPC-P2148 (P1.11)
> #define LEDMASK 0x00000c00 // P1.10...11
>
> unsigned int keys, newkeys, oldkeys;
>
> void process_keys()
> {
> if (!(IOPIN1 & SELECTKEY)) // P1.25 pressed (T on breakout board)
> {
> IOCLR0 = LEDMASK; // Turn both LEDs on
> }
> else if (!(IOPIN1 & DOWNKEY)) // P1.24 Pressed (2 on breakout board)
> {
> IOCLR0 = LED1; // Turn LED1 on
> IOSET0 = LED2; // Turn LED2 off
> }
> else if (!(IOPIN1 & UPKEY)) // P1.23 Pressed (1 on breakout
> board)
> {
> IOCLR0 = LED2; // Turn LED2 on
> IOSET0 = LED1; // Turn LED1 off
> }
> else // Nothing Pressed
> {
> IOSET0 = LEDMASK; // Turn both LEDs off
> }
> }
>
> void delayMS(unsigned char ms)
> {
> unsigned long us = 1000*ms;
>
> while (us--)
> {
> __asm volatile("nop");
> }
> }
>
> int main(void)
> {
> IODIR1 &= KEYMASK; // Set P1.23...25 as inputs
> IODIR0 |= LEDMASK; // Set P0.10 and P0.11 (LED1/LED2 on Olimex
> LPC-P2148) as outputs
> IOSET0 = LEDMASK; // Turn both LEDs off
>
> // Set default debouncing values
> keys = newkeys = oldkeys = 0;
>
> while (1)
> {
> newkeys = (IOPIN1 & KEYMASK); // read port, mask pins used for
> keys
>
> if (oldkeys != newkeys) // key state changed
> {
> delayMS(1);
> keys = (IOPIN1 & KEYMASK); // read port again and mask keys
>
> if(keys == newkeys) // if new state is stable
> {
> process_keys(keys); // process the input
> }
>
> oldkeys = keys; // set oldkeys to actual state
> for next detection
> }
> }
> }

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 12 22:39:49 2008

> you should not work on the IOPIN register in the process_keys(),
but on the
> variable holding the key state. The reason is that the state on the
IOPIN can
> change anytime.

Christian:

Good point (and something I probably only would have noticed when
something went wrong)!

Just out of curiosity ... do you know if there is a more succint way
to write 'if (keys == (KEYMASK - SELECTKEY))'? Coming from a C#
background, I'm really not use to working with hexadecimal values,
and I suppose there is a better way to write this method, no?

Again, thanks for your help and experience!

void process_keys(unsigned int keys)
{
if (keys == (KEYMASK - SELECTKEY)) // P1.25 pressed (T on
breakout board)
{
IOCLR0 = LEDMASK; // Turn both LEDs on
}
else if (keys == (KEYMASK - DOWNKEY)) // P1.24 Pressed (2 on
breakout board)
{
IOCLR0 = LED1; // Turn LED1 on
IOSET0 = LED2; // Turn LED2 off
}
else if (keys == (KEYMASK - UPKEY)) // P1.23 Pressed (1 on
breakout board)
{
IOCLR0 = LED2; // Turn LED2 on
IOSET0 = LED1; // Turn LED1 off
}
else // Nothing Pressed
{
IOSET0 = LEDMASK; // Turn both LEDs off
}
}

Kevin

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Robert Adsett - Sep 12 23:31:07 2008

At 02:39 AM 9/13/2008 +0000, Kevin Townsend wrote:
>Just out of curiosity ... do you know if there is a more succint way
>to write 'if (keys == (KEYMASK - SELECTKEY))'? Coming from a C#
>background, I'm really not use to working with hexadecimal values,
>and I suppose there is a better way to write this method, no?
>
>Again, thanks for your help and experience!
>
>void process_keys(unsigned int keys)
>{
> if (keys == (KEYMASK - SELECTKEY)) // P1.25 pressed (T on breakout
> board)

I think you want

if (keys & SELECTKEY) != 0

KEYMASK-SELECTKEY will produce something not related to the input key
pressed, unless I'm missing something from what you are attempting to do.

You don't need to mask with KEYMASK again but even if you did it would make
no difference to size and speed of the code unless you went out of your way
(KEYMASK & SELECTKEY would be evaluated at compile time to a single constant).

It can be simplified further if you either forbid multiple simultaneous key
presses or assign a different meaning to them, like a shift state.

Robert

http://www.aeolusdevelopment.com/

From the Divided by a Common Language File (Edited to protect the guilty)
ME - "I'd like to get Price and delivery for connector Part # XXXXX"
Dist./Rep - "$X.XX Lead time 37 days"
ME - "Anything we can do about lead time? 37 days seems a bit high."
Dist./Rep - "that is the lead time given because our stock is live.... we
currently have stock."
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

RE: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Michael Anton - Sep 12 23:35:59 2008



> -----Original Message-----
> From: l...@yahoogroups.com
> [mailto:l...@yahoogroups.com]On Behalf
> Of Kevin Townsend
> Sent: Friday, September 12, 2008 8:40 PM
> To: l...@yahoogroups.com
> Subject: [lpc2000] Re: Surface Mount Navigation Switch (Sparkfun
> COM-08236)
> > you should not work on the IOPIN register in the process_keys(),
> but on the
> > variable holding the key state. The reason is that the state on the
> IOPIN can
> > change anytime.
>
> Christian:
>
> Good point (and something I probably only would have noticed when
> something went wrong)!
>
> Just out of curiosity ... do you know if there is a more succint way
> to write 'if (keys == (KEYMASK - SELECTKEY))'? Coming from a C#
> background, I'm really not use to working with hexadecimal values,
> and I suppose there is a better way to write this method, no?
>

Usually, I would invert the value written to keys, and preapply the mask
to it to prevent having to use reverse logic, or worry about the mask.
So 'newkeys = (IOPIN1 & KEYMASK);' becomes 'newkeys = (~IOPIN1 & KEYMASK);'.
Then I would use something like 'if (keys & SELECTKEY)', or
'if (keys == SELECTKEY)' instead, depending on whether you want to allow
multiple keys pressed at the same time, or not.

Mike
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - rtstofer - Sep 13 1:49:11 2008

You asked somewhere above about the pull-up resistors. They go
between the 3 inputs and Vcc. If the switch is open, the resistors
hold the pin at a logic one level.

On reflection, it is always a good idea to put a 330 ohm resistor in
series with switches during development. So, connect one end of the
330 ohm resistor to the input pin and the other to the switch output
(T,1,2). Connect the pull-up resistor between the switch output and
Vcc, not between the input pin and Vcc.

The resistor limits the current that COULD flow out of the pin if it
were accidentally defined as an output, set to 1 and then pulled to
ground with the switch. Bad things happen when first starting out and
this may save you a uC.

Richard

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 13 4:35:36 2008

Hi Kevin,

as others have noted already, it is not KEYMASK - SELECTKEY. Get used to=20
hexadecimal stuff, you will find it all over the place when working on =B5C=
.

The way to check for a key should be, for example:

if(keys & SELECTKEY) ...

That is, if your switches/logic is wired for 0 at idle and 1 at active (usi=
ng=20
pull-down resistors to GND)

In the case you use pull-up resistors to VCC, having inverted logic (1 at i=
dle=20
and 0 at active), it would be like:

if(!(keys & SELECTKEY)) ...

You can define SELECTKEY, DOWNKEY and UPKEY either with hex values:

#define SELECTKEY 0x02000000
#define UPKEY 0x00800000
#define DOWNKEY 0x01000000

Or you use the bit-numbers and shift a 1 accordingly:

#define SELECTKEY (1<<25)
#define UPKEY (1<<23)
#define DOWNKEY (1<<24)

Greetings,

Chris

Am Samstag, 13. September 2008 schrieb Kevin Townsend:
> > you should not work on the IOPIN register in the process_keys(),
>
> but on the
>
> > variable holding the key state. The reason is that the state on the
>
> IOPIN can
>
> > change anytime.
>
> Christian:
>
> Good point (and something I probably only would have noticed when
> something went wrong)!
>
> Just out of curiosity ... do you know if there is a more succint way
> to write 'if (keys =3D=3D (KEYMASK - SELECTKEY))'? Coming from a C#
> background, I'm really not use to working with hexadecimal values,
> and I suppose there is a better way to write this method, no?
>
> Again, thanks for your help and experience!
>
> void process_keys(unsigned int keys)
> {
> if (keys =3D=3D (KEYMASK - SELECTKEY)) // P1.25 pressed (T on
> breakout board)
> {
> IOCLR0 =3D LEDMASK; // Turn both LEDs on
> }
> else if (keys =3D=3D (KEYMASK - DOWNKEY)) // P1.24 Pressed (2 on
> breakout board)
> {
> IOCLR0 =3D LED1; // Turn LED1 on
> IOSET0 =3D LED2; // Turn LED2 off
> }
> else if (keys =3D=3D (KEYMASK - UPKEY)) // P1.23 Pressed (1 on
> breakout board)
> {
> IOCLR0 =3D LED2; // Turn LED2 on
> IOSET0 =3D LED1; // Turn LED1 off
> }
> else // Nothing Pressed
> {
> IOSET0 =3D LEDMASK; // Turn both LEDs off
> }
> }
>
> Kevin

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Christian Klippel - Sep 13 4:58:34 2008

Hi Richard,

good spot! That is indeed a usefull thing to do during development. Otherwi=
se=20
the magic smoke may escape the =B5C ;)

Greetings,

Chris

Am Samstag, 13. September 2008 schrieb rtstofer:
> You asked somewhere above about the pull-up resistors. They go
> between the 3 inputs and Vcc. If the switch is open, the resistors
> hold the pin at a logic one level.
>
> On reflection, it is always a good idea to put a 330 ohm resistor in
> series with switches during development. So, connect one end of the
> 330 ohm resistor to the input pin and the other to the switch output
> (T,1,2). Connect the pull-up resistor between the switch output and
> Vcc, not between the input pin and Vcc.
>
> The resistor limits the current that COULD flow out of the pin if it
> were accidentally defined as an output, set to 1 and then pulled to
> ground with the switch. Bad things happen when first starting out and
> this may save you a uC.
>
> Richard

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - cfbsoftware1 - Sep 13 8:13:44 2008

--- In l...@yahoogroups.com, Christian Klippel wrote:
>
> In the case you use pull-up resistors to VCC, having inverted
logic (1 at idle
> and 0 at active), it would be like:
>
> if(!(keys & SELECTKEY)) ...
>
> You can define SELECTKEY, DOWNKEY and UPKEY either with hex values:
>
> #define SELECTKEY 0x02000000
> #define UPKEY 0x00800000
> #define DOWNKEY 0x01000000
>
> Or you use the bit-numbers and shift a 1 accordingly:
>
> #define SELECTKEY (1<<25)
> #define UPKEY (1<<23)
> #define DOWNKEY (1<<24)
>

Alternatively, if programming using Oberon rather than C you can
conveniently use SETs and set operations for bit-manipulation
operations:

VAR
keys: SET;

CONST
SELECTKEY = {25};
UPKEY = {23};
DOWNKEY = {24};

Then the direct translation of:

if(!(keys & SELECTKEY)) ...

is:

IF (~(keys * SELECTKEY)) THEN ...

However, the usual Oberon way of expressing this is:

CONST
SELECTKEY = 25;
UPKEY = 23;
DOWNKEY = 24;

IF ~(SELECTKEY IN keys) THEN

--
Chris Burrows
Armaide: Oberon-07 for ARM Development
http://www.armaide.com

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Kevin Townsend - Sep 13 18:25:07 2008


Thanks to all of you for the thoughtful input, particularly the remarks
on improving the code (avoid reading IOPIN1 twice, inverting the value
of keys and newkeys to make the code a bit easier to read, etc.). I
have a lot to learn, but I'm always grateful for other people's
experience.

In any case, this is what I've come up with, trying to integrate all the
remarks made:

#include

// Toggle LEDs depending on state of external 3-way switch (Olimex
LPC-P2148)

#define SELECTKEY 0x02000000 // P1.25 (Connected to T on breakout
board)
#define UPKEY 0x00800000 // P1.23 (Connected to 1 on breakout
board)
#define DOWNKEY 0x01000000 // P1.24 (Connected to 2 on breakout
board)
#define KEYMASK 0x03800000 // P1.23...25
#define LED1 0x00000400 // LED1 on Olimex LPC-P2148 (P1.10)
#define LED2 0x00000800 // LED2 on Olimex LPC-P2148 (P1.11)
#define LEDMASK 0x00000c00 // P1.10...11

void process_keys(unsigned int keys);
void delayMS(unsigned char ms);

unsigned int keys, newkeys, oldkeys;

int main(void)
{
IODIR1 &= KEYMASK; // Set P1.23...25 as inputs
IODIR0 |= LEDMASK; // Set P0.10 and P0.11 (LED1/LED2 on Olimex
LPC-P2148) as outputs
IOSET0 = LEDMASK; // Turn both LEDs off

// Set default debouncing values
keys = newkeys = oldkeys = 0;

while (1)
{
newkeys = (~IOPIN1 & KEYMASK); // read port, mask pins used for
keys
// By inverting IOPIN1 (with the
'~'), we
// end up with a hex value showing
the pin(s)
// that ARE selected, rather than
all the
// pins that are not
//
http://tech.groups.yahoo.com/group/lpc2000/message/35693


if (oldkeys != newkeys) // key state changed
{
delayMS(1); // delay before second test
keys = (~IOPIN1 & KEYMASK); // read port again and mask keys

if(keys == newkeys) // check if new state is stable
(debouncing)
{
process_keys(keys); // process the input
// The keys value is passed to the
method to avoid having
// to read IOPIN1 again, since the
value may change between
// the first and second read
attempts in some situations
//
http://tech.groups.yahoo.com/group/lpc2000/message/35688

}

oldkeys = keys; // set oldkeys to actual state for
next detection
}
}
}

void process_keys(unsigned int keys)
{
switch (keys)
{
case (SELECTKEY): // P1.25 pressed (T on breakout board)
IOCLR0 = LEDMASK; // Turn both LEDs on
break;
case (DOWNKEY): // P1.24 Pressed (2 on breakout board)
IOCLR0 = LED1; // Turn LED1 on
IOSET0 = LED2; // Turn LED2 off
break;
case (UPKEY): // P1.23 Pressed (1 on breakout board)
IOCLR0 = LED2; // Turn LED2 on
IOSET0 = LED1; // Turn LED1 off
break;
default: // Nothing Pressed
IOSET0 = LEDMASK; // Turn both LEDs off
break;
}
}

void delayMS(unsigned char ms)
{
unsigned long us = 1000*ms;

while (us--)
{
__asm volatile("nop");
}
}

[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: Re: Surface Mount Navigation Switch (Sparkfun COM-08236) - Ray Molenkamp - Sep 13 19:09:49 2008

May I suggest using

#define SELECTKEY (1<<25) // P1.25 (Connected to T on breakout
board)
#define UPKEY (1<<23) // P1.23 (Connected to 1 on breakout
board)
#define DOWNKEY (1<<24) // P1.24 (Connected to 2 on breakout
board)

Instead of the hard coded hex values, the compiler will do the math
so the resulting code will be the same.

I know you're eager to use your newly learned hex skills but this
makes code so much easier to read/understand when you look at
it 3 months from now or when change the hardware design and
have to assign different pins to these functions.

But then again it is a personal preference I'm fairly sure someone
on the list will disagree with me and think its the worst idea *EVER*

so consider it, if you don't use it no hard feelings :)

--Ray
Kevin Townsend wrote:
> Thanks to all of you for the thoughtful input, particularly the remarks
> on improving the code (avoid reading IOPIN1 twice, inverting the value
> of keys and newkeys to make the code a bit easier to read, etc.). I
> have a lot to learn, but I'm always grateful for other people's
> experience.
>
> In any case, this is what I've come up with, trying to integrate all the
> remarks made:
>
> #include // Toggle LEDs depending on state of external 3-way switch (Olimex
> LPC-P2148)
>
> #define SELECTKEY 0x02000000 // P1.25 (Connected to T on breakout
> board)
> #define UPKEY 0x00800000 // P1.23 (Connected to 1 on breakout
> board)
> #define DOWNKEY 0x01000000 // P1.24 (Connected to 2 on breakout
> board)
> #define KEYMASK 0x03800000 // P1.23...25
> #define LED1 0x00000400 // LED1 on Olimex LPC-P2148 (P1.10)
> #define LED2 0x00000800 // LED2 on Olimex LPC-P2148 (P1.11)
> #define LEDMASK 0x00000c00 // P1.10...11
>
> void process_keys(unsigned int keys);
> void delayMS(unsigned char ms);
>
> unsigned int keys, newkeys, oldkeys;
>
> int main(void)
> {
> IODIR1 &= KEYMASK; // Set P1.23...25 as inputs
> IODIR0 |= LEDMASK; // Set P0.10 and P0.11 (LED1/LED2 on Olimex
> LPC-P2148) as outputs
> IOSET0 = LEDMASK; // Turn both LEDs off
>
> // Set default debouncing values
> keys = newkeys = oldkeys = 0;
>
> while (1)
> {
> newkeys = (~IOPIN1 & KEYMASK); // read port, mask pins used for
> keys
> // By inverting IOPIN1 (with the
> '~'), we
> // end up with a hex value showing
> the pin(s)
> // that ARE selected, rather than
> all the
> // pins that are not
> //
> http://tech.groups.yahoo.com/group/lpc2000/message/35693
>
> > > if (oldkeys != newkeys) // key state changed
> {
> delayMS(1); // delay before second test
> keys = (~IOPIN1 & KEYMASK); // read port again and mask keys
>
> if(keys == newkeys) // check if new state is stable
> (debouncing)
> {
> process_keys(keys); // process the input
> // The keys value is passed to the
> method to avoid having
> // to read IOPIN1 again, since the
> value may change between
> // the first and second read
> attempts in some situations
> //
> http://tech.groups.yahoo.com/group/lpc2000/message/35688
>
> > >
> }
>
> oldkeys = keys; // set oldkeys to actual state for
> next detection
> }
> }
> }
>
> void process_keys(unsigned int keys)
> {
> switch (keys)
> {
> case (SELECTKEY): // P1.25 pressed (T on breakout board)
> IOCLR0 = LEDMASK; // Turn both LEDs on
> break;
> case (DOWNKEY): // P1.24 Pressed (2 on breakout board)
> IOCLR0 = LED1; // Turn LED1 on
> IOSET0 = LED2; // Turn LED2 off
> break;
> case (UPKEY): // P1.23 Pressed (1 on breakout board)
> IOCLR0 = LED2; // Turn LED2 on
> IOSET0 = LED1; // Turn LED1 off
> break;
> default: // Nothing Pressed
> IOSET0 = LEDMASK; // Turn both LEDs off
> break;
> }
> }
>
> void delayMS(unsigned char ms)
> {
> unsigned long us = 1000*ms;
>
> while (us--)
> {
> __asm volatile("nop");
> }
> }
>
> [Non-text portions of this message have been removed]
>
>

------------------------------------



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )