Page 1 of 2

This months Smiley's article

Posted: Fri Jan 02, 2009 8:07 am
by Chupa
Smiley's article in this months is about makeing a Nav menu in C. He joked in the article saying that some users would probably laugh at his method of using a state machine and a ton of switch statements which made me wonder if theirs a better way to do it, even if it is more complex.

Posted: Fri Jan 02, 2009 8:37 am
by psycho
I would use switch statements, too. You would obviously have to use some sort of decision making statements and a switch statement fits best in this case.

That is, unless you are using a language that doesn't support anything like that. I don't think basic does???

He mentioned about break statements. When I start a case statement, I ALWAYS type:

case somecase:

break;

first. Then I fill in the "meat" of the code. That way I will never forget the break statement.

Posted: Fri Jan 02, 2009 1:07 pm
by Chupa
how would one go about writing a menu system without locking the code up.

IE you need to continue to monitor something that cannot cause an INT while also allowing someone to nav though a menu.

Posted: Fri Jan 02, 2009 1:34 pm
by psycho
I am not sure I understand your question...

If you use polling, i.e.:

Code: Select all

void main(void) {
  while(1) {
    processmenu();
    do_your_other_stuff();
  }
}
each time processmenu is called, it will process the current state of the buttons and return (i.e. left, right, up ...). If it has to stall, then you would have to either a) accept that the "other stuff" will not be taken care of or b) use an ISR for either the "other stuff" or the menu itself.

I did not download the code for the article so I can't say how Mr. Smiley <?> did it.

You could use and ISR for a change on the port pins (PIC, I am talking about here) and set the state that way. Then, as long as you know the state has changed, update the menu accordingly.

Posted: Fri Jan 02, 2009 6:28 pm
by Chupa
you know i cant seem to find any place to download what the article is referencing. It says workshop6 but there's only 1-5 on his site and there's no link in the downloads for this issue section on the N&V site.

But i think i understand what your saying. Sometimes i forget that code is executed so fast on a µC that it wont be an issue to do what your saying.

What i mean is it might be possible for someone to press and release the button for only say... 10ms (highly unlikely) at the exact time the code is off doing something else, so the button polling will miss the press. But also that can be avoided by using the ISR, which you also mentioned.

Good times.

jwax, is this not a N&V forum? :razz:

Posted: Fri Jan 02, 2009 6:38 pm
by Chupa
i would have put it in the other section if there hadn't been an article in this months issue.

Posted: Fri Jan 02, 2009 6:46 pm
by psycho
Maybe one of the moderators can move it.

It is quite possible that a "keystroke" could be missed. For instance, you were saving the "configuration" of your device to an I2C EEPROM. Say that configuration is 100 bytes. In this case you would make the user wait (and show a message on the display). If I remember right, the normal write time for a byte is ~5ms. that would mean a half a second at minumum.

But, under normal conditions, you could use polling.

If I were going to do it, I would use interrupt on change and enable the device to wake from sleep on a button press. This way you can put the uC to sleep and not show anything on the display (big power savings). When the user presses a button, the uC wakes up and, if you saved the previous state, you can continue there.

A bit long winded, but....

Posted: Fri Jan 02, 2009 7:44 pm
by Chupa
yea using a pin INT on the nav buttons would make a lot of scene. good information for project im working on. Thanks!

thank god it was moved. it was causing so much trouble being the general section.

Posted: Fri Jan 02, 2009 7:52 pm
by psycho
On the menu system, I ordered some rotory encoders a while back to do a module for user interface control. Never did get around to doing anything with them (yet).

Posted: Sat Jan 03, 2009 8:46 am
by philba
Presuming you are using a microcontroller. If you have a timer available, you can always use the timer interrupt to do the device polling. In general, I try to poll switches/buttons this way rather than use interrupts or main loop polling. There are several reasons for this:
- interrupt pins are often scarce
- bounce causes problems with interrupt driven switches (multiple interrupts per event)
- debouncing is easy with polling, harder with interrupt driven switches

Polling the switches in the main loop of your code is a bad idea in general. Not only do you potentially lose switch events but debouncing wastes time (or is much more complex).

Posted: Sat Jan 03, 2009 2:56 pm
by Chupa
philba wrote:Presuming you are using a microcontroller. If you have a timer available, you can always use the timer interrupt to do the device polling. In general, I try to poll switches/buttons this way rather than use interrupts or main loop polling. There are several reasons for this:
- interrupt pins are often scarce
- bounce causes problems with interrupt driven switches (multiple interrupts per event)
- debouncing is easy with polling, harder with interrupt driven switches

Polling the switches in the main loop of your code is a bad idea in general. Not only do you potentially lose switch events but debouncing wastes time (or is much more complex).
Your saying to poll the button registers every X amount of time using a timer? How often do you suggest doing this?

Posted: Mon Jan 05, 2009 12:44 pm
by philba
I typically use a 5 mS timer. This is so I can debounce the switch. Here's the general idea:

Code: Select all

#define SWMAX = 3
unsigned char sw1;

switch_poll_ISR() {
    if( SWITCH_PIN_1 ) 
        if(sw1 < SWMAX) sw1 += 1;       // increment sw1
    else
        if(sw1 > 0) sw1 -= 1;           // decrement sw1
}

// in main line code
if(sw1 == SWMAX)    // switch is on?
if(sw1 != SWMAX)     // switch is off?

With a 5 mS sample period, you get 15 mS debounce time. Most switches bounce for less than 15 mS so that works pretty well. Depending on your processor, this will take on the order of a few percent CPU overhead. You could reduce the overhead by increasing the period and decreasing the number of samples.

If you have lots of switches, you can save space by packing the SW counters into a single byte (4 per byte) but the increment and test operations are more complex.

Another approach is to use a 2 sample scheme. This is effective for lots of switches. Set your sample frequency to the max debounce latency - say 20 mS. On first sample, read the pin (or a port of pins) and save the results. Next sample, read the pin and compare against the saved sample, if there are both on (or off for pulled high), then the switch is closed. If either is off, then the switch is open. (then save the latest sample) You can use simple logic operations for the test so it is fast.

Posted: Mon Jan 05, 2009 12:47 pm
by philba
I seem to have lost the ability to edit my posts. There's a slight error. its should be
#define SWMAX 3

Posted: Mon Jan 05, 2009 12:49 pm
by Chupa
philba wrote:I typically use a 5 mS timer. This is so I can debounce the switch. Here's the general idea:

Code: Select all

#define SWMAX = 3
unsigned char sw1;

switch_poll_ISR() {
    if( SWITCH_PIN_1 ) 
        if(sw1 <SWMAX> 0) sw1 -= 1;           // decrement sw1
}

// in main line code
if(sw1 == SWMAX)    // switch is on?
if(sw1 != SWMAX)     // switch is off?

With a 5 mS sample period, you get 15 mS debounce time. Most switches bounce for less than 15 mS so that works pretty well. Depending on your processor, this will take on the order of a few percent CPU overhead. You could reduce the overhead by increasing the period and decreasing the number of samples.

Ooo I like that a lot. Im going to start doing that. Thanks a lot!

Posted: Tue Jan 06, 2009 8:58 am
by Michael Kaudze
http://www.nutsvolts.com/index.php?/mag ... ue/2009/01

Click on the Smiley Micros column to get the download file. All downloads can now be found on the issue they were mentioned in.