Shop OBEX P1 Docs P2 Docs Learn Events
creating an object — Parallax Forums

creating an object

DgswanerDgswaner Posts: 795
edited 2008-07-18 05:59 in Propeller 1
I'm trying to make a simple object to control an LED, I want it to blink, be solid, stay on, etc. to be used as a status light. I can make the LED do what I want but it stops the program, I could use newcog but I'd prefer to not have to stop and start the cog to change the state of the LED. is there any documentation on creating an object? I've looked but I can't find anything.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

DGSwaner

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-07-10 00:36
    There are two separate, independent issues here (and you have to understand this first).
    1) There are objects. This is a technique for encapsulating part of a program.
    An object has its own data area and a bunch of subroutines.
    Some of these subroutines are usable by other objects and some are not.
    The ones that are usable are what define the behavior of the object to the rest of the "world".

    2) There are cogs (processors). This is a mechanism for running parts of a program in parallel

    You can have multiple objects that only use one processor.

    You can have a single object that uses a whole bunch of processors to do its work

    It turns out that it's handy to use an object to manage the use of a separate processor
    so the rest of the program doesn't have to worry about the messiness of doing so.

    For your LED blinking, don't worry about objects. Use cognew to start a Spin method to handle
    the blinking using a separate cog. Get that working the way you expect it to work. If you want
    to bundle that whole action up in a package for others to use, then learn how to take what you've
    done and package it as an object.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-07-10 00:43
    When you write the method for blinking, pick a variable to use to communicate between the main cog and the blinky cog. That's really the only way to communicate between cogs. You can do it with I/O pins, but those are better used for controlling I/O.

    This variable should tell the blinky cog what to do. Zero might mean "don't do anything other than wait for a while, then check again". One might mean "turn the LED on". Two might mean "turn the LED off". Values from three to ten might mean to "blink that many times a second".

    Your blinky method just has a big CASE statement that chooses what to do based on the value of this variable (which is initialized to zero before doing the COGNEW). For blinking, the blinky method has to check the "magic variable" while it's blinking the LED to make sure that the main program hasn't changed the value, even to just a different blink rate.

    Your main program just sets this variable to whatever it wants to happen.

    Post Edited (Mike Green) : 7/10/2008 12:49:32 AM GMT
  • DgswanerDgswaner Posts: 795
    edited 2008-07-10 02:42
    I do understand the object and cog part, I know I don't fully understand how to use them to the fullest but I was actually hoping to make an object so I can use it for other projects. I'm not saying that I don't want to use your suggestion to just use a seperate cog, but just so I can understand, why can't I use and object (using a seperate cog). it would be nice to call LED.start(LEDPIN) and then change the function by: LED.error or led.on... as apposed to setting a value of a variable. isn't this what most objects do? I have code to make the LED do what I want, but I don't know how to call the object and have it running on a seperate cog, waiting to run different functions. is this what your saying? that if I call an object that starts a cog blinking an LED the only way to make it do something else would be to change a variable, or stop the cog and then start it again? Thanks for helping me out so much! I really do appreciate it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-10 08:25
    hello dgswaner,

    as a direct answer to your question: Yes it is the only way.

    I'm not sure about what you want to do and what you have already understand and what not.
    I would like to understand what you want to do and therefore it would be best if you post
    your code regardless it is working or not. Programming is best learned by doing and learning from variying the code
    and seeing what is happening.

    best regards

    Stefan
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2008-07-10 10:29
    An object is a collection of functions, these can be sent to another cog or simply used in the current cog.

    If all you want to do is turn the led on and off when required then you don't need to start another cog, just create functions in the object that can be called by your main program.

    If you want the led to blink you have to ask yourself "do I want my main cog to take care of the blinking or do I want to leave it free". If you want the main cog to do the blinking then you will have to incorporate that carefully into the program, sending it into a loop will freeze the program. Of course the counters are a great way of creating a blinking led without the program having to do anything.

    If you want to leave the main cog completely free then you will have to run the object in a seperate cog, creating a start function that will do the cognew.

    Perhaps you might post a simple example program showing what you are trying to do.

    Graham
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-07-10 11:52
    I have to agree with Graham about using the counter. Seems like a better solution for your particular problem than launching a cog. However, Graham states "...you will have to run the object in a separate cog...". I hate to mince words, but something like that would be better stated "...you will have to have your object launch a separate cog process...". The reason I say this is because there is a lot of confusion about cogs and objects. An object is just set of code designed to do a specific set of tasks, with its own variable namespace. Typically, an object that launches a cog will run in more than one cog. Some functions, such as "start" or "init" are executed in the main cog, but will launch a function in the same object to run in a separate cog.

    It's best to think of a cog running a "process" rather than running an "object". The object controls which of its processes (or functions) run on separate cogs.

    There are two main reasons to launch a cog: 1. To run assembly code (because the SPIN interpreter takes up a whole cog) or 2. To more easily implement concurrent or asynchronous processes. Otherwise, for the sake of simplicity you're better off trying to run your code in one cog (like the example here where you would use timers to blink your LEDs).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2008-07-10 15:28
    Quite right Ken, I think the confusing part is that an object can and often does span multiple cogs, there might be a spin or assembly process running in new cog but the code that launched that as well as code to access variables related to that object will be running in the original cog. I created a diagram to assist in program planning that shows this but I don't have a link.

    Graham
  • DgswanerDgswaner Posts: 795
    edited 2008-07-18 05:59
    Here is the code that I came up with for controlling this LED. it works great I just don't know if there is an easier or better way of doing this. I would love some input.

    {{ LED.spin }}
    
    [b]VAR[/b]
      [b]long[/b]  Stack[noparse][[/noparse]9]                       'Stack space for new cog
      [b]byte[/b]  Cog                            'Hold ID of cog in use, if any
    [b]PUB[/b] error (Pin): Success
      Stop
      Success := (Cog := [b]cognew[/b](Toggle(Pin, 100, 0), @Stack) + 1)
    [b]PUB[/b] Online (Pin): Success
      Stop
      Success := (Cog := [b]cognew[/b](Toggle(Pin, 300, 0), @Stack) + 1)  
    [b]PUB[/b] UserWait (Pin): Success
      Stop
      Success := (Cog := [b]cognew[/b](Toggle(Pin, 1, 0), @Stack) + 1)
      
    [b]PUB[/b] BotWait (Pin): Success
      Stop
      Success := (Cog := [b]cognew[/b](blink(Pin, 100, 0), @Stack) + 1)
    [b]PUB[/b] Stop
      [b]if[/b] Cog
        [b]cogstop[/b](Cog~ - 1)
    [b]PUB[/b] Active: YesNo
    {{[b]Return[/b] [b]TRUE[/b] [b]if[/b] process is active, [b]FALSE[/b] otherwise.}}
      YesNo := Cog > 0
    [b]PUB[/b] blink(Pin, DelayMS, Count)
      [b]dira[/b][noparse][[/noparse]Pin]~~                                'Set I/O pin to output direction 
      [b]repeat[/b]                                     'repeat
         [b]repeat[/b] 4                                'Blink LED 3 times
           ![b]outa[/b][noparse][[/noparse]Pin]                            'Toggle I/O Pin
           [b]waitcnt[/b](clkfreq / 1000 * 100 + [b]cnt[/b])   'Wait for 100 MS cycles    
         [b]waitcnt[/b](clkfreq / 1000 * 500 + [b]cnt[/b])     'Wait for 500MS cycles    
      Cog~                                       'Clear Cog ID variable
    [b]PUB[/b] Toggle(Pin, DelayMS, Count)
      [b]dira[/b][noparse][[/noparse]Pin]~~                                'Set I/O pin to output direction 
      [b]repeat[/b]                                     'Repeat the following
        ![b]outa[/b][noparse][[/noparse]Pin]                               'Toggle I/O Pin
        [b]waitcnt[/b](clkfreq / 1000 * DelayMS + [b]cnt[/b])  'Wait for DelayMS cycles    
      [b]while[/b] Count := --Count #> -1               'While not 0 (make min -1)…
      Cog~                                       'Clear Cog ID variable
    
    
    



    Thanks

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner

    Post Edited (Dgswaner) : 7/18/2008 6:06:50 AM GMT
Sign In or Register to comment.