Shop OBEX P1 Docs P2 Docs Learn Events
Programming Fundamentals: Passing variable data between objects (Sony IR decode) — Parallax Forums

Programming Fundamentals: Passing variable data between objects (Sony IR decode)

SteveWoodroughSteveWoodrough Posts: 190
edited 2010-06-13 03:46 in Propeller 1
I've read and studied, and I think I should know how to do what I want, but I can't.

I'm trying to use the Sony IR decoder to decode and IR signal from my Sony Remote.

The Sony IR object works just fine so my signal and circuit are verified.

What I'm trying to do is write a parent object that references the Sony IR object then looks at the message result and then does some operation.· For now that is as simple as lighting and LED and later that will become running a servo.·

My parent object works to the extent that I call the SonyIR object and it decodes and sends messages to the PST.·

What I cannot get to work is "reading" the value of a global variable in the child object.

Here is the meat of the "code":· Full version attached.

Thanks for your help!
Steve

OBJ
· SonyIR : "Sony_IR_Decoder"· '
Pub Main | y····················· 'define Y as local variable
· dira[noparse][[/noparse]10]~~····················· 'Set p10 to output
· outa[noparse][[/noparse]10]~~····················· 'verify LED Lights
· waitcnt(clkfreq +cnt)·········· 'wait 1 second
· outa[noparse][[/noparse]10]~······················ 'turn off led
·· Repeat
··· SonyIR.init·················· 'Gets and decodes signal from Sony IR remote
································· 'This works as designed and displays message
································· 'on PST just fine
··· y:= SonyIR.GetMessage'(@message) 'THIS IS THE PART I'm having trouble with.
··································· 'I want to set y to the value of message
··· if y >= 5··················· 'When I compile with the (@message) I get an error message
······························· 'without the (@message)
······························· 'How do I "see" the value of the global variable
································· '"message" used in the SonyIR object?
····· outa[noparse][[/noparse]10]~~················· 'turn on LED if the value of message is > 5
····················· 'The idea is that if I press 1 -4 there is no LED
····················· 'If I press 5 - whatever I should get a light
·····
····· waitcnt(clkfreq +cnt)······ 'wait 1 second
····· outa[noparse][[/noparse]10]~·················· 'turn off LED


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Recent Project Videos:

http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

Cool Cars:
http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-31 14:47
    You can't access the variables of an object from outside the object. If you need access to a variable, you need to add a method to the object that either sets the variable to the value of its parameter or returns the value of the parameter like:
    PUB setVariable(value)
       variable := value
    
    PUB getVariable
       return variable
    



    I looked at your "Sony_IR_Decoder". The GetMessage method just stays in a REPEAT loop and never returns.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-05-31 16:23
    Thanks Mike, I'll give it a try.

    I assumed that since "Message" is a global variable defined in the Sony_IR_Decoder.spin object that the value of message is accesible to all objects. I guess that is not the case. I can imagine what kind of nightmare might ensue if duplicate variable names exist among objects. So, to that end I thought I would be able to specify that I want the value of the variable "message" contained within the Sony_IR_Decoder.spin object referencing SonyIR.GetMessage(@message). It's clearly wrong but does my logic make sense?

    I also assume that I need to add the methods you describe to the child object Sony_IR_Decoder.spin. and call the getVariable method from the parent object LED Control with Sony IR Remote.spin .

    Let me give it a try and report back.

    Thanks
    Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • bill190bill190 Posts: 769
    edited 2010-05-31 16:57
    Search the forum here for the words "parameter" or "parameter passing".

    Other terms which are used elsewhere are "argument" or "return value", but I've not seen those terms used here much.

    This is difficult to understand at first. Also you might want to look at objects in the object exchange or in your library which have optional parameters. Like FullDuplexSerial.spin has parameters for baud rate and so forth.

    And be aware when·using the @... "Symbol Address Indicator: used immediately before a symbol to indicate the address of that symbol is to be used, rather than the value at that symbol’s location."

    So play around with using @ and not using it and see what happens.

    I like to include the FullDuplexSerial.spin·object in the program I am working on, then display the values of things on the Parallax Serial Terminal screen.

    I use these...

    CON
    ······· _clkmode = xtal1 + pll16x
    ······· _XinFREQ = 5_000_000

    OBJ
    · ·Debug : "FullDuplexSerial"

    Then in the program area...

    PUB Start

    Debug.start(31, 30, 0, 38400)

    waitcnt(6_000_000 + cnt)
    Debug.str(string("Testing.... "))

    (Above wait gives you time to switch to the terminal.)

    This would display the value of a variable I was using called "tenthsec" in decimal...

    Debug.dec(tenthsec)



    Object exchange...

    http://obex.parallax.com

    The Propeller library can be found in the C:\Program Files\Parallax Inc\Propeller Tool area.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-05-31 17:52
    I appreciate everyones input but I'm galactically confused over what should be a simple matter.·

    I tried to follow Mike's instructions, but to no avail.· Attached is the Object I wrote:

    LED Control with Sony IR Remote.spin

    and a slightly revised version of a OBEX object:

    Sony_IR_Decoder.spin

    The entire purpose of this exercise is for me to learn how to take existing OBEX items and apply them to some task in conjunction with other objects.·

    I've read and re-read the Lab Fundamentals on this matter but I'm still not able to apply the principles.·

    I tried the @ method in almost every combination and permutation I could imagine with no luck.·What am I mising?·I'm sorry to ask folks to code for me but I'm at that point.· What should I write and where?···

    Thanks again for your help.

    Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • bill190bill190 Posts: 769
    edited 2010-05-31 20:40
    I·intended to say don't use @ and then use @ and notice the difference.

    So try NOT using @ and see what happens.
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2010-06-01 00:08
    Hi, Steve,
    You said...
    The entire purpose of this exercise is for me to learn how to take existing OBEX items and apply them to some task in conjunction with other objects.
    That's a commendable way to build your skills and thanks for sharing your purpose.· However, your particular task at hand might be frustrating (though also·enlightening).··It seems that you've·chosen the wrong objects to modify or work with to build such skills, as I'll elaborate on below.· On the other hand, in the end, perhaps that will allow you to learn more deeply (if it doesn't kill you first).·

    In particular, it seems to me that·the Sony_IR_Decoder program that you're trying to springboard off of appears to be written as a top-level object, such as a demo program for a tv driver, etc.· As Mike mentioned, it has an infinite loop in it, and that would seem to be a deal-breaker for what you're trying to do without significant restructuring.· I believe that when your program calls Init, control will never be passed back to your program because the Init·method in the Sony program calls GetMessage, and GetMessage is an infinite loop.· Hence, control is never passed back to Init from GetMessage, so Init never fully finishes (though its first 2 lines do), and since it never finishes, control is never passed back to your program that started the ball rolling.· So, even though you have a repeat loop, it never even finishes once, if I'm correct (Disclaimer:· I'm pretty new to this, too).

    Although the Prop has 8 cogs/cores capable of running simultaneously and generally independently, there's only one execution "thread" (so to speak) between your program and the Sony one.· I haven't looked at the BS2 or Seven objects and they may very well involve another thread or two, meaning cog(s), but your program and the Sony one don't specifically start any other cogs to run any of their own methods in, so I believe you've just got the one thread there, and that organization just isn't going to work.· For example, you don't want to write a loop that never actually·loops, right?·

    It's true that getter and setter methods are a great way to communicate between objects, but the ones that you've added will never be called by your program because control never comes back to your program after calling Init.· It would be possible to call those methods you added from within the GetMessage method of the Sony program, but that would only return values to the GetMessage method with the infinite loop, not your program.· By the way, I think that the getter method that you added is odd, anyway, because it receives the value that it returns without modification, when, as Mike showed, it doesn't need to receive anything.· However, by mentioning the general format of getter and setter methods, I think that Mike was only showing you the general way an object provides a mechanism to let a user object control it or communicate with it, not a specific solution to your problem at hand because he then goes on to point out the infinite loop in the Sony program.·

    I don't know if there is a good solution to your current predicament.· I think significant reorganization is needed, and that's why you haven't gotten any short answers (apologies if I'm missing something, though).· You could move your code into the Sony object, the infinite loop of the GetMessage method, in particular.· But then you wouldn't really be accomplishing your goal of learning to work with objects.· Another possibility might be to modify the Init method of the Sony program to have it "spin off" the GetMessage infinite loop method into a separate cog (see the manual for how to use Spin to launch a method into a separate cog).· With such organization, the Init program could complete immediately after starting up a new cog with the GetMessage infinite loop (ultimately,·most cog programs are infinite loops, or should be), and after completing, control for Cog 0 (in which the first Spin interpreter runs) would return back to your program.· Then, your program would be free to call getter or setter methods within its own infinite repeat loop.· Such getter and setter methods would still be located in the Sony object, but they would be ran by the same cog running your program, Cog 0 (in other words, the same line of execution), not the new cog (likely Cog 1) spun off by the Init program to run the GetMessage method.· So, what would happen is this:· in the infinite loop of your program, you would perhaps call GetMessageValue or a similarly-named getter message.· Control would then be temporarily handed off to the Sony object with the Cog 0 thread of execution to briefly run the simple getter method and then control would immediately pass back to your program (along with the value returned by the getter method).· Oh, and because the message variable is global to the Sony object, I believe that the GetMessage (I'm uncomfortable with that name) method and the getter method, such as GetMessageValue, would have no problem accessing the "message" variable.· As such, I don't think you'd need to use the @ parameter passing mechanism (both GetMessage and GetMessageValue would be in the same object, and you'd have a getter method to communicate with the user object).· I'm not experienced at all with Propeller programming, but I think that's how it would work in this particular case (don't worry, others will correct me if I'm mistaken (or perhaps confirm)).·

    But before you go launching code to run in a separate cog, you might want to get some more experience with objects using objects that can either run in a single cog or wherein the called object or objects·take care of launching any other needed cogs themselves.· Consider playing more with, for example, the TV object and displaying stuff on a screen (if that's an option for you with your setup).· Or maybe you're already comfortable with general objects, such as a Circle object that can return the area of a particular instance of that object, but were looking for something more involved.· If so, I guess you've found it, but, again, I think you need to restructure things to get things working.· Most importantly, pay attention to the thread or theads of execution, particularly any infinite loops in any of the objects.· Then, I think, you'll be on the right track...because it's apparent that you're already willing to experiment and learn by trial-and-error, just guide that with a little bit of analysis.· I need to do that, too.· Remember, though, you're the boss.· You'll get the result you want if you perservere.· Hope something in the above helps and that any errors that I've made don't mislead you too much.· Take care.· --Jim



    Post Edited (JRetSapDoog) : 6/1/2010 12:29:00 AM GMT
  • ratronicratronic Posts: 1,451
    edited 2010-06-01 00:52
    @SteveWoodrough , Here is a simple program that just continuosly displays the value of the button pressed.· The ir receiver is hooked to pin7. Maybe you can use this for an example.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE

    Post Edited (ratronic) : 6/1/2010 1:27:02 AM GMT
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-01 02:07
    Jim,
    Thank you for taking the time to provide a thoughtful reply. I guess I really should have titled this “How to Write a Top Level Object?”. That is exactly the primer I’m asking for.

    Last year or so ago I was able to have the Sony Remote control my BOE BOT and it was as easy as making a hot cup of tea.
    I’m not married to this particular set of objects or methods and I understand that the structure and loop on the Sony IR object do not lend themselves as a good starting platform. You are correct in understanding my intent is to gain a full understanding of how to integrate existing objects into a top-level object.

    For the time being I would prefer to do this or some other similar exercise in the same cog. First because it decreases the complexity and second, because I know I could do this with my Stamp!

    Let me explain what I think I know and what I think my questions are. Maybe I’ll answer my own question.

    True or False? For all intents and purposes; Objects cannot retrieve or extract data from other objects, they can only receive it from another object.

    e.g.
    Top Object Gets or passes DATA from some source and passes DATA to Lower Object method by something like:

    LowerObject.method(DATA, Parameter, etc)

    Now, assuming I’m not already wrong, I suppose that the reverse is also true:

    LowerObject sends or passes DATA up to TopObject by something like:

    TopObject.method(DATA, Parameter, etc.)

    We know that from p 111-113 PEK Fundamentals that:
    Top Objects can pass information to Lower Objects by address.
    TopObject sends DATA to LowerObject by something like:
    LowerObject.method(@V1, @V2)

    Where V1 and V2 are defined in TopObject’s global variable list

    Question: Is it possible for a LowerObject in the same cog to similarly write to a memory address? Which objects, top or lower, global variables are used?

    It’s late and time for bed.

    Dave,
    I just saw your post, so I'll try that tomorrow. Thanks!!!!

    Best Always,
    Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-01 05:27
    I've written SIRCS receiver and transmitter objects -- you might have a look at them to seen how the object-to-object communications works.

    www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp4.pdf

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • bill190bill190 Posts: 769
    edited 2010-06-01 13:46
    For a called object to return a value, there is the "RETURN" command. (Page 196 of the Propeller Manual)...

    http://www.parallax.com/Portals/0/Downloads/docs/prod/prop/WebPM-v1.1.pdf

    Then in the assembly language section of the above manual, there are some commands which look interesting...

    Main Memory Access
    [font=Parallax,Parallax][font=Parallax,Parallax]RDBYTE [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Read byte of main memory; p 335.
    [/font][/font][font=Parallax,Parallax][font=Parallax,Parallax]RDWORD [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Read word of main memory; p 337.
    [/font][/font][font=Parallax,Parallax][font=Parallax,Parallax]RDLONG [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Read long of main memory; p 336.
    [/font][/font][font=Parallax,Parallax][font=Parallax,Parallax]WRBYTE [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Write a byte to main memory; p 374.
    [/font][/font][font=Parallax,Parallax][font=Parallax,Parallax]WRWORD [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Write a word to main memory; p 376.
    [/font][/font][font=Parallax,Parallax][font=Parallax,Parallax]
    WRLONG [/font][/font][font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Write a long to main memory; p 375. [/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]The manual is not very good with assembly language instructions. So what I do is search the forums here for examples of their use or comments/questions on it. So here is a search of this forum for WRBYTE as an example of the information you can find...[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]http://www.google.com/search?hl=en&lr=&as_qdr=all&q=wrbyte+site%3Aforums.parallax.com&aq=f&aqi=&aql=&oq=&gs_rfai=[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Here is a search of these forums for the words RETURN VALUE...[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]http://www.google.com/search?hl=en&lr=&as_qdr=all&q=return+value+site%3Aforums.parallax.com&btnG=Search&aq=f&aqi=&aql=&oq=&gs_rfai=[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Then when I want to try out a new command, I don't do this with an already existing program or programs, I create new program with just that new thing in it, then I can learn how·just that command·works.[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]Or I might take an object/program which has that working in it, then comment out or delete everything but that portion, then I can play around with that part and see how it works.[/font][/font]

    [font=Times New Roman,Times New Roman][font=Times New Roman,Times New Roman]

    [/font][/font]
  • lockadoclockadoc Posts: 115
    edited 2010-06-03 15:10
    I had the same trouble , but got some great help here in the forum,I have a project that is in the COMPLETED FORUM that does use a sony remote to light up some leds. Its called Eight Channel Light Controller
    http://forums.parallax.com/showthread.php?p=882404
    You should be able to copy the method you need and tham modify it to your needs



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Life is fun with a Prop.



    BillS
    ··· Louisville KY.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-05 11:44
    You certainly don't need to launch a cog to add two numbers, so I suspect your ambitions are greater. What you want to do is launch a cog and leave it running, then "talk" to that cog through a method in your program. In the attached demo a PRI method called math is launched and waits for a command (this is a global variable). It then picks up two parameters, performs the command, and writes the result back to another variable. Note that method called domath() is the communication between your foreground program and you "background" cog -- this allows you to pass parameters to the background.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-08 02:28
    Thank you everyone for their support and guidance.
    ·
    For the time being I’ve abandoned the idea of working with the SONY IR.· That was simply a tool for me to learn what I really want to FULLY understand: How to pass data back and forth between methods, objects, and cogs.·
    ·
    I’ve made progress over the past few days and I can now pass data between methods and between objects within the same cog.· I know this seems simple for 99.99% of you but it’s a big deal for me.· My test bed program, attached, is very simple.· I enter 2 numbers through the PST and call either an internal method or a method in another object to add the two numbers together.····
    ·
    The point where I am now hopelessly confused is doing the same Z= X+Y within it’s own cog, applying the principles from PEK p.112 and 113 Objects lab as well as the 3 tips given on p. 160 of the same.· Initially I want to learn how to do this all within the same object.· Once I get the hang of that I’ll perform the cog launching in a different object.
    ·
    I have to say I feel as though I’ve really tried to do my homework, but “Johnny just can’t read.”·
    ·
    What am I doing wrong and how do I get this to work?·
    ·
    Thank you for your help.
    Steve··

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-08 04:28
    One side of me says this stuff is not nearly as hard as you seem to want to make it, while the other side says you're withholding state secrets about what you ultimately want to do.... tongue.gif

    Since you would not waste a cog to do simple addition, what is it that you are planning to do? Your actual goal may help a yutz like me give better suggestions.

    Update: I just looked at your code again and I think I found the problem -- you're trying to call a method that is running in a different Spin cog; cogs cannot "talk" directly with each other. What you need to do is have the method cog put the result in the hub where the caller cog can get to it. I showed you how to do this in a previous post.

    Also.. be mindful of formatting; you code is not indented very well and this could result in errors if you're not careful.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA

    Post Edited (JonnyMac) : 6/8/2010 4:41:19 AM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-06-08 07:20
    Hello,

    inside one object you have access to every global variable that is defined in a VAR-block

    inside one object you can even access variables ACROSS cogs

    global variables are stored in the HUB-RAM which is shared by all 8 cogs.

    So even if you start a ANY method in a new cog you can directly ACESS all variables that
    belong to the same object

    see axample code here

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      
    VAR
      long CogStack1[noparse][[/noparse] 20]
      long CogStack2[noparse][[/noparse] 20]
      
      long MyTestVar
    
    OBJ
      debug : "FullDuplexSerial"
    
    
    PUB Main
    'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run
      'heart.Start(27, 200)
      debug.start(31, 30, 0, 9600)
      
      MyTestVar := 100
      debug.str(string("Start MyTestVar="))
      debug.dec(MyTestVar)
      debug.Tx(13)
    
      cognew(M1,@CogStack1)
      cognew(M2,@CogStack2)
      
      repeat
        waitcnt(clkfreq + cnt)
        debug.str(string("MyTestVar="))
        debug.dec(MyTestVar)
        debug.Tx(13)
    
    
    PUB M1
      repeat
        waitcnt(ClkFreq * 3 + cnt)
        MyTestVar := 1
    
    
    PUB M2
      repeat
        waitcnt(ClkFreq * 5 + cnt)
        MyTestVar := 2      
    
    
    



    easiest access of variables across OBJECTS is to define get- and setmethods INSIDE the second object like Mike Green already showed in a earlier posting

    best regards

    Stefan

    Post Edited (StefanL38) : 6/8/2010 10:10:11 AM GMT
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-09 01:59
    Jon,
    Thank you for your candor!! Believe me I'm not trying to withhold state secrets!· I do believe though that before I attempt to use OBEX items I must first develop a full understanding of how to exchange data between methods, objects and cogs.· If I cannot do that reliably and with absolute confidence that I fully know and understand every line of code I’m "pushing a rope".· To use an analogy, before I started playing competent golf, I first took lessons and went to the driving range and learned how to hit all the clubs.· I also did not learn on a 1 iron, I started with something simple and worked my way up.· Same principle applies here.·
    ·
    After reading and working through the PEK labs my initial attempt at using other objects began with the SONY IR object at the beginning of this thread.· I arbitrarily chose that object because I had a general understanding of the IR operation from my STAMP experience.··
    ·
    My background is physics and mechanical engineering and my programming experience is limited to some FORTRAN I did 25 years ago, and my experience with the BOE BOT and STAMP.· My day job pays the bills but does not really tickle my engineer bone.· To get my engineer fix, I mess with RC helicopters and got interested in robotics a few years back.· I guess if I had a STATE SECRET it would be:· Control a motorized golf caddy with my cell phone using GPS feed back that would send my clubs to the 150 yard marker without driving into a bunker, player, tree or lake!·· Maybe build a machine to cut the grass without running through the Zinnia garden.· A car that drives itself would be nice.· Something that could read sheet music and play the piano would be a good winter project.· The horizon is as distant as our minds eye.· But as you can clearly tell, I’m several light years away from ANY meaningful project, if I cannot get a cog to add 1+1 and not get the cog ID back as the answer….
    ·
    So, to continue the golf analogy I started with some chipping and putting; something simple like adding two numbers in a method within the top object.· I got that to work.· Next, I did the same adding two numbers in another object.· I got that to work.· Now lets try a full swing; add two numbers in another cog.· It’s a waste of a cog, but so is a perfect drive at the driving range.· It’s good practice, and who knows, I might just learn something.·· Well I just can’t seem to make contact with the ball.· When I try to add two numbers I get either 0 or 3 (cog ID).· Once I get this down, and by GOODNESS I WILL, I’ll do the same using a separate object and a new cog.· All this is the functional equivalent to a well-struck pitching wedge, but essential to the game.· As an aside, PASM, IMO, is a 1 iron from a tight lie, reserved for the pros.· ··
    ·
    I’m also confused by the conflicting techniques starting cogs.· The PEK manual seems to insist that cogs be started using a start method that stops the cog, then continues on with:· success:=(cog:=cognew(AddXY(XX,YY),@stack)+1)· but both yours and Stefan’s examples seem to defy the PEK tips by going right to cognew(method name).·· Maybe I need to skip the cog stopping and success:= business and just start the darn cog.·

    Best Always
    Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • kuronekokuroneko Posts: 3,623
    edited 2010-06-09 02:35
    The thing is, cognew is a function which returns either the ID of the launched cog or an error (-1). Also, when cognew returns it doesn't mean that your function has been run (there is an 8K cycle overhead for loading the SPIN interpreter into a new cog which then subsequently deals with your function). So there is no way you could start a cog, calculate the result and have that result returned from cognew all in one go. This will have to be a two step approach, i.e.
    • start cog (once)
    • ask cog to perform an operation (multiple)
    • stop cog (optional, once)
    Does that make sense so far?
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-09 03:34
    Yes, and that is what I suspected from what I've read and the fact that I would get a result like 3 which I guessed was the cog ID +1.

    Since my last post I've had a small breakthrough and a setback.

    I got 4+5 to equal 9 by forcing the values of x and y. This is temporary to the exercise, but I'm really trying to simplify things here. However, I could only get the correct answer, 9, if debug.dec(x) or debug.dec(y) are present. If one or both are present (see below) it works. If both debug statements refering to x and y are commmented out then the result for debug.dec(z) is 0. Just what I needed!!! More clarity..LOL

    Thanks
    Steve




    ''Address Passing Experiment
    ''Experiment using addresses to pass paremeters back and forth between objects

    P30- Tx
    P31- Rx

    }}
    CON
    _clkmode = xtal1 + pll16x ' System clock → 80 MHz
    _xinfreq = 5_000_000 ' crystal Frequency

    ''Parallax Serial Terminal Control Character Constants
    ''────────────────────────────────────────────────────
    HOME = 1 'Move cursor to home postition
    CRSRXY = 2 'Position Cursor X, Y
    CRSRLF = 3 'Move Cursor Left
    CRSRRT = 4 'Move Cursor Right
    CRSRUP = 5 'Move Cursor Up
    CRSRDN = 6 'Move Cursor Down
    BELL = 7 'Beep Speaker
    BKSP = 8 'Back Space
    TAB = 9 'Tab
    LF = 10 'Line Feed
    CLREOL = 11 'Clear to End of Line
    CLRDN = 12 'Clear Lines Below
    CR = 13 'New Line
    CRSRX = 14 'Position Cursor X
    CRSRY = 15 'Position Cursor Y
    CLS = 16 'Clear Screen
    VAR
    byte cog

    long X, Y, Z,stack [noparse][[/noparse]100] 'Tip 1 Global variables for cog and stack

    OBJ
    Debug : "FullDuplexSerialPlus" 'Brings in addtional object alias debug


    Pub Main 'Main application
    'Start FullDuplexSerialPlus.
    Debug.start(31, 30, 0, 9600) 'Starts FullDuplexSerialPlus in new cog
    '(rxpin, txpin, mode, baudrate)

    waitcnt(clkfreq*4+cnt) 'wait 4 seconds to start Parallax Serial Terminal
    Debug.tx(debug#CLS) 'clear screen

    x:= 4
    y:= 5

    cognew(AddXY,@stack) 'Must start the cog first



    Debug.tx(debug#CLS) 'clear screen
    debug.dec(x)
    ' debug.str(string(CR))
    ' debug.dec(y)
    ' debug.str(string(CR))
    debug.dec(z)

    Pub AddXY

    z:= x+y

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-09 03:46
    What you seem to be missing is that cogs cannot directly communicate with each other. The indirect connection is the shared RAM of the hub. As an example I posted early shows, you can signal another hub to do something by writing to a known variable in the hub. Result locations are also known by both. If you look at the Propeller architectural diagram you'll see that the only thing common between cogs is the system counter and the shared RAM; the latter is the key to cog-to-cog communications.

    BTW... my first job out of the service was for Toro Irrigation so I've seen a lot of nice golf courses -- played a few, too (if not terribly well).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • kuronekokuroneko Posts: 3,623
    edited 2010-06-09 03:57
    SteveWoodrough said...
    However, I could only get the correct answer, 9, if debug.dec(x) or debug.dec(y) are present. If one or both are present (see below) it works. If both debug statements refering to x and y are commmented out then the result for debug.dec(z) is 0. Just what I needed!!! More clarity..LOL
    The effect you see is that both calls spend time which is used to hide the cog startup time. As I mentioned, once cognew returns it takes some time before your function is run. Displaying z too early (i.e. before you do the add) will result in 0. As a quick fix add a waitcnt(8192 + cnt) after the cognew. The way it's usually done is that the caller waits for some flag set by the code in the newly started cog before attempting to use said cog. HTH
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-09 03:59
    What Kuroneko points out is why most of use use semaphore variables to communicate with "background" processes -- minimizes race conditions that lead to faulty results.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-10 01:23
    Darned interesting, thanks guys. Jon, I saw the pause in your example and did wonder just what the heck that was for.

    I get what you all are saying about cogs not being able to speak with each other. The model I have in my mind is that each cog sits in it's own cubicle. A cog can't see the other cogs in their cubicles, but can see the ceiling (RAM). For cogs to "talk" an object operating in one cog has to put a sticky note (data) on a ceiling tile (address). An object in another cog must look at the right ceiling tile (address) to retrieve the desired data. Am I functionally on the right track? Therefore a setter method sets the value of a global variable in the shared RAM and a getter method retrieves a value from RAM

    Setter: GLOBAL_Var:= 42 'Global_Var is defined in the VAR section of an object.

    Getter: Local_Var := LONG[noparse][[/noparse]@Global_Var]

    Still on track?

    Kuroneko, please continue with your train of thought you started above...

    Thanks...Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • kuronekokuroneko Posts: 3,623
    edited 2010-06-10 02:27
    SteveWoodrough said...
    The model I have in my mind is that each cog sits in it's own cubicle. A cog can't see the other cogs in their cubicles, but can see the ceiling (RAM). For cogs to "talk" to an object operating in one cog has to put a sticky note (data) on a ceiling tile (address). An object in another cog must look at the right ceiling tile (address) to retrieve the desired data. Am I functionally on the right track?
    That is quite an interesting way of looking at it (no pun). Yes, the worker cogs wait for commands (by staring at the ceiling) and once they got one they process it. When the result is ready they remove the sticky note, meaning result is in the out tray, please deliver. I'll attach a small demo program which performs add/sub operations and also deals with the startup delay mentioned above.

    There is one other issue, communication between caller and worker. There are certainly lots of different ways to do it (not counting the wrong ones), the most commonly used one is that the worker polls a command location (e.g. long in VAR), if it's 0 keep polling, otherwise it's a command, do something. Once finished the command location is cleared so the caller knows the result is ready or that it can issue the next command. On the caller side this means if the command location is not zero then this particular worker is busy so we have to wait (or use a different worker). If zero then we should setup any required parameters first(!) and finally write the command. Doing it the other way around may leave the worker with incomplete/invalid parameters.

    The example is not fit for any specific purpose but should get the idea across. HTH
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-10 07:24
    Steve,

    The math example I posted earlier does exactly this; the math cog simply waits for a non-zero command, reads the parameters, applies the command, and then writes the result to a common (known) hub location. Have a look at that program again in light of your last post -- I think you'll see that your train is now on the correct track.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-11 03:11
    Thank you both for your time and patience.· I'm traveling on business through the weekend and don't have any toys with me.· I'll take a look a closer look at this when I return, and continue to reread the documentation in light of these concepts.
    Best Always,
    Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2010-06-13 03:46
    kuroneko
    Thank you for taking the time on this example. I had a chance to download and view. I'm not fulling understanding it, but let me study over it again in the morning.
    Thanks, Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
Sign In or Register to comment.