Timed task

I haven’t been able to get a timed task working properly.
Here’s the old code:

static float MGTim;
static float MGDc;
task MGLy()
{
	while(true)
	{
		motor[MGL] = MGDc;
		wait(MGTim);
		motor[MGL] = 0;
	}
}

task autonomous()
{
  startTask(MGLy);
  MGDc = -127;
  MGTim = 1.1;
}

And what I’m seeing is some motor jittering, like the task keeps on running.
I just wrote this code:

static float rp;
static float rt;
static float rtog=0;
task rmgl()
{
	while(rtog == 1)
	{
		motor[MGLF] = rp;
		wait(rt);
		motor[MGLF] = 0;
		rtog = 0;
	}
}

task autonomous()
{
  startTask(rmgl);
   rtog = 1;
  rp = -127;
  rt = 1.1;
}

What I want to happen is for the motor to turn on for 1.1 sec then turn off til I redefine the variables. Will this work? If not, what do i need to change?

static float MGTim;
static float MGDc;
task MGLy()
{
	
	motor[MGL] = MGDc;
	wait(MGTim);
	motor[MGL] = 0;
	
}

task autonomous()
{
  startTask(MGLy);
  MGDc = -127;
  MGTim = 1.1;
}

You had a while loop, so you told it to loop your action forever.

After I posted I realized that. Thank you!

I don’t have time to read through both thoroughly right now, but some comments on the first:

The real problem: What is the point of the wait() and motor]=0 commands inside the while loop? You have them all inside while(true). This means you’re trying to run the motor at the given power almost all the time, except for a bunch of microseconds when you’re going to turn the motor off before turning it back on again as the while loop repeats. Presumably you only wanted this to happen once, giving a point to those commands, which you’ve undone because of the while loop. So, yes, the task should keep running because you’ve told it to run forever. Get rid of while(true){}.

Second, why are you defining a value we want to be an integer as a float? MGDc shouldn’t be a float, though it should work.

Third, you’ve decided to pass values to the task without passing values to the task. You should write things more like this:

task MGLy(int MGDc, float MGTim)

Then you place the value in there. It’s a much, much better practice.

edit: ninja’d, but do check the rest of my advice.

1st: already fixed.
2nd: I don’t know the difference between a float and an integer
3rd: I don’t understand. My voids look like that but none of my tasks do. How do I implement that formatting when I want to call it?

Not valid code. The way he did it was correct.

Oh, wow. That’s… sad. That would mean putting a task in a separate file would require creating a function to which you pass values or just making tons of global variables. That’s bad C. Why did they write RobotC that way?

@callen - Tasks do not have parameters passed to them the way functions do. The task is always running in the background, so if you set a task-related variable to a value (like MGDc = -127) in the main part of the program, then it functions in (very basically) the same way as passing values to a function.

So my original code will work if I just remove the while statement correct?

Well, they’re usually passed in lambda’s, right? And RobotC doesn’t include lambda’s, right?

I’m not as used to tasks, I’ll readily admit. But I am used to writing programs with thousands of lines of code split across many files. One of the big ideas in programming is to isolate values. One of the reasons is so you don’t have to look all over the place for where you’ve used something you’ve decided to change. The best programming instructor I know says, roughly, “If you’re using global variables to do something, you don’t really know what you’re trying to do properly.”

The while statement made the task an infinite loop. It should have run the motor forever with periodic, very short, attempts to stop. Yes, remove it.

Bruh I’m still learning. I ain’t ready for all that I just need a timed task.

That was mostly just a response to the others.

Just remove the while loop. See if it works.

Of course

If I have 5 tasks that never stop, there is no better way to communicate between them than global variables. If you just think of a tasks as a quick function that runs in parallel, it can feel silly to not have parameters. But if you think of them as running an entire subsystem forever the parameters don’t change much.

Anonymous functions (lambda expressions) really make no difference in this use case.

Some sort of shared memory interface is the most common way to communicate between tasks. Global variables in the same processor context (and the same variable scope and namespace) is the simplest implementation of shared memory. It is particularly well suited for use cases where one side writes the values and the other side reads, so that no synchronization is required. I don’t remember the level of atomicity guaranteed by RobotC, but I believe a variable write is an atomic operation in the RobotC Virtual Machine.

Other more complex constructs are built on top of shared memory (or global variables). You can build up mutexes, spin locks, queues, mailboxes, and message passing architectures all on top of shared memory or global variables. But no reason to go to the more complex architectures if the simple global does the job.

Your instructor may have little experience in embedded systems. Communicating between concurrently operating tasks on the same hardware requires pushing data through something both sides can access. The most light-weight of these is global variables, and works fine for the purposes here.