Flashing an Multitasking

Started by psyclopedia January 12, 2006
I've picked up a couple of RGB LEDs to play with recently. Man, these
things are really fun. I'm learing a bunch about what = what when
mixing colors.

On to the point.

I would like to flash one of the LED colors at some interval while
simultaneously running another piece of code. As I've never done any
work with multitasking, is that what must be done here? I need to
flash in software rather than hardware, so external components are not
an option. There's obviously a timing issue to be aware of as well.

Could someone point me in the right direction?

Don


> ... I need to flash in software rather than hardware...

At what rate? Tom


3 different rates. Slow (0.5Hz), Fast (0.2Hz), and always on.
There's a catch though.

As I am using RGB LEDs, each color is tied to an output pin (common
cathode). In order to flash the color yellow, for example, both the
green and the blue pins must flash simultaneously. Depending on the
color, 1, 2 or all 3 segments of the LED may or may not be on at any
given time. Or perhaps the LED is showing a non-flashing yellow, in
which case both the blue and green segments are on constantly.

At the same time, Com1 is outputting data (debug.print), and I am
sampling voltages via GetADC on one of a possible 4 different pins.

I'm leaning towards multitasking. I think that with such slow
flashing, a few milliseconds one way or the other won't make a difference.

-Don
--- In basicx@basi..., Tom Becker <gtbecker@r...> wrote:
>
> > ... I need to flash in software rather than hardware...
>
> At what rate? > Tom
>




> ... I'm leaning towards multitasking.

Yes, this is a job for multitasking, I think.

You're right that the pin timing will vary by a BX-24 tick or two as
tasks are switched so, if you can tolerate 5mS of jitter, dividing the
different time periods into tasks will simplify the solution, I'm certain. Tom



Thanks fo the input Tom. After reading through the docs, I think this
multitasking thing isn't as difficult to impliment as I had imagined.

-Don --- In basicx@basi..., Tom Becker <gtbecker@r...> wrote:
>
> > ... I'm leaning towards multitasking.
>
> Yes, this is a job for multitasking, I think.
>
> You're right that the pin timing will vary by a BX-24 tick or two as
> tasks are switched so, if you can tolerate 5mS of jitter, dividing the
> different time periods into tasks will simplify the solution, I'm
certain.
>
>
> Tom
>




I have both: positive and negative experience with multitasking.
Please take into consideration the following things:

1. Multitasking is finicky, so be patient.
2. Debugging is rather complicated.
3. The worst problem is the size of the tasks' stack. If it is too
small - it will overflow and may overwrite some variables without any
warning. If it is too big - it will not fit into the RAM. Do not plan
to have more than 2-3 tasks, if you need more then consider ZBasic.
4. Since the code of the tasks is stored in their stacks, make all
tasks as small as possible, keep all logic in procedures.
5. Watch for all possible hardware conflicts, use semaphores and
locking to avoid them.
6. Use locking if you need to complete certain activity without a
risk to be interrupted in the middle of it.

-Yuri --- In basicx@basi..., "psyclopedia" <psyclopedia@y...> wrote:
>
> Thanks fo the input Tom. After reading through the docs, I think
this
> multitasking thing isn't as difficult to impliment as I had
imagined.
>
> -Don > --- In basicx@basi..., Tom Becker <gtbecker@r...> wrote:
> >
> > > ... I'm leaning towards multitasking.
> >
> > Yes, this is a job for multitasking, I think.
> >
> > You're right that the pin timing will vary by a BX-24 tick or two
as
> > tasks are switched so, if you can tolerate 5mS of jitter,
dividing the
> > different time periods into tasks will simplify the solution, I'm
> certain.
> >
> >
> > Tom
> >
>




> 1. Multitasking is finicky, so be patient.

Perhaps particular programming invites finicky behavior, but the
mechanism works well if used well. I have not found debugging
difficult; treat each task independently, then in concert. Tom



--- In basicx@basi..., "Yuri Bernikov" <ybernikov@y...>
wrote:
> 4. Since the code of the tasks is stored in their stacks, make all
> tasks as small as possible, keep all logic in procedures.

Actually, code isn't stored on the task stacks. The task stacks are
used for the following:

- local variables defined in the procedure
- temporary space used during expression evaluation
- the "activation record" used for calling and returning from
subroutines/functions

As as been described in this forum before, you should reduce or
eliminate the use of strings, especially local variables that are
String type. It helps to reduce the default string size or use
BoundedString types and use the smallest possible string size.

If you look at the code generated for the evaluation of an
expression you may be able to find ways to rearrange the expression
or simplify it to reduce stack usage.

Also, you can "flatten out" the structure of the application,
favoring in-line code over calling a subroutine or procedure to do
the work.

Use Mike's bxDism (http://home.austin.rr.com/perks/micros/bxDism)to
get an understanding of which procedures are using the most stack
space and concentrate on reducing stack use in those. Pay special
attention to the extra procedures that are quietly added to your
program due to use of System Library routines. These are often some
of the major consumers of stack space.

You'll want to study your code to see if there is an alternate way
to accomplish the same objective that uses less stack space. Again,
bxDism is useful in this effort.

Don


Thanks very much for the insight. I do have a question though.

As I am a novice at multitasking, let's see if I can describe this
correctly.

We start at Sub Main() and perform a few tasks. Main() calls Sub
Display(). Display() retrieves some analog voltages and lights up
some LED's depending on the retrieved value. Now, Sub Display() loops
continuously, constantly retrieving analog values and updating the
display. At some predetermined value, one of the LEDs should be
blinking at rate X.

Am I correct in thinking that both Display() and Blink() subs should
each be seperate tasks?

Also, within Display(), other subs are called to perform specific
tasks such as the state change of the various output pins. This could
be converted to inline code, but it would bloat the program size a bit.

I guess the question is, is it OK to call a sub that isn't defined as
a task from within task.

-Don

ps I have downloaded bxism and it's a very good tool for determining
all of these little stask gremlins.

--- In basicx@basi..., "Don Kinzer" <dkinzer@e...> wrote:
>
> --- In basicx@basi..., "Yuri Bernikov" <ybernikov@y...>
> wrote:
> > 4. Since the code of the tasks is stored in their stacks, make all
> > tasks as small as possible, keep all logic in procedures.
>
> Actually, code isn't stored on the task stacks. The task stacks are
> used for the following:
>
> - local variables defined in the procedure
> - temporary space used during expression evaluation
> - the "activation record" used for calling and returning from
> subroutines/functions
>
> As as been described in this forum before, you should reduce or
> eliminate the use of strings, especially local variables that are
> String type. It helps to reduce the default string size or use
> BoundedString types and use the smallest possible string size.
>
> If you look at the code generated for the evaluation of an
> expression you may be able to find ways to rearrange the expression
> or simplify it to reduce stack usage.
>
> Also, you can "flatten out" the structure of the application,
> favoring in-line code over calling a subroutine or procedure to do
> the work.
>
> Use Mike's bxDism (http://home.austin.rr.com/perks/micros/bxDism)to
> get an understanding of which procedures are using the most stack
> space and concentrate on reducing stack use in those. Pay special
> attention to the extra procedures that are quietly added to your
> program due to use of System Library routines. These are often some
> of the major consumers of stack space.
>
> You'll want to study your code to see if there is an alternate way
> to accomplish the same objective that uses less stack space. Again,
> bxDism is useful in this effort.
>
> Don
>




--- In basicx@basi..., Tom Becker <gtbecker@r...> wrote:
>
> > 1. Multitasking is finicky, so be patient.
>
> Perhaps particular programming invites finicky behavior, but the
> mechanism works well if used well. I have not found debugging
> difficult; treat each task independently, then in concert. > Tom
>

Thanks, Tom.

I agree that the mechanism is reliable and works fine when the code
is properly done. When I said that "multitasking is finicky" I wanted
to warn that the documentation may give a false impression of over
simplicity. My first project with BasicX was the Pool Heater control
board. I was very inspired by the example given in the documentation
and designed a program with 7 tasks. Needless to say, that it never
worked in its original design. After fighting for a few days
with "everhanging" tasks I realized that BX24 just does not have
enough RAM for the stacks, so I converted all of them into procedures
that are called sequentially in a big loop. After this change I was
able to start what can be called "a productive debugging". I've done
another project where the multitasking is used for interruptions
handling. This time it succeeded, though I spent a lot of time
figuring out the proper size of the stack and resolving issues with
hardware conflicts.

-Yuri