Not too confused anymore about using cogs, spin and objects [code posted for ap
iQuit
Posts: 78
Am I totally confused, or is this true.... a cog only runs one method at a time? A cog does not run an entire object? Or multiple methods?
Please correct any all of the following.
I'm new to the structure of the Propeller and am working on a project while studying the manual, searching this site, posting questions here, plugging
wires into the demo board etc. Things are starting to clear, a little bit here and there. I get the idea of objects to use as building blocks; makes sense!
You have a main, or top, object, and then call to the other objects for their particular methods. I'm not real clear how to pass variable information from
one object to another, but I'll get that soon--I found several things here in the forums.
Then there are the cogs. I can only find instances of additional cogs getting started to run a single method. This seems wasteful to me. Unless! Unless all
of the code that is run from the main program, in the top object, is run in cog 0 one method at a time. And then additional cogs are started if called upon
by code to perform a method--just as if it were a separate program, like the main program, run in a cog.
If there are several objects that make up a program, and none of them call cognew, everything must run in cog zero--I used deductive reasoning to get that
one.
Please tell me more about the interpreter.
Why not just put everything into one spin file? Then, whenever you need to run something in the background (concurrently), start a cog.
Thanks in advance, Confused! (I'm not giving up, though)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Post Edited (iQuit) : 4/24/2010 2:07:09 AM GMT
Please correct any all of the following.
I'm new to the structure of the Propeller and am working on a project while studying the manual, searching this site, posting questions here, plugging
wires into the demo board etc. Things are starting to clear, a little bit here and there. I get the idea of objects to use as building blocks; makes sense!
You have a main, or top, object, and then call to the other objects for their particular methods. I'm not real clear how to pass variable information from
one object to another, but I'll get that soon--I found several things here in the forums.
Then there are the cogs. I can only find instances of additional cogs getting started to run a single method. This seems wasteful to me. Unless! Unless all
of the code that is run from the main program, in the top object, is run in cog 0 one method at a time. And then additional cogs are started if called upon
by code to perform a method--just as if it were a separate program, like the main program, run in a cog.
If there are several objects that make up a program, and none of them call cognew, everything must run in cog zero--I used deductive reasoning to get that
one.
Please tell me more about the interpreter.
Why not just put everything into one spin file? Then, whenever you need to run something in the background (concurrently), start a cog.
Thanks in advance, Confused! (I'm not giving up, though)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Post Edited (iQuit) : 4/24/2010 2:07:09 AM GMT
Comments
Cog 0 is the first cog that runs after powerup and it runs a pasm program within the cog (in it's cog·memory)·called the Spin Interpreter (Interpreter for short). Your spin code exists in the hub memory and is run interpretively. As you call methods, they execute sequentially as a normal program would do.
However, you may have a program that you want to run in parallel in another cog. This can be either spin or pasm (but not both). You start this process by coginit or cognew. Some examples of object that use a seperate cog are the FullDuplexSerial (it runs the code to simulate the UART for the serial I/O) and uses spin code to interface to it in your normal calling program. There is a TV object to display on a TV, the VGA object to display on a VGA screen (this uses more than 1 cog), the PS2 Keyboard object, and others.
In one of the manuals there is a tutorial for learning some of this. In particular, a simple LED flashing program is loaded into another cog. In fact, you can load the same code into multiple cogs and flash different leds at the same time. This may be the best place to start.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
Re "Why not just put everything into one spin file? Then, whenever you need to run something in the background (concurrently), start a cog."
Well, you can if you like. You could take ten objects from the object exchange and turn them all into one big spin file, all with their assembly code and spin code. I tried doing that once - it does work but the problem is that lots of objects use the same variable names and when they are in seperate objects it is not a problem, but if you combine them to one big spin file then you have to rename a lot of variables.
It is possible to start and stop cogs and reload them with different assembly programs. But usually you just start it running and then leave it running - eg driving a VGA or a TV display. Start the cog, set it running on the TV and feed it information from time to time.
In the real world, cogs get spoken for fairly quickly. One for keyboard, two for VGA, one for serial ports, one to run a sd card, one for the underlying spin interpreter, and suddenly there are hardly any left. So in practice you might end up just plugging in existing code, and the code you actually write yourself is just one spin file.
What sort of project are you thinking of building?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
That's one of the cool thing of the propeller. If you have for example a sender and a receiver - or let's call it a producer and a consumer to be more general - you can run both on the same propeller chip in different COGs until everything works. And when you're done with development you put one part of the code on prop1 and the other on prop2 and it'll still work.
Basically a microcontroller does work or "tasks"...
Like a horse.
If you have a big field, you could have one horse plow the big field. It would take awhile...
BUT if you have several horses, they could each do a portion of the work and the work would be done sooner.
Or maybe the neighbor needs some work done. If you lend the neighbor your only horse, you will not be able to get any work done!
However if you have several horses, you can lend one to the neighbor (be doing that work), and have several other horses plowing different sections of your big field at the same time. Everything gets done all at once!
And same thing with multiple cogs. Several things can be done at the same time.
With just one microcontroller, it can only do one thing at a time. Say you have some buttons which someone can press and you are also moving a controller motor. As that one microcontroller is making the motor move, it is busy and can't be checking to see if someone has pressed a button...
It can only do one thing at a time!
However if you have two microcontrollers (or cogs), one can be checking to see if a button was pressed *all* the time and the other can be making the motor move at the same time!
And that is the reason I bought the propeller. So that one cog can be assigned to check the input buttons. And another can do something else at the same time.
Another way to do this is with speed. Quickly make the motor move a little, then go back and check that button to see if it was pressed. And the propeller can do this as well with just one cog because it is quite fast!
But that is more difficult to program. You need to pay attention to timing and that you are not spending too much time away from those buttons. Easier to assign another microcontroller to the "task" full time.
And think about pressing a button quickly. At that instant in time, the microcontroller needs to be checking to see if the button was pressed. If it is busy doing something else, it will not see that you pressed the button!
Worse still is a "matrix" of many buttons. You can have 16 buttons and only 8 wires.·4 wires across and 4 wires up/down. You press a button and it would cause two of these wires to short. If you have a very fast microcontroller, it can very quickly check all possible combinations of wires to see if there is a short between two of them. Lots of work to do! Better to have a fast microcontroller and·even better is·one which is dedicated to this task.
As to motors, if these are to move to a certain position and then stop, you may need to keep checking a sensor on the motor to see if it has moved to where you want it to. This could take a full 5 seconds or more if it is a slow moving motor. It can take all the time in the world if you have one cog assigned to that motor...
subject; many cogs working together.
@ cluso99, I have gone through the tutorial you mentioned. It helped. I plan on going through the PE kits also. I'm currently building a project also, so I'm
throwing myself in the water to learn how to swim. I'm also enjoying the challenge.
@ Dr_Acula, I'm building a cell phone based remote for my car. I use my cell phone, the one I carry around (CPA), to call the one placed in the car (CPB).
CPB will call CPA if the alarm goes off, notifying me of the condition. Kind of like those two way alarms, but only with a longer reach. I can also call CPB,
enter a PIN, and then give it commands such as Unlock, Lock, pop the trunk and Panic--all of these are done using a spare key fob remote that the car came
with. Another command would be, kill engine ignition. CPB is connected to a propeller via a DTMF decoder. I chose the decoder, kludgy as it is, because
I wanted to have access to the car using any phone, not just my phone. I've found info here that shows FFT using the propeller, but that's a little beyond me
at this point.
@ MagIO2, Two Props? That's cool. Maybe later down the road, after I've mastered one.
@ bill190, I like the horse analogy. The book that I'm going through uses clones, but same idea.
To all, I would love to hear how each of you deal with the information exchange between multiple cogs. Also, information exchange between the top object
and other objects that are called. I'm not quite clear on how to do this, and it seems that there are several ways to do this--this may be where I get a little
confused. Too many choices? Or is there only one way for each case?
Thanks to everyone for the help. It greatly appreciated.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
The core thing needed is for all the cogs involved to know the HUB memory addresses where the data exchange will happen. You use the @ operator for this. @mydata will return the address value $4f00, for example, if that were the actual value. Once you know where your data lives in hub memory, you can pass the actual value, or number that represents it to your various cogs, who then go and do their thing with it, whatever it is you've programmed them to do.
From there, you build up structures based off of that, or offset from that address, or addresses.
Such structures may include one or more of the following:
-flags, where the HUB memory location holds values that the cogs watch for and act on
-parameters, where a sequential block of addresses contains mode, state, or timing information to be acted on, or that is the product of an cog action
-buffers, where a series of hub addresses contain the product of one cog, consumed by another cog.
There are other data structure forms too. I just put a few here.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
8x8 color 80 Column NTSC Text Object
Safety Tip: Life is as good as YOU think it is!
Post Edited (potatohead) : 4/22/2010 3:42:20 PM GMT
before, and it has confused me. Say Lock is a var, and I set it to 1. Does @Lock have 1 or some address, like $4F00?
I think that I have the general idea, but it's in the details where I get confused. Practice with examples will help. Direct me to any that you know of
that would help clear things up.
Thanks for the reply.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
if Var1 is located at address $4f00 and has a value of 1 the following would be true.
a := Var1 would get the value so a := 1
a := @Var1 would get the address so a := $4f00
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Will work for Propeller parts!
Thank yo for that straight forward, concise answer; never has it been explained like that. Kudos. However...
I assume that the only time that you need the address of a variable is when you are running more than one cog, and want to share information
between the cogs. Do I assume correct?
And then does it mean that you have to first get the address of a variable, and then get its contents? Or, does that happen in one step e.g.
Cog A looks at the value of a variable located in cog B:
Cog B first sets a variable called Lock to 1; Lock := 1
Then cog A says, is cog B locked? LockStatus := @Lock
Will cog A see 1, or simply the address--say $4F00. And if this is true, how do I see just the value; because I'm not interested in the address, just the data.
This one has confused me since I've started learning spin and its object oriented language. Once I have this figured out, I'll be on my way.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Post Edited (iQuit) : 4/22/2010 5:11:43 PM GMT
-Steph
books. I do plan on going through the PE Kits as time allows.
As mentioned above, I'm currently working on a project, and this is why I need to know NOW.
Just kidding. I'll learn it at whatever pace I can absorb it. But as a need arises, I look for answers--everywhere I can. I sometimes re-read sections of
the manual and a light goes off. But not always.
Sometimes when you are learning something new, your mind wraps around it looking for a way in. The way in is not always apparent upon first inspection.
Sometimes it takes several tries. The manual is a great reference, but does not go into much detail. The official guide goes beyond the manual, but those
that wrote it already know the stuff inside and out. I hope that the PE Kits Labs are what I need, and I will get to those when time allows.
Concepts. It's all about the concepts here. The structure of objects were confusing at first, but now I have a good grasp of how they work. It's some of
the other things that elude me. Such as the var1 vs @var1 thing. blittled gave a good explanation, but as you can see I still have questions about exactly how it
works. (see my post above in response to his)
Thanks to everyone that has given time to respond.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
I look at it like this. You are put into a Formula 1 car and can not figure why you can't make this thing drive straight. Then you go back and do the Skip Barber school of racing, and then everything starts to make sense.
My .02
Jim
Can someone answer the section above that I put in Blue concerning the two cogs talking to each other? Here it is again:
Cog A looks at the value of a variable located in cog B:
Cog B first sets a variable called Lock to 1; Lock := 1
Then cog A says, is cog B locked? LockStatus := @Lock
Will cog A see 1, or simply the address--say $4F00. And if this is true, how do I see just the value; because I'm not interested in the address, just the data.
Thanks, Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
I drew this image based upon the the "VAR-spin language reference" section from the manual. See attached image.
The statements in blue come from Scope of Variables, "Symbolic variables defined in VAR blocks are global to the object in which they are defined
but not outside of that object."
Those in red are based upon, "Global variables are not accessible outside of an object unless the address of that variable is
passed into, or back to, another object through a method call. "
And finally, that in green is based upon this in Scope Extends Beyond a Single Cog, "If the object launches some of its methods into multiple cogs, each of those
methods, and thus the cogs they are running on, have access to those variables."
It does not say if Method X can see vars A, B in obj1, but I suspect that there is a way to get them if need be.
Feel free to correct what I see, or add helpful information; this may help others also.
I hope to revise this image, adding actual examples of code, to show proper ways of doing what is shown there.
Thanks, Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Good reading there.
Jim
Please don't forget that you can use one object twice or have a whole array of the same object! Then each of the instances will have it's own copy of the variables. Only a DAT section is really global across all instances of an object.
MagIO2, That above was taken verbatim from the manual. It didn't refer to multiple instances of the same object. Don't try an confuse me further
Thanks, Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
I didn't write anything useful in the Official Guide, I was just the go-between for the authors and the publisher. (That was enough excitement for me!)
For your particular quandary, take a look at "Scope Variables" and "Scope Extends Beyond a Single Cog" in the Propeller Manual v1.1. And since you have the Official Guide, pages 74 to 77 might shed some light. I hope you have downloaded all the code examples for the Official Guide from ftp://ftp.propeller-chip.com/PCMProp. And just FYI, all the code examples for the PE Kit Labs book are also bundled with the Propeller Tool software.
-Steph
Take a look above at my "Okay, here's what my brain looks like on Spin" post. I quote those very sections of the manual. I also included a nice
diagram showing my understanding of that part of the manual. Take a look and see if it's correct.
I will re-read the 74 - 77 pages tonight. I'm currently looking at the PE Kit Labs 5, 6.
It's starting to set in.
=Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
iQuit: Firstly, be careful of the use of the word Lock as there are some locks in the prop which we rarely use.
The main use of the @xxx is to pass an address of a set of variables to a cog running pasm. It is not the only one, but a big one. Your questions which haven't been answered are because it is a little complicated at this stage to explain.
Take a look at the FullDuplexSerial object. When we do fdx.start(r,t,0,baud) we are passing a set of pins and speed to the object. This will run the start routine in fdx (which is still running in cog 0 in spin). It then sets up these parameters in a list in hub and starts a new cog which will run pasm. Part of the cognew is to pass an address of the list of parameters to the pasm in the new cog. This pasm code will immediately get the "par" register which contains the @.... address of the parameter block, and proceed to get the parameters from hub.
Now for your spin code to send a character it calls the fdx.tx (or hex, str, dec,) spin routines in the fdx object (still in the same cog 0) which will pass the data characters to the fdx cog's pasm code via what we call a hub buffer. The cog pasm code is looking at these hub addresses to see if any characters are available for it to send. See the txhead and txtail pointers as this is how we tell if there is any data in the tx buffer.
There is a simpler way using just one hub location but a simple program that you can look at escapes me for now. The fdx code is one that you will likely use soon. While you do not require to know the details of the fdx object other than the routines, it is a place to start and an object I am quite familiar with. Do not worry about the pasm code as it is quite complex for you at this stage. It is actually doing two things at once so it is continually swapping tasks to do a little of each - that being transmit then receive.
I hope this helps and does not confuse you. It is hard to try and go back to describe the basics once you master the complexities.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
I hope to master this someday, but for now, I hope to simply understand it. And everyone is helping. If you can, take a look at my post above regarding what my brain
looks like on spin. I have a diagram that I created that outlines what I read and understand of the manual's description.
I will look at the FullDuplexSerial object. I have looked at some others, and find that I do understand some of what I see. I'm going to try putting together
a small program with two objects and pass stuff between them. Then, when I have that working, I'll start a cog and pass some more stuff to and from it.
Nothing like trial and error.
If you think of that other object, let me know.
= Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Setup;
Cog A wants to look at the value of a some variable located in cog B
So,
Cog B at some time during its running sets a variable called var1 to 1, var1 := 1
Then cog A says, what is the value of var1 in cog B by using GetVar := @var1
Will cog A see 1 in GetVar, or simply the address--say $4F00.
And if this is true, how do I see just the value; because I'm not interested in the address, just the data.
Thanks, Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
SO your statement GetVar := @var1 will return just the address of the variable, not it's value. However, because of what I said above, var1 must be in hub, not the cog.
If the cog has placed the data into var1 in hub (by a wrbyte/word/long instruction in pasm or var1 := avalue in spin) then you just do GetVar := var1
I hope this answeres your question and makes sense.
There is also a wiki tutorial IIRC.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
of testing theories. Trial and error! I am making success and gaining ground. Thanks to all that have helped.
Please tell me more about where this wiki is.
= Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Just look at my signature [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
8x8 color 80 Column NTSC Text Object
Safety Tip: Life is as good as YOU think it is!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
Definition: A variable is a symbol (a name) for a location im memory.
If you use this variable you access the content of that memory location. If you work with the @ operator, you can find out what address the variable has in memory.
First let's have a look at just one SPIN-file. There are·4 ways to define variables:
myVar_1 and myVar_4 are usable everywhere in the same SPIN-file. Each function has access to it and can change the values. It does not matter if the functions run in 1 or in·many COGs!
myVar_2 and myVar_3 are so called local variables and are placed on the stack. Only the function where these variables are defined has direct access to these variables. So, if myOtherFunction would like to access myVar_3 you get a compile error.
If you run a function in more than one COG, each will have it's own set of local variables. For example:
Each function has it's own whichLED and timing, but both access the same variable time_10ms for calculating·an individual·on/off-time.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
I actually have some code written that resides in two objects. The main obj calls a method in the second obj to initiate a cognew. I also have the main object
make calls to the second object to get variable info that resides in the second obj, just like I wanted. I'll post the code for review when I get home tonight. I'm
quite proud of myself But I want to thank everyone for their assistance. I'm not quite done with the project, so there may be more questions coming.
Stay tuned in, and thanks = Dan
P.S. Cluso99, no SlingBlade?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny
Post Edited (iQuit) : 4/23/2010 7:40:02 PM GMT
I've seen you request some code that shows how a cog can communicate with a variable. Perhaps this useless program will shed some light.
Just change one of the led_state_ variables and the associated led will do what you ask...
Ex:
led_state_1 := -1 'Turns on LED_ONE
led_state_2 := 0 'Turn off LED_TWO
led_state_3 := 10 'Flashes LED_THREE at ten blinks per second
.Steve