Programming Fundamentals: Passing variable data between objects (Sony IR decode)
SteveWoodrough
Posts: 190
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
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
I looked at your "Sony_IR_Decoder". The GetMessage method just stays in a REPEAT loop and never returns.
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
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.
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
So try NOT using @ and see what happens.
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
···································Fix it, if ain't broke!
D Rat
Dave Ratcliff N6YEE
Post Edited (ratronic) : 6/1/2010 1:27:02 AM GMT
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
www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp4.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
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]
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
·
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
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
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
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
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
- start cog (once)
- ask cog to perform an operation (multiple)
- stop cog (optional, once)
Does that make sense so far?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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
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
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
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
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
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