Can we do multitasking?

It not matters if it's easy for us to use a kitchen clock but if for others is simple.
@Robin2 you have answered hundreds of threads with links to the famous "blink without delay" and this confirms its complexity.
It is also strange to hear about millis as a substitute to a scheduler, do different things and in different ways.
Not always you will need a scheduler as always millis and the state machine will be able to replace a scheduler.
Could you with a simple millis + state machines have features non-blocking, interrupt differentiated for each function, priorities on who should be executed first, stop at any time a function that wastes too many resources to be active another?

I seem to be two very different things that you should not confuse it abuse.

@Robin2 you have answered hundreds of threads with links to the famous "blink without delay" and this confirms its complexity.

Just because a noob hasn't found it yet doesn't "confirm its complexity".

How many actual lines of significant code is blink without delay?
Six?
Seven?

you have answered hundreds of threads with links to the famous "blink without delay" and this confirms its complexity.

I think that it proves the exact opposite. For many purposes the BWD principle provides a simple way of implementing non blocking timing in direct contrast to the use of the delay() function which is where many references to BWD arise. Combine millis() timing with a state machine and you have a powerful, readable and flexible way of controlling what happens and when without the need for a library or class.

Programming in a limited environment intensifies the need to take an open minded, global view of the techniques for multi tasking and timing (as well as other things). It's important to weigh the advantages and disadvantages and not hide any of them because we have a favourite way of doing things.

With multitasking, there must be a framework to allow safe inter-operation of the task components. There is always some complexity to such a solution. With round robin loop() multitasking, the penalty is the requirement to use states and to prohibit blocking. With pre-emptive schemes, there are the issues of code bulk for the scheduler itself, resource allocation and interprocess communication, overhead in task switching, and other things to worry about.

There isn't a "right way", but there also isn't an easy way. I would happily experiment with a pre-emptive system but I haven't seen anything gaining traction. It seems to me that you would begin with a large code overhead. Perhaps it could be reclaimed if the user code was more efficient as a result, when the user code size increases. But I would be skeptical about the thing working very well on anything smaller than a Mega. Most of the sketches I'm writing now already use about 80% of the available RAM.

TechnoBubba:
Response to dmjlambert (#31)

Anything that uses millis which increments is "doomed" to rollover and requires extra code to work around that problem. Please see #30.
Thanks. :slight_smile:

Would you like to learn why there is no "rollover problem" or extra code involved when you use unsigned variables to do the math. None Whatsoever.

A 12 hour clock is unsigned. Let's do an unsigned subtraction on that and see what happens?
The formula I want to use is: Now - Start = Interval
Now it is 2 and my last time mark, Start, was at 9.
So from 2, I subtract 9 by moving the hand left 9 hours and the result is the hand on 5.

Unsigned variables work like that only with more than 12 positions. No problem with "rollover".
Work it out on paper using 4-bit values, a 16 hour clock but use bits instead of clock hands and don't forget to leave carry or borrow out of it unless you want to count 'days' on the side.

Here's a sketch you can plug values into and see what happens without doing the math yourself.

unsigned long a, b, c;

void setup() {
  Serial.begin( 115200 );
  Serial.println( "\n unsigned math\n" );
  
  a = 0xffffff00UL;
  b = 0x10UL;
  Serial.print( "a = ");
  Serial.print( a, DEC );
  Serial.print( " = 0x");
  Serial.print( a, HEX );
  Serial.print( " = 0b");
  Serial.println( a, BIN );
  Serial.print( "b = ");
  Serial.print( b, DEC );
  Serial.print( " = 0x");
  Serial.print( b, HEX );
  Serial.print( " = 0b");
  Serial.println( b, BIN );
  
  if ( b >= a ) Serial.println( "b >= a" );
  else          Serial.println( "a > b" );
  c = a - b;  
  Serial.print( "a - b = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  
  c = b - a;
  Serial.print( "b - a = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );

  c = b - (b + 1);
  Serial.print( "b - (b + 1) = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  
  while( 1 );
}

void loop() {};

I have good working sketches that time contact switch/button bounce using the low 8 bits of Arduino millis. That's good up to 255 millisecond intervals, bounce takes 2 to maybe 20 (extreme case) so I don't bother storing or using 32-bit values to time switch stable states, I can have 4x as many buttons for the same RAM it takes to use 32-bit time values. The number of bits only determines the length of the maximum interval I can time, it's the unsigned part that makes it able to work.

PaulMurrayCbr:
In attempting to do something complex, you run out of pins before you run out of anything else.

A better solution can sometimes be to get two arduinos. They're twenty bucks. If the components have to talk to each other, then you can do the co-operative multitasking on one arduino, or you can have multiple microprocessors talking o each other.

Or use "pin multipliers" like (but not only)

-- parallel to serial Output Shift Registers ( cheap, so many for $1 from some stores)
-- serial to parallel Input Shift Registers ( cheap)
-- Universal Serial Registers where the data direction of each pin can set and changed. (not so cheap)
-- led driver and RGB led driver chips

These run on SPI bus, they can be daisy-chained and there are people running 8x8x8 RGB led cubes with small AVR powered Arduinos.

vbextreme:
It not matters if it's easy for us to use a kitchen clock but if for others is simple.
@Robin2 you have answered hundreds of threads with links to the famous "blink without delay" and this confirms its complexity.

BWD method is "complex" when you don't know how it works and will remain so for you.
Learn and then you wonder why it wasn't obvious before.

It is also strange to hear about millis as a substitute to a scheduler, do different things and in different ways.

To the same end. When the store is down the block, feet can substitute the need for a car.

Not always you will need a scheduler as always millis and the state machine will be able to replace a scheduler.

True for over 99% of cases. What's your point?

Could you with a simple millis + state machines have features non-blocking, interrupt differentiated for each function, priorities on who should be executed first, stop at any time a function that wastes too many resources to be active another?

Not all that but then I engineer my code to not need those last two steps to FIX anything while with a scheduler I certainly do!

I seem to be two very different things that you should not confuse it abuse.

I bet you meant It instead of I there?

What we are doing that one part is millis timing is writing Event Driven Code. Time is only one kind of event trigger, process state value is another, pin state another, serial available another and the values of data variables as single number or table of truth-bits can go as far as you take them.

We show the most simple to teach those who can how to do amazing code in very small environments. It works great with little overhead.

I like @aarg's Reply #44.

To my mind there are two important aspects of multitasking - is it easy to use and does it leave as many as possible free CPU cycles available for real work.

And by "easy to use I especially mean is it easy to figure out the problem when it is not doing what think it should be doing. I much prefer to spend my time figuring out my problem rather than trying to figure out some other person's library.

...R

TechnoBubba:
Response to dmjlambert (#31)
Anything that uses millis which increments is "doomed" to rollover and requires extra code to work around that problem. Please see #30.
Thanks. :slight_smile:

Well I have 2 things to say to that:

  1. No, there is no rollover doom, and
  2. I guess the point I was trying to make was completely missed, as I was simply talking about piggybacking on the same ISR millis uses. Your method uses an interestingly simple way of counting down, but I don't like the ISR using TimerOne.

Last Response to all "participants-of-interest"

  1. I didn't mean to "Gore anybody's Ox.
  2. There are more than "many" ways to skin the "cat"
  3. I'm suspecting that just a few have actually looked at the code.
  4. Some are fixated on cramming "schedulers" into a $6.99 UNO when the MEGA at $12.99 equals 3 or 4 UNOs
  5. Alright, I concede your "preference" to preserve Timer1 ( on a MEGA w. 3 more?) for some other need.
  6. I'm still trying to figure out how the millis() can count up 'forever' without eventually overflowing and
    going thru "zero" - unsigned or not, and I don't care how "long" the "long" is.
  7. I'm going to go out on a "limb" here - my example runs faster, just count the instructions taken.
    ( and last )
  8. You will not "HURT" my feelings if you find my code without merit and never USE IT !
    Thanks for your interest. Happy New Year !! :slight_smile:

millis do rollover but it's not really a problem, as described here: Arduino Playground - TimingRollover

@AWOL #43
For those who have been created Arduino? for advanced users? no because here can be counted on the fingers of one hand.
Arduino means SIMPLE and millis() it is not, how many posts you have to continue to respond to convince yourself.
And do not tell me that just study, so the Arduino would lose all its customers.

@Robin2 #48
If so we thought we would all stop assembly with a touch of C, forgetting what can serve the C++
Simplify a problem is sometimes necessary to reduce the number of bugs, but in 90% of cases, I agree with your answers when the tips millis (), although I would prefer a delayAsync () for those who just want to turn yet another Christmas tree.

TOPIC: can we do multitasking?
YES! Arduino permits, or they attempt to make them do. But it is an advanced concept, you have to first investigate whether it is really necessary, not as a call to millis()

P.S. I will be happy only when I stop to see threads on BlinkWithoutDelay

vbextreme:
P.S. I will be happy only when I stop to see threads on BlinkWithoutDelay

I hope you are prepared for a long period of misery :slight_smile:
(none of it intended against you personally)

vbextreme:
6. I'm still trying to figure out how the millis() can count up 'forever' without eventually overflowing and
going thru "zero" - unsigned or not, and I don't care how "long" the "long" is.

I'm afraid that, for me, this completely disqualifies you from giving advice about programming. It is the essence of unsigned integer maths.

Would you trust a doctor who does not know how to use a clinical thermometer ?

...R

The point is, that although millis() does count up and eventually go through its maximum value and back to zero that there are programming techniques that mean this does not cause a problem. For the avoidance of doubt, I am referring to the use of subtraction of unsigned values and not the detection of the transition through zero and taking avoiding action.

@Robin2:
I hope you are prepared for a long period of misery :slight_smile:

We're working to fix :slight_smile:
What do you think of delayAsync()?
It can be complicated?

My advice, @vbextreme.

Package and document your concept, with some examples that a noob could understand. Host it somewhere. When that is done, start another thread about it. This is an old thread that has been hijacked multiple times. It also invokes a racial slur every time it comes back to life.

Honestly, I'm interested in your idea, but proffering examples here doesn't make it useful to me. Again, I need a fully functional package, with examples (it should include an equivalent BWOD). You claim that it can be simpler for beginners. That is the way to prove it.

TechnoBubba:
Last Response to all "participants-of-interest"

  1. I didn't mean to "Gore anybody's Ox.

I get it, you don't want to learn.

  1. There are more than "many" ways to skin the "cat"

Do any others include holding untrue beliefs about other methods? Ones that hold the believer back?

  1. I'm suspecting that just a few have actually looked at the code.

Really? Was that anyone who commented on the code or about something completely else?

  1. Some are fixated on cramming "schedulers" into a $6.99 UNO when the MEGA at $12.99 equals 3 or 4 UNOs

Not me, I think it's a waste of program space and cycles.
The Mega2560 only has one core just like the Uno.
Prices you show are for knock-offs and if you shop a bit, you can find cheaper knock-offs.

  1. Alright, I concede your "preference" to preserve Timer1 ( on a MEGA w. 3 more?) for some other need.

So nice of you especially when you can't see that advant errrr need..

  1. I'm still trying to figure out how the millis() can count up 'forever' without eventually overflowing and
    going thru "zero" - unsigned or not, and I don't care how "long" the "long" is.

It's real, it works, I posted a sketch that demonstrates it, I have an 8 bit version too, no rollover.

  1. I'm going to go out on a "limb" here - my example runs faster, just count the instructions taken.
    ( and last )

How would you know?

  1. You will not "HURT" my feelings if you find my code without merit and never USE IT !
    Thanks for your interest. Happy New Year !! :slight_smile:

Don't mind me. I was trying to rescue a closed mind that I saw hurting itself.
What I posted is for anybody to read and may still help other members lost in the same fallacy.

vbextreme:
TOPIC: can we do multitasking?
YES! Arduino permits, or they attempt to make them do. But it is an advanced concept, you have to first investigate whether it is really necessary, not as a call to millis()

P.S. I will be happy only when I stop to see threads on BlinkWithoutDelay

You refuse to find out the simple way so it's "an advanced concept"?

w00t!

Let's look at an analogy. Say you want to cook breakfast. You need to cook:

Coffee - takes 1 minute
Bacon - takes 2 minutes
Eggs - takes 3 minutes

Now a seasoned cook would NOT do this:

Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.
Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.
Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.

The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).

In computer terminology this is blocking. That is, you don't do anything else until the one task at hand is over.

What you are likely to do is this:

Start frying eggs. Look at watch and note the time.
Glance at watch from time to time. When one minute is up then ...
Start cooking bacon. Look at watch and note the time.
Glance at watch from time to time. When another minute is up then ...
Put coffee on. Look at watch and note the time.
When 3 minutes are up, everything is cooked. Serve it all up.

In computer terminology this is non-blocking. That is, keep doing other things while you wait for time to be up.

Yup, advanced... but simple. At least what you can do with it runs from dead simple to very advanced.

I'm locking this thread because: first, it is old and starting to wander. Second, the name of the OP is offensive. That way it can sink into oblivion.