Log in

View Full Version : A few questions on programming the Control System


Avarik
03-02-2004, 07:21
First off, let me start by saying I really don't know C too well. I am having a hard time programming, but I am attempting to do it anyway. Now...I have a few questions for programming the control system.

Firstly, how would I set up a system to push 1 button to open and close pneumatics? I was thinking about having a state which is altered if the button is pushed, but I cannot figrure out how to do this (from decleration to initialization to writing the code!)

Secondly, how do I create a program which will overide all other code and execute a set of commands? This would be to use pneumatics to shift gears in a gearbox. I am unsure how to program the code, and set up overiding the system. I was thinking about using interupts, but I don't know how to call them (I have Kevin's code with the interupts added in.)

Thanks in advance! Any help is appreciated!

Adam Shapiro
03-02-2004, 08:48
Firstly, how would I set up a system to push 1 button to open and close pneumatics? I was thinking about having a state which is altered if the button is pushed, but I cannot figrure out how to do this (from decleration to initialization to writing the code!)
There could be another (better) way but the way I did it last year (now in C) would be as follows:
bool pressed=false; //is switch pressed (put this somewhere where it will remain globally constant)
if(p1_sw_top&&!pressed)
{
pressed=true;//set the toggle value
relay1_fwd=(!relay1_fwd);//set the relay state
}
else if(p1_sw_top)
{
//do something else if you want (but you don't have to)
}
else
{
pressed=false;//turn off the toggle
}


Secondly, how do I create a program which will overide all other code and execute a set of commands? This would be to use pneumatics to shift gears in a gearbox. I am unsure how to program the code, and set up overiding the system. I was thinking about using interupts, but I don't know how to call them (I have Kevin's code with the interupts added in.)
I'm not exactly sure what you need but you can use an if statement to check for a certain state and call functions you create (run_drive_code() and run_override_code() for example) based on the state. That would probably be the easiest method unless you need multiple override options in which case a switch statement would probably be useful.

Ryan M.
03-02-2004, 09:04
bool pressed=false;
Do we actually have a built in boolean type? This is C and C typically doesn't have a built in bool. Just wondering. :)

Adam Shapiro
03-02-2004, 21:31
Do we actually have a built in boolean type? This is C and C typically doesn't have a built in bool. Just wondering. :)
I guess you are right. I'm more used to C++ so sometimes I forget the simple differences.

Avarik
04-02-2004, 03:01
I tried the code and it didn't work, thanks for the help though! I have a much better understanding of it. However, it seems I cannot type in p1_sw_top as a variable for an if statement, doesn't seem to work.

Also, I need to do this multiple times...I was wondering if there would be a way to set up a function and call it multiple times sending different values in for different solenoids?

Once again, thank you very much for the help!

Ryan M.
04-02-2004, 16:22
I guess you are right. I'm more used to C++ so sometimes I forget the simple differences.Yeah, I'm a C++ guy too! :)

Also, I need to do this multiple times...I was wondering if there would be a way to set up a function and call it multiple times sending different values in for different solenoids?Do you really mean a solenoid? They are just on or off systems. Give a few more details on what you want the function to do and I can probably help. (Probably... :))

Jay Lundy
04-02-2004, 19:29
You can still sort of use bools.

typedef bool unsigned char;

or

typedef unsigned char bool;

I can never remember which (more of a C++ guy myself too). I think it's the top one though.

Also:

#define TRUE 1
#define FALSE 0

Avarik
05-02-2004, 00:29
Sorry, I realize my post wasn't too clear, so here is exactly what I want to do.

I simply need a way to control the solenoid with one button. In the code, you control a relay's forward/backward signal with 2 buttons (one for each). I was wondering how I could make it so 1 button could control a solenoid, where some state would change each time I hit it, sending a different signal.

Example: If I were to hit the trigger of the controller in port 1 the first time, it would cause a cylinder to open by sending the command to the solenoid. However, the next time hit this trigger, the cylinder would close. I am not sure it matters, but we will be using only double solenoids.

I want to create some sort of function which could do this, as I would need to set up quite a few for this years robot. I have been looking through the code, trying to find a way to do this succesfully for a while now, and I can't seem to do it.

My main problem is that I can't find a way to detect whether or not a trigger has been hit. I tried #if p1_sw_trig, but I got a malformed function error. If I try #if (p1_sw_trig) then it says expected ')' and malformed function...

rdsideresistanc
05-02-2004, 01:04
Sorry, I realize my post wasn't too clear, so here is exactly what I want to do.

I simply need a way to control the solenoid with one button. In the code, you control a relay's forward/backward signal with 2 buttons (one for each). I was wondering how I could make it so 1 button could control a solenoid, where some state would change each time I hit it, sending a different signal.

Example: If I were to hit the trigger of the controller in port 1 the first time, it would cause a cylinder to open by sending the command to the solenoid. However, the next time hit this trigger, the cylinder would close. I am not sure it matters, but we will be using only double solenoids.

I want to create some sort of function which could do this, as I would need to set up quite a few for this years robot. I have been looking through the code, trying to find a way to do this succesfully for a while now, and I can't seem to do it.

My main problem is that I can't find a way to detect whether or not a trigger has been hit. I tried #if p1_sw_trig, but I got a malformed function error. If I try #if (p1_sw_trig) then it says expected ')' and malformed function...

I have implemented this very thing into our FRC code. Basically you need one button to just flip the spike from green to red (or vice versa).


void toggle_spike(unsigned char button, unsigned char relayfwd, unsigned char relayrev) {
if (button == 1) {
cyl_count++;
} else {
cyl_count = 0;
}
if (cyl_count == 1) {
if (relayfwd == 1) {
relayfwd = 0;
relayrev = 1;
} else {
relayfwd = 1;
relayrev = 0;
}
} else {
relayfwd = relayfwd;
relayrev = relayrev;
}
}


I think that should work. Just initialize cyl_count at the top of user_routines.c like:


unsigned int cyl_count = 0;


Then if you just place it where your current relay definitions are in user_routines.c and pass it the correct variables. Like:

instead of:

relay1_fwd = 1;
relay1_rev = 1;


put this:

toggle_spike(p1_sw_trig,relay1_fwd,relay1_rev);


Keep in mind that im used to C-based languages...i've not done much programming in C....someone verify my code maybe?

Avarik
05-02-2004, 01:56
Interesting, and thanks! I'll test this tomorrow if I can.

Joe Ross
05-02-2004, 07:31
Keep in mind that im used to C-based languages...i've not done much programming in C....someone verify my code maybe?

you need to pass relayfwd and relayrev as pointers so that the modifications you make don't get "thrown out" when you exit the function.

I'm also not sure what the purpose of cyl_count is. Since you increment it each time the button is pressed, and reset each time it isn't pressed, it will only hold the value of 0 or 1. You could make the code much simpler by changing if (cyl_count == 1) to if (button) and removing the code before that.

Based on the sound of the variable name (cylinder count?), it seems that you may want to keep track of how many times you activated a cylinder. If you want to do that, remove the else {cyl_count = 0} part and change the if statement like I said above.

However, you only then would have the count of how many times total cylinders had been activated. You could pass cyl_count as a pointer again and have multiple variables for multiple cylinders.

Raven_Writer
05-02-2004, 08:02
You can still sort of use bools.

typedef bool unsigned char;

or

typedef unsigned char bool;

I can never remember which (more of a C++ guy myself too). I think it's the top one though.

Also:

#define TRUE 1
#define FALSE 0It'd be

typedef unsigned char bool;


Also, here's a another way (taken from HartRobots.com):

typedef enum{
true = 1, false = 0
} bool;

Ryan M.
05-02-2004, 11:13
typedef enum{
true = 1, false = 0
} bool;
According to one of my programming mentors, enums don't work with this compiler. I didn't actually try it myself, but I trust him enough to think he did it right. :D It was also on the edubot, preseason. But, the compilers the same, so if it didn't work on one, it probably won't work on the other.

Mike Soukup
05-02-2004, 11:17
According to one of my programming mentors, enums don't work with this compiler. I didn't actually try it myself, but I trust him enough to think he did it right. :D It was also on the edubot, preseason. But, the compilers the same, so if it didn't work on one, it probably won't work on the other.
If they don't work, we're all in trouble since there's an enum in 'ifi_utilities.h'. Our current code has multiple enum's and we haven't had any problems with them.

Ryan M.
05-02-2004, 11:26
If they don't work, we're all in trouble since there's an enum in 'ifi_utilities.h'. Our current code has multiple enum's and we haven't had any problems with them.OK, well, I'll guess I have to yell at Greg. He probably did it wrong. He actually is a Java programmer, not C/C++. Thanks for telling me. :)

rdsideresistanc
05-02-2004, 12:34
you need to pass relayfwd and relayrev as pointers so that the modifications you make don't get "thrown out" when you exit the function.


You are correct about this.....hmm....could you possibly tell me how to pass them as pointers?

Raven_Writer
05-02-2004, 14:57
If they don't work, we're all in trouble since there's an enum in 'ifi_utilities.h'. Our current code has multiple enum's and we haven't had any problems with them.enum's work. I've tried the code out on the compiler. It compiles perfectly and such.

Joe Ross
05-02-2004, 15:18
Here is how I would implement the code (from which you should be able to figure out how to implement your code with pointers)


void toggle_single_solenoid(unsigned char button, unsigned char *prev_button, unsigned char *relay_fwd)
{
if (button && !prev_button) //don't keep toggling if they hold the button
*relay_fwd = !(*relay_fwd);

*prev_button = button;
}

call it like this:
toggle_single_solenoid(p1_sw_trig, &prev_p1_sw_trig, &relay1_fwd);

Remember to declare prev_p1_sw_trig and change the variables to whichever switches and relays you want.

seanwitte
05-02-2004, 15:36
I haven't tried it, but can you have a pointer to a bit field? relay1_fwd is a macro with the value LATDbits.LATD0. Just curious.

Avarik
06-02-2004, 10:13
What exactly is prev_button?

And thanks...I've been at this for too long...

Shouldn't take me this long!

Avarik
08-02-2004, 02:55
Alright, I finally figured it out! Here is how I did it.


if (p1_sw_trig && rel1==0)
{

rel1++;
if (rel2==0)
{
relay1_fwd=1;
rel2++;
}
else
{
relay1_rev=1;
rel2--;
}

}

if (!p1_sw_trig)
{
rel1=0;
relay1_fwd=0;
relay1_rev=0;
}




rel1 and rel2 are simply declared as ints, where rel1 is initialized to 0, and rel2 to 1. This makes it go forward at first, then backwards the next time.

Adam Shapiro
08-02-2004, 11:42
Alright, I finally figured it out! Here is how I did it.


if (p1_sw_trig && rel1==0)
{

rel1++;
if (rel2==0)
{
relay1_fwd=1;
rel2++;
}
else
{
relay1_rev=1;
rel2--;
}

}

if (!p1_sw_trig)
{
rel1=0;
relay1_fwd=0;
relay1_rev=0;
}




rel1 and rel2 are simply declared as ints, where rel1 is initialized to 0, and rel2 to 1. This makes it go forward at first, then backwards the next time.
Essentially my method. ;)