Log in

View Full Version : limit switches


stephenthe1
20-04-2005, 10:33
Hi,
We've been having a little trouble using limit switches. We get the value registered when the limit switch is pressed, but when it is released, the value doesn't change back. I figured the first thing to check would be the wiring. I haven't seen much on chiefdelphi after searching on limit switches, so if you could provide a wiring diagram, that would be helpful. Then secondly, maybe sample code for referencing the limit switch. ThankS!
-Stephen P.

Mike Betts
20-04-2005, 12:41
As per page 9 of the "Full Size RC Reference Guide", switches are connected between SIG and GND on the digital input.

stephenthe1
26-04-2005, 10:11
we're having a big problem with our limit switches. Basically, once it is pressed, the value of it changes it to 1, which is good, but once it is released, it doesn't change back to 0. hilf mir! danke schon

billbo911
26-04-2005, 10:34
Hi,
We've been having a little trouble using limit switches. We get the value registered when the limit switch is pressed, but when it is released, the value doesn't change back. I figured the first thing to check would be the wiring. I haven't seen much on chiefdelphi after searching on limit switches, so if you could provide a wiring diagram, that would be helpful. Then secondly, maybe sample code for referencing the limit switch. ThankS!
-Stephen P.

A couple of questions, or answers to them, might help:
1) How are the switches connected? For example: Are they connected to the RC Digital input 1, 2, 3 etc.
2) How are you "registering them"? Do you have your own code, or are you using the interrupts associated with the digital inputs?
3) When it sticks, how do you unstick it? Manually or by reseting the controllers?

If you are using the digital inputs, my guess is that the switches are sticking, either by binding of the mechanism, or internally to the micro switch it's self. If you are using your own code to set a flag, the code may not be written to reset the flag once the switch state changes.

Good Luck, and let us know what you find.

Ryan M.
26-04-2005, 15:53
If you are using the digital inputs, my guess is that the switches are sticking, either by binding of the mechanism, or internally to the micro switch it's self. If you are using your own code to set a flag, the code may not be written to reset the flag once the switch state changes.I bet he's right. Try hooking a multimeter up to the switch and see how the resistance changes when you press and release the switch. If it's working properly, you should see a high (infinite, depending on the meter) resistance when released, followed by a fairly low resistance when you press it, and back to what it was before when you release it again.

If you find that it stays low after you release the switch, then you know it's the switches fault. Get a new one... :)

stephenthe1
26-04-2005, 17:29
I think the switch is ok. The problem is, once pressed, the value I use to reference it in the code (rc_dig_in08 == 0) when it is released, does not recognize that it is released. It recognizes in the code when it changes to one, though (rc_dig_in08 == 1) when it is pressed, but upon release, it doesn't change back to zero. Would this be code, I don't think so anyways, but I have my doubts as to whether it is hardware, because my code is such that the motor should only turn if the rc_dig_in08 == 0, and once the switch is released, and I press the button to turn the motor, it acts as if the rc_dig_in08 did indeed return back to 0, it's normal state. This really perplexes me. If you want to see my code, just respond and ask and I'll show you, it's very simple. My Mentor thinks it's possible we have a limit switch, that remembers its state, and upon release of the switch, it stays that way instead of returning back to it's 0 state. I hope this made sense, if not (I'm slightly confused myself!), I'll post the code, and will try to provide wiring details on our limit switch on Thursday. Thank you for you help!

Alan Anderson
26-04-2005, 17:46
...the value I use to reference it in the code (rc_dig_in08 == 0) when it is released, does not recognize that it is released. It recognizes in the code when it changes to one, though (rc_dig_in08 == 1) when it is pressed, but upon release, it doesn't change back to zero...
If you have the switch wired properly, between SIG and GND, the digital input will read 1 when the switch is open, and 0 when the switch is closed.

Please post the part of the code that isn't doing what you expect it to do.

Mike
26-04-2005, 18:34
Try adding a printf to your code, see what it puts out.

printf("Limit Switch: %f \n", rc_dig_in08);

Alan Anderson
27-04-2005, 00:29
printf("Limit Switch: %f \n", rc_dig_in08);
I thought the printf() we have didn't support the %f format. Even so, you want %d anyway.

David Brinza
27-04-2005, 01:42
we're having a big problem with our limit switches. Basically, once it is pressed, the value of it changes it to 1, which is good, but once it is released, it doesn't change back to 0. hilf mir! danke schon

Make sure you're using a "momentary contact" switch rather than a latching or locking switch. The momentary contact switch will only remain closed/open while the switch is depressed, whereas a latching/locking switch toggles between open and closed each time the switch is depressed.

Greg Ross
27-04-2005, 12:28
If I were a betting man, I would put money on it being a software problem.

First check the switch -- only because it's often easier to check hardware than to find a code problem. If it tests OK, then it is more than likely a software problem. (It could still be the controller, but unless you had a fairly major oopsie with it, I doubt it.)

After you've tested the switch, post the code, and we'll help you find the problem.

Workaphobia
27-04-2005, 17:37
This is definitely a simple matter of testing for the wrong value in code. Digital inputs on the RC (but not on the OI) have "pull ups", which means they are set to register as 1 in software when not grounded. Your input will be in the 0 state when the switch is pressed. This isn't a problem at all, just invert where you have tests for 1s and 0s.

stephenthe1
27-04-2005, 17:51
actually, limit switches are the opposite of that. They are normally 0, or true, then once pressed, turn to 1. I'm trying to find the code I used, but I think it's on my flash drive some where where I can't fine it. I'll post tomorrow with results and code. Thanks for all the help!!!

or wait, do you mean that they've actually 'simplified' it for us, by reversing the values in the code we work with, so I should use == 1 to test for being pressed? that would make a lot of sense, because I thought the joysticks were supposed to be == 0 when pressed, but it only worked when I did == 1. thanks for the information. Why don't they tell people these small, but important things. Thanks!

Workaphobia
28-04-2005, 02:04
Er, unless I'm severely mistaken, it's ==0 for when a digital input is grounded, ==1 for when it's not grounded, ==0 for an unpressed joystick button, and ==1 for a pressed joystick button. Unless your switch grounds when inactive and removes the contact when it's activated, you do test for ==0 (or !rc_dig_in01) to tell when the switch is active. Page 14 of the 2004 Programming Reference Guide (http://www.ifirobotics.com/docs/legacy/2004-programming-reference-guide-12-apr-2004.pdf) describes it.

Actually, it appears that the guide makes no exception for the OI inputs, so perhaps it's possible that the joysticks that we typically use *are* of the second kind of switch, that breaks a ground connection instead of establishing one.

The 2005 OI Guide (http://www.ifirobotics.com/docs/oi-ref-guide-2-21-05.pdf) mentions on page 5 that an OI digital input senses a ground connection to "become active".

Ok, so I'm beginning to doubt some of what I've said, but I'm still fairly certain that the RC switch is logically true in code when ungrounded.

Ryan M.
28-04-2005, 07:12
If you have the switch wired properly, between SIG and GND, the digital input will read 1 when the switch is open, and 0 when the switch is closed.Your input will be in the 0 state when the switch is pressed. This isn't a problem at all, just invert where you have tests for 1s and 0s.actually, limit switches are the opposite of that. They are normally 0, or true, then once pressed, turn to 1.Er, unless I'm severely mistaken, it's ==0 for when a digital input is grounded, ==1 for when it's not grounded, ==0 for an unpressed joystick button, and ==1 for a pressed joystick button.
:ahh:

I can never remember/am never sure which it is, so I setup #defines at the beginning of a include file I put all that general setting stuff in, then use that in my tests. IE:
#define SWITCH_ON 1 /* Value switches give when on. */
#define SWITCH_OFF !SWITCH_ON

if(rc_switch_01 == SWITCH_ON)
{
// ...
}That way, if I'm wrong, I have to change one value and my entire program changes to reflect it. Plus, it makes your logic (to some people) clearer.

Alan Anderson
28-04-2005, 12:26
actually, limit switches are the opposite of that. They are normally 0, or true, then once pressed, turn to 1...
Using the word "pressed" when talking about how the RC digital inputs work is probably a bad idea. Some switches are normally open and close the contacts when activated, while others are normally closed and open the contacts when activated. Some are built with both options at the same time, and you can choose which contacts to use when you connect the wires. They give different results when "pressed", and can be a source of great confusion for people trying to understand how to program for the digital inputs.

The RC digital inputs have a pullup resistor to +5 volts. Reading them will return a 1 when the switch is open, and a 0 when the switch is closed to ground.

eugenebrooks
28-04-2005, 12:44
Try adding a printf to your code, see what it puts out.

printf("Limit Switch: %f \n", rc_dig_in08);

printf("Limit Switch: %d \n", (int)rc_dig_in08);

Both the %d and (for our RC compiler) the cast to int are important...

Mike
28-04-2005, 19:04
Heh, yeah sorry about that. It is %d not %f. It's little (seemingly) trivial things like that that always get me.

eugene: I've never used (int) before, and my printf's work fine.

CyberWolf_22
29-04-2005, 01:06
I am not sure if the question has been answered or not but I can't really diagnose the problem with out the code but what my first idea would be is that there is not an else statement following his if statement to turn the motor off when the switch is not pressed.

if (button8 == 1)
{pwm01 = 254;}
else
{pwm01 = 127;}


Wait, after rereading some of the posts maybe this is not the problem.
Please post your code so we can further diagnose it.

stephenthe1
05-05-2005, 11:45
thanks for all your help. I've got it working now. the problem was just in how I was accessing the limit switch in the code. there was a variable that wasn't being reset when the switch changed its state. thanks for all your help. Originally, this wasn't the only problem, we had problems wth our buttons that kept messing me up too. but now that's all solved. thanks for the help!!!
the code you posted worked fine. thanks again.

Gamer930
10-05-2005, 13:10
I searched and couldn't find and couldn't think through the code for:

I have a motor and 2 Limit Switches that sets the upper and lower limits of an arm from our 2003 Robot.

I want to have it so when I hit a Trigger on the joystick it sends the motor forward until it hits the Top limit switch or if it is already at the top to reverse the motor until it hits the Bottom Limit Switch.

I have:
#define T_DRIVE pwm01
#define Up_T_Limit rc_dig_in01 /* Limit Switch on Full Up Set */
#define Down_T_Limit rc_dig_in02 /* Limit Switch on Full Down Set */
#define T_BUTTON_BTN p2_sw_trig /* Button to change T state. */
/* T state variable. */
int intTState = 0;

Thanks in advance

<slightly off topic> This is for an off season project to convert our PBASIC 2003 robot into a vision robot for presentations </slightly off topic>

Ryan M.
10-05-2005, 14:45
...I want to have it so when I hit a Trigger on the joystick it sends the motor forward until it hits the Top limit switch or if it is already at the top to reverse the motor until it hits the Bottom Limit Switch.

I have:

#define T_DRIVE pwm01
#define Up_T_Limit rc_dig_in01 /* Limit Switch on Full Up Set */
#define Down_T_Limit rc_dig_in02 /* Limit Switch on Full Down Set */
#define T_BUTTON_BTN p2_sw_trig /* Button to change T state. */
/* T state variable. */
int intTState = 0;

...

I'd try something like this:

Somewhere at top of file:

// Your stuff
#define T_DRIVE pwm01
#define Up_T_Limit rc_dig_in01 /* Limit Switch on Full Up Set */
#define Down_T_Limit rc_dig_in02 /* Limit Switch on Full Down Set */
#define T_BUTTON_BTN p2_sw_trig /* Button to change T state. */

int intTState = 0; /* T state variable. */

// My stuff
#define RC_SWITCH_ON 0
#define RC_SWITCH_OFF !SWITCH_ON
#define OI_SWITCH_ON 1
#define OI_SWITCH_OFF !OI_SWITCH_ON

#define T_STATE_UP 1
#define T_STATE_DOWN !T_STATE_UP


Somewhere in main loop:

if(T_BUTTON_BTN == OI_SWITCH_ON)
{
// Switch states. We could do it with intTState = !intTState,
// but just for clarity...
if(intTState == T_STATE_UP)
{
intTState = T_STATE_DOWN;
}
else
{
intTState = T_STATE_UP;
}
}

if(intTState == T_STATE_UP && Up_T_Limit == SWITCH_OFF)
{
// We need to go up more
T_DRIVE = 255;
}
else if(intTState == T_STATE_DOWN && Down_T_limit == SWITCH_OFF)
{
// We need to go down more
T_DRIVE = 0;
}
else
{
// We are at our goal. Stop motor
T_DRIVE = 127;
}


Be advised that I have the code run the motor full speed. If there's no sort of cushion, you could break something. Slow it down if appropriate.

Dave Scheck
10-05-2005, 15:17
Ryan, I don't think that your code is going to do what was requested. With your code, every time it gets called you will change your intTState. I think what you're trying to do is as follows...(This is uncompiled and untested, so be sure to understand the code before trying to run it)
#define T_DRIVE pwm01
#define Up_T_Limit rc_dig_in01 /* Limit Switch on Full Up Set */
#define Down_T_Limit rc_dig_in02 /* Limit Switch on Full Down Set */
#define T_BUTTON_BTN p2_sw_trig /* Button to change T state. */

//NOTE: THIS VALUE MAY CHANGE IF YOUR SWITCH IS NORMALLY OPEN
#define RC_SWITCH_ON 0
// Added parens around the operation to be safe
#define RC_SWITCH_OFF (!SWITCH_ON)

#define OI_SWITCH_ON 1
// Added parens around the operation to be safe
#define OI_SWITCH_OFF (!OI_SWITCH_ON)

#define T_STATE_UP 1
// Added parens around the operation to be safe
#define T_STATE_DOWN (!T_STATE_UP)

// Depending on where this is you'll probably want to make it static
// Also I changed this from a hardcoded 0 to a constant (assuming it starts at the bottom)
static int intTState = T_STATE_UP; /* T state variable. */

...

if(T_BUTTON_BTN == OI_SWITCH_ON)
{
// The button is pressed, let's move the motor
if(intTState == T_STATE_UP)
{
// Currently moving up
if(Up_T_Limit == RC_SWITCH_OFF)
{
// We need to go up more
T_DRIVE = 255;
}
else
{
// We were moving up and hit the upper switch
// Stop the motor and change the state
initTState = T_STATE_DOWN;
T_DRIVE = 127;
}
}
else if(intTState == T_STATE_DOWN)
{
// Currently moving up
if(Down_T_Limit == RC_SWITCH_OFF)
{
// We need to go down more
T_DRIVE = 0;
}
else
{
// We were moving down and hit the lower switch
// Stop the motor and change the state
initTState = T_STATE_UP;
T_DRIVE = 127;
}
}
else
{
// We are in a bad state, stop the motor
T_DRIVE = 127;
}
}

Ryan M.
10-05-2005, 17:28
Yep, you're right. I didn't think to include a "the press is from the last time through!" check. Your code should work, but just for the sake of completeness... :) (new stuff in bold)

Somewhere at top of file:

// Your stuff
#define T_DRIVE pwm01
#define Up_T_Limit rc_dig_in01 /* Limit Switch on Full Up Set */
#define Down_T_Limit rc_dig_in02 /* Limit Switch on Full Down Set */
#define T_BUTTON_BTN p2_sw_trig /* Button to change T state. */

int intTState = 0; /* T state variable. */

// My stuff
#define RC_SWITCH_ON 0
#define RC_SWITCH_OFF !SWITCH_ON
#define OI_SWITCH_ON 1
#define OI_SWITCH_OFF !OI_SWITCH_ON

#define T_STATE_UP 1
#define T_STATE_DOWN !T_STATE_UP

int buttonPressedLastTime = 0;


Somewhere in main loop:

if(T_BUTTON_BTN == OI_SWITCH_ON)
{
// Switch states only if this button press isn't from a loop before
// (the user held it down).
if(buttonPressedLastTime == 0)
{
if(intTState == T_STATE_UP)
{
intTState = T_STATE_DOWN;
}
else
{
intTState = T_STATE_UP;
}
}

buttonPressedLastTime = 1;
}
else
{
buttonPressedLastTime = 0;
}

if(intTState == T_STATE_UP && Up_T_Limit == RC_SWITCH_OFF)
{
// We need to go up more
T_DRIVE = 255;
}
else if(intTState == T_STATE_DOWN && Down_T_limit == RC_SWITCH_OFF)
{
// We need to go down more
T_DRIVE = 0;
}
else
{
// We are at our goal. Stop motor
T_DRIVE = 127;
}

I'm pretty sure that works... hasn't been compiled, but hey, I'm perfect. ;)

Gamer930
11-05-2005, 07:26
Thanks for the help. I partly finished rewiring and converting it to 2004 last night. I will finish up this weekend and let you all know.

One question: When you say SWITCH_OFF that isn't defined. Is that suppose to be RC_SWITCH_OFF??

Dave Scheck
11-05-2005, 11:44
One question: When you say SWITCH_OFF that isn't defined. Is that suppose to be RC_SWITCH_OFF??Good catch...lost track of constant names. I'll update my post to reflect this. It's good to see that you aren't just trying to drop the code in without reading through it. Hopefully you were able to get an understanding of what is being done and can expand it and reuse it in the future.

Ryan M.
11-05-2005, 13:40
One question: When you say SWITCH_OFF that isn't defined. Is that suppose to be RC_SWITCH_OFF??Yep... good catch. I've updated my second post as well.

Alan Anderson
11-05-2005, 15:56
Y'all need to change !SWITCH_ON to !RC_SWITCH_ON as well.

Dave Scheck
11-05-2005, 16:37
Y'all need to change !SWITCH_ON to !RC_SWITCH_ON as well.
You are correct, however, I can't seem to edit my original post...