easyC: Detecting Unique Button Presses

I’ve been writing code in ROBOTC for a while now, and I was asked to write a program for a team in easyC. I was having little issue writing the program, but I ran across a weird peculiarity. I was programming the joystick so that every time you press one of the buttons, it would change a digital output (pneumatics). Normally, you could just use Joystick Digital to Digital Output, but it needed to be every time you push the button, it would change to the other value (0 to 1 and vice versa). My way of writing this in ROBOTC is as follows:

if(vexRT[Btn5U] == true && ClampPressed == false) { AutoClamp(); ClampPressed = true;}
		else if(vexRT[Btn5U] == false) {ClampPressed = false;}

This code works fine, I could detect whether button has been pressed and if it is currently pressed. The AutoClamp() detects what the clamp currently is and changes it accordingly.

Now, the problem arises when I write the same code in easyC. I of course change the syntax so we call the button before querying, falses to 0s, trues to 1s etc., etc. The issue is that when the button is pressed, the pneumatics start rapidly switching back and forth. It is as if the robot doesn’t change the the ClampPressed value.

My question is this: how do you detect when the a joystick button has been pressed or how do you achieve the same thing I’m trying to do here?

Out of curiosity what does the function AutoClamp do?

I think there’s already a function called JoystickToDigitalLatch. I wrote an equivalent (and generic) version to simulate it here.

https://vexforum.com/showpost.php?p=326321&postcount=24

Post the EasyC version so we can take a look. Which digital port are you using? Is it programmed to be an output?

I tried this, works just fine (replaced AutoClamp() with a simple output toggle).

#include "Main.h"

void OperatorControl ( unsigned long ulTime )
{
    int ClampPressed = 0; 
    int PneumaticsState = 0; 

    while ( 1 ) // Insert Your RC Code Below
        {
        if ( (GetJoystickDigital(1, 5, 2 ) == 1) && (ClampPressed == 0) )
            {
            ClampPressed = 1 ;
            PneumaticsState = 1 - PneumaticsState ; // // toggle PneumaticState
            SetDigitalOutput ( 12 , PneumaticsState ) ;
            }
        else if ( GetJoystickDigital( 1, 5, 2 ) == 0 )
            {
            ClampPressed = 0 ;
            }
        Wait ( 50 ) ;
        }
}

Things I would check.

The default digital outputs are 9 - 12, the others are inputs, change the direction if you are using them.

Are the variables you are using local, global? Does ClampPressed retain its state in whatever function this code really resides.

Both solutions (JoysticktoDigitalLatch and your solution) worked (we needed both, as we have a servo clamp and pneumatics tray).

Thanks for all the help, jpearman.

BTW, 1826_Kitteh:

void AutoClamp() {
	switch (ClampCurrent) {
	case true:
		motor[SSL] = -100;
		motor[SSR] = 100;
		ClampCurrent = false;
		writeDebugStreamLine("Clamp off");
		break;

	case false:
		motor[SSL] = 50;
		motor[SSR] = -50;
		ClampCurrent = true;
		writeDebugStreamLine("Clamp on");
		break;
	}
}

ClampCurrent is a global boolean.

The way I do it is I have a Controller struct that holds the previous state of all the button presses and updates during each iteration of the while(true) loop.

So if you want to detect a button that just went down, you would do something like:

Controller Joystick;
//Some other code
if(Joystick.Buttons_Down[GetJoystickIndexFromButton(Btn7R)])
//do stuff

Where Joystick has the fields Buttons_Down, Buttons_Up, and Buttons_Last. Buttons_Down for a button is true when vexRT = true but Buttons_Last = false. Buttons_Up is the opposite. The struct’s fields are updated each loop.

It’s useful for toggles for single buttons as well as for double button toggles, but it’s a bit more complex for double toggles.

Any chance I could get a full copy of that RobotC file? I want to achieve that effect, but AutoClamp() is an unrecognized procedure and I’m not sure if I’m missing something…

Yep, AutoClamp() automatically switches whatever servo/pneumatics you have and uses the boolean ClampCurrent as a watchdog to know where the clamp currently is.

void AutoClamp() {
	switch (ClampCurrent) {
	case true:
		motor[SSL] = -100;
		motor[SSR] = 100;
		ClampCurrent = false;
		writeDebugStreamLine("Clamp off");
		break;

	case false:
		motor[SSL] = 50;
		motor[SSR] = -50;
		ClampCurrent = true;
		writeDebugStreamLine("Clamp on");
		break;
	}
}

I also wrote a little function where you can set the clamp yourself. The only difference from any other function is that it changes ClampCurrent, so if you call AutoClamp() after messing with the current position of the clamp, it will go to the actual opposite position.

void Clamp(bool setting) {
	switch (setting) {
	case true:
		motor[SSL] = 50;
		motor[SSR] = -50;
		ClampCurrent = true;
		writeDebugStreamLine("Clamp on");
		break;

	case false:
		motor[SSL] = -100;
		motor[SSR] = 100;
		ClampCurrent = false;
		writeDebugStreamLine("Clamp off");
		break;
	}
}

You should also initialize ClampCurrent outside those two functions (so it acts as a global). Also, false is clamp off and true is clamp on.


bool ClampCurrent = false;

I initialized ClampCurrent as false because a) you could run into some potential issues with you running AutoClamp with no value (should never happen) and b) I set the clamp using two standard motor] during the startup sequence of my code.

Thank you very much for replying, but where would I connect this all to a button on the joystick? And where you wrote motor I should change to the pneumatic sensor port and change the value to 1 and 0 right? Sorry for my ignorance, I just started using RobotC and its hard to get used to from EasyC. And thanks again for any help.:slight_smile:

EDIT:

If you happen to have the time, could you go over this? I used your code but just changed the motor to pneumatics and the values to 1s and 0s…Im not sure if I have the variable types correct (or in the right place) and same with the function. Again, any help is much appreciated :slight_smile:

DOUBLEEDIT:

I finally got access to the robot to test the program and…IT WORKS! Thank you so much edjubuh, I would have never gotten that to work by myself. You saved myself and my team a whole bunch of time and headaches. Really, that had stumped both myself and our real programmer since the beginning of the year. Thank you again :slight_smile:
Hopefully we will see each other at Worlds this year, however if we don’t, we all wish you the best of luck.
PneumaticTest.c (3.39 KB)

No problem, 7708 is also in your division (Engineering). Good luck at Worlds!