Limit switch to trigger differnt programs

I want to use one limit switch to trigger a lot of programs, for example if i hit the button once it will start code bracket one. If i hit it twice it will start code bracket two.

I basically need to know how to store a value from a limit switch or bumper switch like if i push it once it needs to be 1 and so on.

So the programs will be initiated by a set number of pushes on the limit switch.

I would think this is possible, but right now i can only think of having four buttons and having to push certain combinations to achieve the desired program.

Any help would be greatly appreciated!

This can be a little tricky because it involves accumulating date over time. You have to code up something called a “state machine”. You can think of a state machine like a board game (like Chutes and Ladders, or Monopoly). Each place on the board is a state, and you can only be in one of them at a time. For any given state, there are events that can cause you to move into another state (Go directly to Jail, etc).

First, think about the events you are trying to count. You want to count button presses, but you also have to count button releases so you can tell that the next press has started. Also, how are you going to signal that you are done pressing buttons? Probably by waiting some amount of time after the last press.

So, if you wanted to select program 3, then the set of events you need to track are:

[LIST=1]
*]Button Press
*]Button Release
*]Button Press (within 1s of release)
*]Button Release
*]Button Press (within 1s of release)
*]Button Release
*]>1s elapses with no button press
[/LIST]

To do this, you’ll need two variables that carry the state info from loop to loop, and one timer to know when to consider the count finished.

The first variable (switch_state) will tell you what the switch state was last time around so you can tell if it has changed. The 2nd variable (counts) will tell you how many presses you’ve counted. You initialize both to zero.

In your program loop, you read the current value of the switch and compare it to switch_state. If they are the same, then you have to decide if you’ve got a timeout and need to go run the selected program. If they are different, you need to decide if you are going to up the count.

I’ve used this technique to enable or disable autonomous features via the channel 5 & 6 buttons on the back of the remote. It is kind of handy for testing out different algorithms live without having D/L new code.

Best of luck,

  • Dean

Here is a simplified diagram of a state machine to count two button presses:

http://homepage.mac.com/dean.reece/Sites/Vex/SwitchCounter.tiff

That was kind of confusing but i am reading it over and over and it is starting to make sense.

Seems like it would be a complicated program.

I can always make it a combination on the controller that way you would not even have a button on the unit itself. A combination is very simple but i would really like to have a robot that you manually program on the spot with the buttons.

ummm…im so srry to crap all over your theory (watching simpsons :D) but this is sooooo easy :smiley: (not intended to be snobbish)

anyway make a global variable that is increased by one every time you click the limit switch (click as in press then release, if (limit=press) wait(300mS) then if (limit=released)

then when clicked put the variable in a switch statement that calls a function corresponding to the variable value

for each “new program” just make a new function that is called from the switch statement

True - though my suggestion allows the main program loop to continue running while you are counting button presses. This was important for my use, where the robot was off doing something autonomously, and I wanted to enable or disable algorithms without stopping everything else.

This probably isn’t necessary for robofreak’s purposes, so your approach should work fine. In fact, both approaches code the same state machine, but yours plays out in a single pass through the main loop, whereas mine allows the loop to continue cycling.

Cheers,

  • Dean

Actually, it is more complicated to explain than it is to code. The code for it can actually be extremely simple; only slightly more complicated than what bascixman talks about.

  • Dean

i meant also copy the same limit switch check code into your other subroutines

Wow thanks for the help basicxman.

That is a lot easier to understand and it fits my needs.

The robot will just sit and then you will press the switch until you have achieved
the desired program/function.

Its a really simple robot.

Could you guys make a simple program like this and post a screenshot?

That would help a lot.

I finished building my robot a while ago so i is ready to be programmed so any ideas using one switch are welcome.

It has 4 omnis for turning, 2 shaft encoders one for each side, ultrasonic, and a light sensor mounted on a motor so that it can spin around. There is also 2 bumper switches used for programming and a key switch to turn the robot on.

The Article, Event driven Finite State Machine has a good example, which I linked to from Finite state machine.

Also, read through the two articles from Embedded Systems about Embedded multitasking with small MCUs. I bought the book that these two articles were pulled from… I would recommend that all Embedded Programmers should look at a copy…

I already went to that wiki, it was kind of confusing could someone please post a screen shot of this code in easy c v2, that would help a lot because thats what i use most of the time.

I’m afraid I don’t use Easy C, so I can’t help you there. I always program by starting with the Default User Code and inserting my own logic.

I couldn’t find the source code I mentioned earlier in the thread so I wrote up a new example. I have not tested this, but it is very similar to what I used before and should work OK. If I get a chance this evening, I’ll try running it to see if it really works :wink:

Start with the Default User Code, and edit “user_routines.c”. First, you need to declare a few variables:

/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
int            Switch_Debounce = 0;        /* used to clean up switch signal */
unsigned int   Switch_State = OPEN;        /* Debounced Switch State */
unsigned int   Prev_Switch_State = OPEN;   /* Switch state remembered from the previous pass */
unsigned int   Release_Timeout = 0;        /* Counts sixty 17ms cycles to end user input */
unsigned int   Press_Count = 0;            /* Current press count, or 0 if none */
unsigned int   Running_Program = 0;        /* Which program is running, or 0 if none */

Then, you need to make sure and define your switch as an INPUT:

void User_Initialization (void){
  ...
/* Add any other user initialization code here. */
  IO1 = INPUT;   /* Use switch on IO1 to select program to run */
  ...
}

Third, you need to insert the state machine code into the main program loop:

void Process_Data_From_Master_uP(void)
{
  ...
  /* Add your own code here. */
  
  /* First, debounce the switch signal to avoid false counts */
  if (rc_dig_in01 == CLOSED) {
    if (Switch_Debounce++ >= 2) {
      Switch_State = CLOSED;
      Switch_Debounce = 2;
    }
  } else {
    if (Switch_Debounce-- <= -2) {
      Switch_State = OPEN;
      Switch_Debounce = -2;
    }
  }
    
  /* Second, read the switch and run the state machine */
  if (Switch_State == CLOSED) {          /* Switch is pressed, */
    if (Prev_Switch_State == OPEN)       /*    but was not last time. */
      Press_Count++;
  } else {                               /* Switch is not pressed, */
    if (Prev_Switch_State == CLOSED) {   /*   but was pressed last time, */
        Release_Timeout = 60;            /*     so start the 1s timeout. */
    } else if (Release_Timeout) {
      Release_Timeout--;
      if (Release_Timeout == 0) {        /* 1 sec since last release, */
        Running_Program = Press_Count;   /*   so run selected program. */
        Press_Count = 0;
        switch (Running_Program) {
          case 1:  Program1_Init();    break;  /* Init Prog 1 */
          case 2:  Program2_Init();    break;  /* Init Prog 2 */
          case 3:  Program3_Init();    break;  /* Init Prog 3 */
          case 4:  Program4_Init();    break;  /* Init Prog 4 */
          default: Running_Program = 0;        /* Unknown program */
        }
      }
    }
  }
  Prev_Switch_State = Switch_State;   /* Remember switch state. */
  
  /* Finally, call out to whichever program is active */
  switch (Running_Program) {
    case 1:  Program1();    break;    /* Run Program 1 */
    case 2:  Program2();    break;    /* Run Program 2 */
    case 3:  Program3();    break;    /* Run Program 3 */
    case 4:  Program4();    break;    /* Run Program 4 */
    default: Running_Program = 0;     /* Unknown program */
  }
  ...
}

And finally, you need to define functions for Program1_Init(), Program1(), etc. The Program#_Init() functions will be called once when a program is selected, and the Program#() functions will be called every 17ms after that.

You can select a new program at any time by simply pressing the right number of times. It will stop the current program and switch to the new one 1s after the last press.

I know this isn’t Easy C, but I hope you find it helpful nonetheless.

  • Dean

It helped, i get it a little better now. Its time for some experimenting with the programming.

I finished my tricked out squarebot, i just put the wireless camera on it and i am ready to program it.

OK, I tried this out and it worked fine for me. I had four programs that wiggled the first four motor ports, and I could switch between them at will by pressing the right number of times on a button in port1.

I made two simple edits to my source code post above, though:
[LIST=1]
*]Added a declaration for Release_Timeout, which I inadvertently forgot
*]Shrunk the debounce constants from 5 to 2 (and -5 to -2). Five was just too big and could cause presses to be missed altogether.
[/LIST]
Cheers,

  • Dean