Prop Code and Objects
RICoder
Posts: 91
I'm pretty new to the Prop chip and I'm wondering about the state and constancy of objects. In the normal course of object oriented programming I might instance an object and keep it live, having initiated it with some variables that I store locally. I would like to do the same thing in prop code, and I'll use an example to help me state my question.
Suppose I make a temperature sensor class (i'll call it that, because the code itself is not the object, the INSTANCE of the code is the object), and I want to pass in the DQ, RST and CLK pins on initialize so that when I make subsequent calls to the functions in that class, I don't have to pass those pins in again. Now, lets say I even use START as my function and pass in those values, and store them in locally declared variables LOCAL_DQ, LOCAL_RST and LOCAL_CLK.
Assume I have a OBJ declaration in my main app called TEMPERATURE set to this class.
First question(s):
If I call TEMERATURE.Start (DQ, RST, CLK) and all it does is store them in those local variables, can I be sure they remain there in future uses of the object? (assuming the entirety of the Start code is just assignment of those vars)
Now, lets further say that I want to have multiple instances of this class. So, I name two OBJ vars TEMP1 and TEMP2 as my class.
Next question:
Are they unique? If I use a different pin for DQ in each, can I rely on the fact that the objects are going to store them correctly?
Finally, I want to deal with COGs. I would like the object to use a cog when one of its functions are called. Now it becomes an issue of timing. For my Start code, there is no real need to start a COG and certainly no reason to hold one, since I am only assigning variables.
Next questions:
Can I kick off a new cog in the function calls?
Can I use my locally set variables in that new cog?
Can I kill that cog when I'm done?
Not the easiest questions in the world, I know.
Suppose I make a temperature sensor class (i'll call it that, because the code itself is not the object, the INSTANCE of the code is the object), and I want to pass in the DQ, RST and CLK pins on initialize so that when I make subsequent calls to the functions in that class, I don't have to pass those pins in again. Now, lets say I even use START as my function and pass in those values, and store them in locally declared variables LOCAL_DQ, LOCAL_RST and LOCAL_CLK.
Assume I have a OBJ declaration in my main app called TEMPERATURE set to this class.
First question(s):
If I call TEMERATURE.Start (DQ, RST, CLK) and all it does is store them in those local variables, can I be sure they remain there in future uses of the object? (assuming the entirety of the Start code is just assignment of those vars)
Now, lets further say that I want to have multiple instances of this class. So, I name two OBJ vars TEMP1 and TEMP2 as my class.
Next question:
Are they unique? If I use a different pin for DQ in each, can I rely on the fact that the objects are going to store them correctly?
Finally, I want to deal with COGs. I would like the object to use a cog when one of its functions are called. Now it becomes an issue of timing. For my Start code, there is no real need to start a COG and certainly no reason to hold one, since I am only assigning variables.
Next questions:
Can I kick off a new cog in the function calls?
Can I use my locally set variables in that new cog?
Can I kill that cog when I'm done?
Not the easiest questions in the world, I know.
Comments
Check out the tutorials in the manual. They give very concreate examples of this type of problem.
Cheers!
Paul Rowntree
these are VERY good questions that hit the most important things about complex programming in SPIN.
So the experts in this forum have a challenging question
local variables defined in the headline of a method like this
are only accessable INSIDE MyMethod
global variables defined in the VAR-section of a *.SPIN-File are global in the limits of THIS *.SPIN-file
If you take a look inside the DS1620 object
in the PUB start the PIN-Numbers were assigned to the global variables dpin, dpin, rst
these variables are accessable everywhere inside of THAT instance of the methods of the DS1620.SPIN-file
So if you define two objects TEMP1, TEMP2 based on the same DS1620.SPIN-file the two objects are independant
and work on their own with their own variables
ONE object can use multiple cogs and as long as methods and variables are inside ONE *.SPIN-file you can access these variables
even ACROSS cogs ! If you do so you have to use a lock/unlock mechanism to make sure that writing to variables is NOT colliding
with writing to the same variable from another cog. Use the LOCKxxx-commands therefore
Yes you can start a cog inside any PUB or PRI-method
by using the command cognew(Methodname,@Stack)
where Methodname is the name of that method that should run in the new cog
and
@stack is a stackvariable that is defined in the VAR-section of the same *.SPIN-file
and needs a minimum of 9 longs
example
usually the size of this stackvariable is 20-100 longs depending on various things like paremeter of called methods and nested calls of other methods called from "MethodName"
EVERY call of cognew needs its own stackvariable
You should do the cognew inside the same *.SPIN-file where the starting method is located
locally variables - defined to be local for one method - can only be accessed within that method
global variables can be accessed within the same *.SPIN-file
even ACROSS cogs but cannot be accessed directly ACROSS *-SPIN-files
Therefore you have to pass a pointer pointing to the variable to a VAR-section-variable
or you have to use variables defined in the DAT-section which work by using pointers anyway (and always only with pointers)
to get or set values of variables in an other *.SPIN-file you can use methods
you can "kill" the cog when you're done. Start a new cog with cognew takes some microseconds
if your code running in the new cog leaves all loops a cogstop is called automatically
But you can code a cogstop if you like to
But why start and stop a cog all the time ?
As long as things don't HAVE TO run independent and parallel keep your programming sequential,
which means insert the new code in an existing loop of the same cog.
It is MUCH MUCH easier to debug sequential running code than parallel running code
This is a lesson that I have learned from programming controls for automotive production industries
Of course something like FullDuplexSerial HAVE TO run in its own cog INDEPENDENTLY
Because the Prop can NOT know when serial data arrives
But whenever YOU can control the start of events (like read out a temperature or a signal keeps its logic state
longer than your longest time it takes your loop to start its next looping KEEP THE CODING SEQUENTIAL !
Oh sorry for so many UPPERCASE letters. The meaning is just emphasising. It is NOT meant that I'm angry or harsh or anything like that
just emphasising
So feel free to ask as many more questions as you like about objects, cogs, variables or whatever
I think a lot of other forum-members will enjoy reading and learning or answering
best regards
Stefan
Post Edited (StefanL38) : 2/1/2009 8:48:54 PM GMT
Cogs and objects are not really related. I have several programs that use a main "object" and several library "object"s. I also sometimes use objects just for encapsulation with no use of separate cogs at all. My BoeBotBasic interpreter starts several cogs, sometimes just for a short period of time, then stops them. There is overhead for starting a cog ... about 100us. Depending on your application, that may be prohibitive or it may be fine. If it's too much, then you start a cog during initialization and the cog sits looking for a command to be passed through shared memory, executes the command, and goes back to waiting for a new command to be provided.
I attacked each problem separately and my results are these:
For what I was calling local variables, I chose the wrong words. What I should have said was variables that are global to the object. For example, my 7 Segment LED object (using a 74HCT595 chip):
In my main object, I have two object definitions:
With the above code, I can make repeated calls to the left and right display to set values without having to constantly send in the pins, which honestly is just a pain in the butt, and also, IMO, bad programming as it is just another point of failure especially if the code changes.
Further, I decided to investigate COG control where I would have an object that didn't necessarily need a cog running until there was a function called. What I did, I will explain without the use of actual code because it is just sample code and a little confusing, but I'm interested in what people think of it. I'll use the function "SetValue" from my 7 Segment LED object as an example.
What I did was create two methods, PUB SetValue (lVal) and PRI SetValueCog (lVal).
When you call SetValue (lVal) it checks to the cogs in use to make sure it uses the right pointer for stack space. Then it kicks off a new cog calling the method SetValueCog and adds it to the list of cogs in use.
This way the object is controlling the use of new cogs in context. You cannot initiate SetValueCog (lVal) from outside, as it is private.
I've not seen any other code around here that treats cogs like this, and I may very well be violating some standard for programming a microcontroller...i'm curious to know what people think.
As I dig deeper into SPIN I can see the power that is there, but I think there is a lot of room for smarter ways to deal with COGs and objects...certainly ways that are easier to implement and understand.