Shop OBEX P1 Docs P2 Docs Learn Events
Having Trouble passing parameters — Parallax Forums

Having Trouble passing parameters

gdrowellgdrowell Posts: 7
edited 2011-04-21 07:30 in Propeller 1
Hello All,

I am having difficulty passing information from two slave cogs back to the main cog. My code is as follows:

CON
high = 1
low = 0

VAR
long stack[30]
long stack2[30]
long stack3[30]

PUB Main
Coginit (1, Task1(5, 5, 2) , @stack2)
Coginit (2, Task2(3, 2, 6) , @stack3)

dira[16]~

**
if Task_1_finished_flag == Task_2_finish_flag
outa[16] = high
**
PUB Task1(a, b, c) : Answer1 | Task_1_finished_flag

Answer1 := a + b / c
Task_1_finished_flag := 1

PUB Task2(d, e, f) : Answer2 | Task_2_finished_flag

Answer2 := d - e * f
Task_2_finished_flag := 1



I am trying to get a LED light to turn on once all operations are done in the 2 cogs doing the simple arithmetic. Any direction or advice would be helpful. Thanks in advance

p.s. The ** area has syntax errors.

Comments

  • John AbshierJohn Abshier Posts: 1,116
    edited 2011-04-19 13:24
    Task_1_finished_flag and Task_2_finished_flag are local to their tasks. Make them global vars. Another note: Using coginit instead of cognew is frowned upon. Also I don't think you will ever see Answer1 or Answer2.

    John Abshier
  • gdrowellgdrowell Posts: 7
    edited 2011-04-19 13:35
    Mr. Abshier, i appreciate your input. I changed from coginit to cognew. However, I am curious as to how I would see the answers 1&2 from cog 0. Is there something I am leaving out, (note: I am extremely new to the propeller) Thank you so much again.
  • John AbshierJohn Abshier Posts: 1,116
    edited 2011-04-19 14:06
    I don't know what it is you really want to do. In main you start a cog with either cognew to run Task1. That line returns the value from the cognew instruction, not the return value from Task1. Task1 does the arithmetic, sets the flag and since it has no more code the cog shuts down.

    John Abshier
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-04-19 14:09
    Answer1 and Answer2 are return values. Return values only work with usual function calls and not with COGNEW. You could propably find it on the stack but that's a hack!

    You should make Answer1 and Answer2 global variables as well. Every function in the same file has access to the VARs. To make it more flexible you could also pass the address of an Answer variable to the task function.
  • gdrowellgdrowell Posts: 7
    edited 2011-04-19 14:22
    I am in need to know how to program the propeller to do simple arithmetic between multiple cogs and report it back to a master cog. It starts with the master cog sending out a set of numbers, then (at least two) cogs would do some simple math (cog 2 would do addition of the numbers then divide by 3; cog 3 would subract the numbers than multiply by 3) then report the answers back to the master cog. The master cog would then take the average of the two reported answers from cog 2 and cog 3. Any help with programming this would be superb. Thanks in advance.

    This is an overview of my project . . . Thanks.

    Also, thanks MagIO2 . . . .I'll try that and get back to you. Thanks a bunch
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-04-19 14:51
    Is this just for learning how to start COGs and "communicate" with it, or is it for a real program?

    Why I ask?! Because starting a COG for doing such simple things is meaningless. Start time is simply to long compared to the execution time of the task itself. And if COG0 has nothing better to do than wait for the results it could have done the job by itself faster ;o) So, usually for repetitive tasks COGs are started and wait for a command from the master. In this way you don't have the startup-time.

    By the way ... your if statement should be a

    repeat until Task_1_finished_flag and Task_2_finish_flag

    otherwise the master does not wait for the results.

    And last but not least, after you set the output to high you should have an endless repeat loop, otherwise the COG0 will be stopped, which will disable the outputs of that COG.
  • gdrowellgdrowell Posts: 7
    edited 2011-04-19 15:03
    This is actually for both. I am trying to use multiple cogs for means other than blinking LEDs. I do understand that one cog is well enough to do the operation, but it is cool to know that multiple cogs could be used to do multplei things with interruption. That is the basis of my project.

    By changing the if statement, should it be

    repeat
    if Task1_finshed_flag && Task2_finished_flag
    ! outa[16]

    or do i still keep separate?
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-04-19 15:10
    As MagIO points out, your task_finished flags need to be global for the main method to see them. As locals, they can't be seen outside the method where they're declared, and they get clobbered as soon as the task finishes and the cog unloads.

    This may be helpful:
    -- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp10.pdf
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-04-19 15:27
    I can't help you with the syntax (too many new languages running through my head at the present) but I can help with the concept. As mentioned above, a task (routine/thread/process/etc) started on a COG doesn't return anything to the COG that started it as a function call would in a language. A COG is pointed to some code, which it will run until it hits the end or is stopped in some other way. The only way the COGS can really communicate or pass data back and forth is through global variables (ok, there are probably other ways but for now, it's global variables).

    COG 0 starts another piece of code in another COG to do some task and goes on its way. If at some point the code COG 0 is running needs to check on the work the COGs it started are doing, it needs to check a global variable - did a change from 1 to 2? sit on a global variable in a repeat - did this variable get set to true yet? The communication between independent code paths needs to be coordinated by the programmer. You need to set up the communication method (variables, flags, semaphores, interrupts, whatever your hardware and software supports). In propeller-land, it's global variables for a nice clean way to do it.

    The repeat that was suggested by MaglO2 is that type of arrangement within your code. COG0 code is waiting for both of the "finished" flags to be set to true by the other COGS that were started. It just sits and waits....it could be waiting on math...a servo to be moved into position....a character to come in from a serial pin.....anything your sensors desire but in the end, the code in the other COG needs to set a global variable to something the COG0 code understands as a signal.

    Multiple processor communication is wickedly fun!!
  • gdrowellgdrowell Posts: 7
    edited 2011-04-19 18:31
    Thanks alot mindrobots . . . and JonnyMac. So wherever the variable changes ( or gets a value) globally, i can see that change anywhere, regardless of which method it is in? (ex. Answer1 has a value change in PUB Task1 . . . so I can see the change in PUB Main if i called on the variable Answer1?). Thoroughly agree with you too, mindrobot multiple processing is really cool.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-04-19 23:01
    If you want two or more cogs to have direct access to a variable you have to make the variable global. Any other configuration means indirect access which requires you to create a messaging scheme.
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-04-20 04:06
    BTW ... what is stack good for?

    You have an array named stack which is not used. The main COG does not need a stack array. The compiler takes care that COG 0 always has the whole rest of HUB-RAM as stack-space. "whole rest" means all memory which is not used by VAR/DAT/PUB/PRI - the free RAM reported when clicking "View Info" in the Propeller Tool.
  • RS_JimRS_Jim Posts: 1,768
    edited 2011-04-21 07:30
    gdrowell,
    Boy do I really relate to your problem! I raised this question in this threadhttp://http://forums.parallax.com/showthread.php?128922-Passing-Memory-Address-I-am-stumped! toward the bottom Jonny-Mac attached version 2 of etimer that finally gave me the insite i needed to understand using global VARS. I used v2 and am passing the timer var to 3 different cogs that are reading the "master clock" I also am passing several other arrays and pointers from the top object to multiple cogs.
    Jim
Sign In or Register to comment.