Pfth Forth => How to deploy multiple cogs
LoopyByteloose
Posts: 12,537
Hello all,
This is a recent revision of this HOWTO document as the previous were imperfect.
Of course, one thing always seems to lead to another and now that I can get multiple cogs working well, this begs the issue of actively passing variables and state information between the cogs.
In some cases, migrating data into and out of the active serial terminal would be very useful.
All that needs another HOWTO. But I am sure it can be done.
This is a recent revision of this HOWTO document as the previous were imperfect.
Of course, one thing always seems to lead to another and now that I can get multiple cogs working well, this begs the issue of actively passing variables and state information between the cogs.
In some cases, migrating data into and out of the active serial terminal would be very useful.
All that needs another HOWTO. But I am sure it can be done.
Comments
Loopy,
Thanks for the write up. I have a slightly different perspective on the cogs that are used by pfth at startup and have a slightly different way to keep track of cogs my code starts (as opposed to built in code).
When I first started using pfth, I used the basic version without any of Dave's options (e.g. no SD Card, no Linux support). I wrote a couple of words that I could run either in a new cog or not, depending on how I chose to start it. To make that work, when I start the word in a new cog, I save the value that is returned by COGNEW into a variable tied to the started word (cognum_xxx) and also print a message on the terminal.
That showed me that the basic vanilla pfth operates from cog 0. (The first started newcog had a value of 1, and I would use '1 cogstop' to stop execution on the word.)
When I began to use pfth with SD support, I noticed that cognew returned 2 for the first used new cog. So the version of pfth that you use does affect which cogs are available.
To stop code, I use the variable cogid_xxx (where xxx is a specific id for the word that is using the cog) and cogstop. I can do that either manually from the keyboard or from inside the word.
I like your method of using COGID from inside the word, but will have to use it carefully since some of my words can run either in the main cog or in a new cog, and I only want to stop the new cog.
The code below gets values from a Bluetooth device and uses them to control the intensity of the R B and G channels of an RBGLed. It has the option of either running in the main cog or running in its own cog. The RBGLED code runs in a separate cog because of the required refresh rate using one counter to run the three colors. So this can start either 1 or 2 cogs. (One reason why I start the BT code in its own cog is so that I can interact with the program from the PC keyboard and terraterm while using an android device with BT to control the colors.)
The last line of code (gobtrgb) is called to start the BT code in the main cog. The line above that (gobtrgbcog) starts the BT code in a new cog. GO1COG starts RBGLED in a new cog. The last 5 lines of BLUERBG stop the RBGLED cog and test to see if BT was started in a new cog. If so it stops that cog also.
Other info about the BT program: rv, bv, and gv are words defined elsewhere that take values 0 - 9 and use them to derive the FRQA value for the intensity of the Leds. Those three words store the calculated FRQa in variables RVAL, BVAL, and GVAL used by RBGLED. RGBLED only reads xVAL and the xV words only write to it.
Tom
In my previous post, I forgot to mention that when I start the BT code in its own cog, I can use the terraterm terminal (as well as the BT device) to also call RV, BV, and GV. (e.g. 8 rv 0 bv 7 gv will change the color of the Led to yellow). I also have 3 words that allow me to enter the value of FRQa into RVAL, BVAL, or GVAL directly from the keyboard while RBGLED is running in its own cog. During calibration and debugging I used that method to determine what base value of FRQA I needed for each color to give a full range of intensities for each color.
I use separate variables for storing values to and for fetching values from the other cog (and in that cog I do the reverse). It uses more variables than the Forth police would like, but it works.
I would like to find out if there is a way to print to the teminal directly from a word running from a new cog, rather than having to transfer data via variables just to print them.
Tom
Since the issue of which Cogs remain available exist, I tend to use CogNew, tend to avoid CogInit and let the Propeller allocate empty Cogs as it sees fit. Then the CogID CogStop sequence inside the code called, cleans up. The result is simple less dictionary entries to create.
This may not be the Only way, nor the best in some instances... but the HOWTO was written for new users that have yet to get their creative juices flowing.
I suppose it is already in need of a rewrite to deal wth the issue of the SDcard taking a cog at startup.
Feel free to use my HOWTO as a style sheet and create your own HOWTO pass variables between Cogs and in and out of an existing active Terminal.
Feel free to edit the titile as well if so inclined.