Pages: [1] 2   Go Down
Author Topic: blink 1.05  (Read 2851 times)
0 Members and 1 Guest are viewing this topic.
West Des Moines, Iowa USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This sketch introduces new versions of the scheduling functions which have been moved into the subs.ino file/tab, and adds a print() task loop. You'll need to open the serial monitor to see it working. The LED blinks at 2Hz, and the print() function runs at 3Hz. You can see this syncopation by watching the on-board LED blinking at one rate while the transmit LED blinks at the other.

I couldn't find any way to make a gentle transition from blink104 to blink105, and anticipate a lot more questions - but at this point we have a scheduling "infrastructure" capable of supporting a fairly large number of tasks...

* blink105.ino (1.89 KB - downloaded 61 times.)
* blink.h (1.7 KB - downloaded 46 times.)
* subs.ino (5.56 KB - downloaded 51 times.)
Logged

There's always a better way!

USA
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This looks great, but of course, I have questions smiley

1) It looks like time_t is a 64bit impl of usec, not msec, right?  I don't need the accuracy of usec at this point, do you have a similar struct, etc. for msec, or am I just dead-wrong here?

2) I see you have arrays holding queued tasks.  A set of helper functions to somehow "cancel" a task and/or to reset the time on a specific task would be a great addition!
For example: I would like to use the aftr() to set an "alarm" to occur iif an event doesn't happen in the meantime.  If said event were detected, reset the aftr-time to an additional delay.

Awesome stuff.
-AJ
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4703
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tasking. It's almost like an OS. And then Micro$oft will want to take over. You know, Windows ain't done till Arduino won't run.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

West Des Moines, Iowa USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

AJ - It's an easy change: just change the call to micros() to call millis() instead.  :-)

I was originally going to use millis(), but then realized that once I'd expanded to 64-bits there'd be no upside to millis() - and since I was paying the price, I might as well have all the benefits to be got. Hmm - in addition to changing the call, you'd probably want to update the conversion macros in the header file (NBD).

I thought about adding a cncl() capability, but don't need it for my application (which may very well be the only one I ever tackle with an Arduino) so decided to leave that for anyone who needs it and/or is willing to spend the time. Where I have a subtask that might need to be cancelled, I just set a flag so that when it's invoked it simply says "I'm done", cleans up its internals, and gives control back.

I meant to add: The task queue only starts out as an array because "array of struct" is supported by C while "singly-linked list of n elements" is not. You probably noticed that I hid a one-time initialization loop to effect that conversion in the schd() function.

GFS - This is a long, long way from an OS, and it's probably safe from that particular portion of the "Dark Side". AFAICT, MS is still struggling to understand interrupt-driven software.   smiley-mr-green

Edit: added array/list afterthought
« Last Edit: April 13, 2012, 10:17:34 am by Morris Dovey » Logged

There's always a better way!

USA
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I took the weekend off, but thought about this a little more.

I guess I need to be able to do some basic math with the "enhanced time" you created ("time_t"), though the scheduling "feature" you've already built already does a lot of what I might need.

I don't know that I can do it with the struct.  I know in C++ you can overload operators if you use a class.  Do you know if I can do that in the C/C++ subset available to the Arduino?  If so, is the thought that building-out such a class (instead of the straightforward struct you have) will waste precious RAM or something?

EDIT: Maybe I just haven't worked with C structs in such a long time, because you do actually illustrate math in your examples.  Are you saying that the struct is "packed" in such a way that the two, 32bit ulongs act like one, 64bit ulong if you just perform math on the struct as a whole?  Like would this work...?
Code:
time_t x = now();
x += ULONG_MAX; //add roughly 50 days if struct is millis
// This wouldn't overflow or anything, and my variable "x" now is today + 50days (or whatever the actual ULONG_MAX equates to)???

Thanks for the help.
-AJ
« Last Edit: April 16, 2012, 04:17:14 pm by AJ Weber » Logged

West Des Moines, Iowa USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

<grin> Take another look and distinguish carefully between 'struct' and 'union'.

I suggest that you don't do anything with the struct, and instead just work with the 64-bit time_t value returned by now().

The union allows me to tell the compiler to force the time_t value and the struct containing the two longs to occupy the same memory space. That lash-up allows access to the entire 64-bit time as a single unsigned long long variable, or to access either the upper or lower 32-bit value as an unsigned long, which makes adjustment very much easier when whichever time source overflowed.

Whether anything is "wasted" depends on what you need. The minimal code I posted is for people to hack on to suit their own needs. I was fairly well pleased to shrink the executable part as far as I did - and I'll be really pleased if anyone can show me how to shrink it further.   smiley-mr-green
Logged

There's always a better way!

Offline Offline
Sr. Member
****
Karma: 1
Posts: 462
I am a amateur.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What is the difference between schd() and aftr()? Is there a function for...
1) Executing a function X milliseconds after it is called, without conflicting with the loop:
Code:
//...
void blink(){
  static boolean output = 1;
  digitalWrite(13, output ^= 1);
}
void loop(){
  callAfter(blink, 250);
}
2) Executing a function, then "wait" X milliseconds before doing it again.
3) Being able to terminate functions, or execute it X times, then stop [forever].
Logged


Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4703
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice and clean. It's like recursion without having to go back.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Sr. Member
****
Karma: 1
Posts: 462
I am a amateur.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice and clean. It's like recursion without having to go back.
What do you mean?
Logged


Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4703
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In recursion each call has a return.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Sr. Member
****
Karma: 1
Posts: 462
I am a amateur.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you talking about schd() or aftr()? If one of them is
Quote from: GoForSmoke
Nice and clean. It's like recursion without having to go back.
then what is the other one?
Logged


Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4703
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

They are both nice and clean. Have you written any recursive routines before? I don't mean it's exactly like recursion, just allows recursive-like functionality without loading up the stack.


Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Sr. Member
****
Karma: 1
Posts: 462
I am a amateur.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So, they are both the same? Is it possible to stop and continue the functions at will?
Logged


Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4703
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know what 'same' you refer to. I look at the code and see ways to use it that remind me of recursion. My explanation comes from what I know, what I have done. Your mileage may vary.

If you make your code edit the event queue you can stop/continue/change events. If you so desire then you have the source and can add functions, part of the power of code.  OTOH you can put a flag check in the function(s) you will schedule and on condition not execute the function.

Code language is like an alphabet to write novels with. The story is up to the author.

BTW; RIP Ray Bradbury, your works did inspire many.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Sr. Member
****
Karma: 1
Posts: 462
I am a amateur.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

By "same", I mean that if I replace aftr() with schd() in my code, there is no difference. I wanted to know how to use each function, and which function is best for what situation.
Logged


Pages: [1] 2   Go Up
Jump to: