Yes you can do millis timing inside a function. But you still have to obey the rules of cooperative multitasking, which require that you do not dally around for long periods of time in the function - you have to check something quickly and return quickly.
If you passed a unique call ID number to the function it cpuld be used by the function as an index to an array of variables such as previousMillis and interval which means that the timing for each will not get affected by other calls to the same function
in the first case your calling the same function twice and that function updates the value of previousmillis. so when it is called almost immediately after the first call, previousmillis is the same value as currentmillis
UKHeliBob:
If you passed a unique call ID number to the function it cpuld be used by the function as an index to an array of variables such as previousMillis and interval which means that the timing for each will not get affected by other calls to the same function
Thank you UKHeliBob
This is also a very useful solution.
Would it be very memory consuming if I had, say, an array for 100 calls of previousmillis?
Would it be very memory consuming if I had, say, an array for 100 calls of previousmillis?
Well, 400 bytes. That's a substantial fraction of the RAM available on a Uno, and 100 timed "tasks" is probably at the point where you have to be really careful not to let any of them get "slow."
This is one of the simplest forms of multi-tasking.
westfw:
Well, 400 bytes. That's a substantial fraction of the RAM available on a Uno, and 100 timed "tasks" is probably at the point where you have to be really careful not to let any of them get "slow."
This is one of the simplest forms of multi-tasking.
Ok. Thank you for the code. I will try it these days...
I must have gotten it wrong. I tried the following but it will not deal with one function after the other. I guess it is still the same problem of calling the same function over and over again. How to get it more structured?
int value1, value2, value3, value4;
void setup()
{
}
bool delay_without_delaying(){unsigned long time) {
// return false if we're still "delaying", true if time ms has passed.
// this should look a lot like "blink without delay"
static unsigned long previousmillis = 0;
unsigned long currentmillis = millis();
if (currentmillis - previousmillis >= time) {
previousmillis = currentmillis;
return true;
}
return false;
}
void otherfunction(const int &a, const int &b)
{
do something with a;
do something with b;
}
void loop()
{
if ( delay_without_delaying(1000) )
otherfunction(value1, value2);
if ( delay_without_delaying(1000) )
otherfunction(value3, value4);
}
UPDATE: I did realize that I didn't add the function with &since. I haven't tried it yet but am quite sure this will do the trick.
But how is the value of &since updated being passed by reference? Each call will need memory for an unsigned long?
Can I use this one only if I call it once?
boolean delay_without_delaying(unsigned long time)
Each "timer" will need storage for an unsigned long.
It's pretty much exactly like UKHeliBob's example, except with individual ulongs for each purpose, instead of an indexed array of them.
I think I found a way to successfully use an id to to control Serial output. I combined the input of ukhelibob and westfw's function.
I want to use the id to store the values of previousMillis in an array. But there must be something I am doing wrong as the previousMillis value doesn't seem to be updated:
//#define S_U_LONG static unsigned long
#define INTERVAL 1000
float sensor = 15.5;
int sensor2 = 20;
bool delay_without_delaying(unsigned long);
void setup()
{
Serial.begin(115200);
while (!Serial);
}
bool delay_without_delaying(const byte &id, unsigned long time) {
// return false if we're still "delaying", true if time ms has passed.
// this should look a lot like "blink without delay"
static byte idIndex = 0;
static unsigned long previousMillis[100];
if ( idIndex < id )
{
idIndex = id;
unsigned long currentmillis = millis();
if (currentmillis - previousMillis[id] >= time)
{
previousMillis[id] = currentmillis;
return true;
}
return false;
}
}
void loop()
{
static byte id;
//currentMillis = millis();
if ( delay_without_delaying(id=0, INTERVAL) )
{
Serial.print("HellOO: ");
Serial.println(sensor);
Serial.println(id);
}
if ( delay_without_delaying(id++, INTERVAL) )
{
Serial.print("Hello2: ");
Serial.println(sensor2);
Serial.println(id);
}
if ( delay_without_delaying(id++, INTERVAL) )
Serial.println("Test");
Serial.println(id);
}
Up to now I used this as if condition which caused problems updating previousmillis:
if ( idIndex < id )
I realized now that previousmillis is updated if I save id in idIndex and use this as index of the previousmillis array. Which will help in the functioning of the blink without delay function.
Now the big problem remaining is the selection of the correct id passed to the function. I tried to accomplish with a flag and some more detailed if conditions to better filter the id so they would only be permitted in increasing order until id is reset to zero. Up to now this doesnt work how ever.
Flag and if conditions:
static byte idIndex = 0;
static bool idFlag = false;
if ( id == 0 )
idFlag = true;
else if ( id > 0 && id > idIndex && id == idIndex+1 )
idFlag == true;
if ( idFlag )
{
idIndex = id;
The whole current code:
#define INTERVAL 1000
float sensor = 15.5;
int sensor2 = 20;
bool delay_without_delaying(unsigned long);
void setup()
{
Serial.begin(115200);
while (!Serial);
}
bool delay_without_delaying(const byte &id, unsigned long time) {
// return false if we're still "delaying", true if time ms has passed.
// this should look a lot like "blink without delay"
static unsigned long previousmillis[50];
unsigned long currentmillis = millis();
static byte idIndex = 0;
static bool idFlag = false;
if ( id == 0 )
idFlag = true;
else if ( id > 0 && id > idIndex && id == idIndex+1 )
idFlag == true;
if ( idFlag )
{
idIndex = id;
if (currentmillis - previousmillis[idIndex] >= time) {
previousmillis[idIndex] = currentmillis;
return true;
}
return false;
idFlag = false;
}
}
void loop()
{
static byte id;
if ( delay_without_delaying(id=0, INTERVAL) )
{
Serial.print("HellOO: ");
Serial.println(sensor);
Serial.println(id);
}
if ( delay_without_delaying(id++, INTERVAL) )
{
Serial.print("Hello2: ");
Serial.println(sensor2);
Serial.println(id);
}
if ( delay_without_delaying(id++, INTERVAL) )
{
Serial.println("Test");
Serial.println(id);
}
}
What would I have to change to only allow the id's in "correct" increasing order?