can update the variable without any further interaction with
the “foreground” program. I told you this was cool stuff.
Here’s what this boils down to for us regular folks: We
don’t have to learn assembly to get background processes
running! How cool is that? With eight cogs at our disposal,
the world is brand new and wide open for just about anything
we can imagine. I can tell you in all candor that I’ve been
operating on a lot less sleep now that Spin has kicked in
and started making sense; I’ve got 12 years of BASIC Stamp
programs that I’m reviewing and porting to the Propeller.
Okay, let’s have a look at the “foreground” program
(top level object) that takes advantage of rctime.
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
LCD_PIN = 0
LCD_BAUD = 19_200
LCD_LINES = 2
POT_PIN = 1
lcd : “debug_lcd”
pot : “rctime”
if lcd.start(LCD_PIN, LCD_BAUD, LCD_LINES)
if pot.start(POT_PIN, 1, 1520, 642, @potVal)
waitcnt(clkfreq / 5 + cnt)
As you can see, it’s actually quite simple. We’ll use a
Parallax serial LCD as our output device. If you prefer the
SEETRON BPI-216 display — no problem. I’ve included an
object called Debug_BPI-216 that has the same methods as
Debug_Lcd; all you have to do is change the baud rate to 9600
and the lcd object file; everything else is handled internally.
Look carefully at the repeat loop after the pot.start
method is called. Notice how we don’t ever have to use the
pot.rctime method? We don’t because the rctime method
is running in its own cog and taking care of things automatically. And no, we don’t have to worry about attempting to
read potVal from the main program while rctime is updating
it; the Propeller hub allows only one cog at a time to access
the main system RAM, so there won’t ever be a collision.
Before we wrap up this section, you may be wondering
about the values 1520 and 642 for the zofs and div param-
16 June 2006
eters. These values were derived empirically in three steps.
The first step was to run the program with 0 (zofs) and 1
(div). I found on my setup that this returned a value of 1520
when the pot was turned to the zero position. Where
does this come from? Instruction overhead and the small
discharge delay caused by the 220-ohm resistor.
The next step is to insert 1520 into the zofs parameter
and run the program again. The zero position should now be
zero. Now we can turn the pot to the max position and note
the output. In my case, it was about 64125 (with some small
variation due to breadboard noise). I decided I wanted my
pot to read 0 to 99, so I used 642 as the divisor. Step number three is to check it — bingo, the pot now reads 0 to 99.
STACKING IT ALL UP
Okay, there is one critical technical detail that we have to
address before calling it a wrap this month. When a Spin
program is running in its own cog, it needs a section of dedicated RAM — called a stack — to keep track of intermediate
values (i.e., used during expression evaluation). Until the
Propeller, determining proper stack size required a bit of luck,
if not outright magic. Some time back, I was working with a
small device that was multi-threaded, and the guidance for setting the stack for a new thread was to start big, then reduce
the stack size until the thread crashed. Mmmm, I just didn’t
feel quite right doing it that way. So why not just make the
stack big and forget about it? Because it’s a waste of space,
and even with all the memory available in the Propeller, it is
still a small controller and we should use memory wisely.
Good news: We can use one of the Propeller’s cogs to
determine the stack usage of another object. Now, I wish I
was clever enough to have come up with this, but I’m not.
I am clever enough to put it to use, though, and so are you,
so keep this handy for when you start developing multi-cog
projects. Included in the files is an object called
stack_mon-itor.spin. This was created by a very sharp guy named Phil
Pilgrim. Perhaps Phil’s name doesn’t ring a bell, but his work
will. As a long-time friend of Parallax, he’s created some
very interesting products including the M&M sorter, the
color sensor AppMod, and recently, the Scribbler programming GUI. Phil brings his considerable programming skills
to the Propeller and some really neat things are happening.
The stack_monitor is one of those objects that runs
in its own cog; this allows it to keep tabs on a chunk of
memory that another object is using as its stack. It must be
installed (with its own start method) in the start method of
the object that has the stack, providing the location of the
stack, its size, and the MSB and LSB pins (connected to
LEDs) that will provide stack usage output.
Here’s how to install it into the rctime object as the first
line in the start method:
stackmon.start(@stack, 32, 23, 16)
This points the array called stack that has an initial size
of 32. I’m using the Propeller Demo Board which has LEDs
on pins A23..A16, so that’s what I’ll use as outputs. Now we
go back to the top object and rerun it. On my system, LEDs