I have defined an array as follows
int action[3][4] = {
{2, 4, 1000}
{3, 2, 800}
{5, 5, 1000}
{8, 4, 800}
}
The first column of the array represents time. I want to run a loop that starts from time 0 and goes up in increments of one, then when the time count is equal to a number in the first column of the array it proceeds to do an action.
i.e. something like this
if timecount = action(action_point, 1) {
etc. }
where action_point is the index of the array.
Can anyone tell me how this can be done?
Thanks
First, you have an array of 4 by 3, not 3 by 4, so it would be "action[4][3]".
Second, so I can understand, is everything in bold the time, and if so what are the other two columns?
{2, 4, 1000}
{3, 2, 800}
{5, 5, 1000}
{8, 4, 800}
Thanks for pointing that out. Yeah, the bold column is time. The second column is the length of time to run a motor and the third column is the speed at which to run the motor
The second column is the length of time to run a motor and the third column is the speed at which to run the motor
So, given that data, the motor does nothing for two seconds. Then, starting at 2 seconds, the motor runs at 1000 something for 4 seconds. Then, starting at 3, the motor runs at 800 something for 2 seconds.
Does that mean that from 3 to 5, the speed should be 1800 somethings?
Do you see that duration is not needed?
There are multiple motors in question, there is a column I've left out. What i'm mainly interested in is the time count, do you understand what i mean?
What i'm mainly interested in is the time count, do you understand what i mean?
Yes. You can record when loop starts (using millis()). Then, periodically, you can see if enough time has passed (again, using millis()) to necessitate doing anything. If it has, do it.
How would that be written in Arduino?
ajr93:
There are multiple motors in question, there is a column I've left out. What i'm mainly interested in is the time count, do you understand what i mean?
In that case there's another important requirement which you have implied but not stated - turning each motor off at the end of the specified run duration.
I suggest you try to restructure your data so that you have explicit start/stop actions for each motor. It avoids a significant amount of complexity in your sketch and also eliminates some awkward corner cases where your list of actions has inconsistencies of the sort that PaulS pointed out.
If you take that suggestion then your ketch would need to iterate through the action array and execute each action as it becomes due. The simplest implementation would be to make your sketch block (stop and wait) until the next action is due. However, that would make is difficult for your sketch to do anything else at the same time. A better approach would be to design your sketch to be non-blocking: you could define a global variable which holds an index into your global action array, and identifies the next action to be carried out. Then add some code which uses millis() to read the current Arduino time (relative to the startup) and test whether it was time to execute the next action. If it is, execute the action and update the index for the next action. I'd suggest putting that code in a function to be called from loop().
You will need to decide what to do when you get to the end of the action array - do you want to go back to the beginning and repeat it, or just go through once and stop?
What you are asking for is a scheduler. I am sure it is possible to do it in Arduino, since it is very common in embedded design. Usually you have a timer that iterates on a fixed amount of time (nice round number like 10ms, or 100ms), then an array of objects that holds Time remaining, Wait Time, task ready, and Task to execute (This could just be the durations you have in the system), and possibly Enable/Disable, Priority, and other stuff, but the first 3 items are the important thing. Though looking through, I think you understand this.
Now the other important thing is to have a fixed timer. Usually you set up the onboard timer and set up an ISR, and every time the timer increments, you go through your array, check if any of the events are ready, set them up to execute, and then decrement the time remaining on the rest of the array.
However, if you are lazy and don't need the system to do anything else, you can just set it up to execute in your loop() and put a delay at the end with a fixed time. Or have it trigger whenever Millis()% = 0.
How would that be written in Arduino?
Using the IDE or your favorite text editor.
PaulS:
How would that be written in Arduino?
Using the IDE or your favorite text editor.
I think he meant, "how would the code look like"?
Something like this.
if(((millis() - setTime) / 1000) >= action[0][ /*0 - 3)*/ ])
{
.
. // do something here for that time
.
}
setTime = millis();
First of all, rather than use a 2d array, you would be better off using an array of structs, because the code will be much clearer. Like this:
struct motorParameters
{
int startTime;
int duration;
int speed;
};
motorParameters[] action =
{
{2, 4, 1000},
{3, 2, 800},
{5, 5, 1000},
{8, 4, 800}
};
To schedule the motors, you can use something like:
for (int i = 0; i < sizeof(action)/sizeof(action[0]); ++i)
{
if (timecount == action[i].startTime)
{
motorOn(i, action[i].speed);
}
if (timecount == action[i].startTime + action[i].duration)
{
motorOff(i);
}
}
PS - if you want to use a scheduler, then I have one at GitHub - dc42/arduino: Reusable modules, drivers and patches for the Arduino platform. But this project sounds simple enough not to need one.