Shop OBEX P1 Docs P2 Docs Learn Events
1 Core 2 Activities - Page 2 — Parallax Forums

1 Core 2 Activities

2

Comments

  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 09:46
    jazzed wrote: »
    TV or VGA gives lots of LEDs with very few pins.
    Hi Jazzed. Good point. We may need to do that. We could easily give up the pins on the Demo Board for TV use..It could be worth it to dedicate a cog at the "upper end of the spectrum." Thanks for the method reminder.

    humanoido
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-21 17:56
    I kept this code for posterity but made a slight change to pass the pin number as a decimal value (easier with the demo board).
      dira[16..23]~~            'make pins 16 thru 23 outputs
     
      task_led_0.init(16, 100) 
      ..
      task_led_0.init(23, 170) 
    

    And use the bitwise decode operator set the led value
    PUB init(_led, _period)
      led := |< _led   'decode pin number   
      period := _period
      DIRA |= led 
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 20:49
    I kept this code for posterity but made a slight change to pass the pin number as a decimal value (easier with the demo board).
      dira[16..23]~~            'make pins 16 thru 23 outputs
     
      task_led_0.init(16, 100) 
      ..
      task_led_0.init(23, 170) 
    
    And use the bitwise decode operator set the led value
    PUB init(_led, _period)
      led := |< _led   'decode pin number   
      period := _period
      DIRA |= led 
    
    Hi Ron, thanks for the concept ideas. Can you make this into a tiny minimal working program? Thanks very much! Humanoido
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-22 03:35
    Humanoido,
    Not sure what you mean by
    tiny minimal working program

    I just took Heater's code (as he tweaked it throughout this thread) and changed the way the pin number was passed.

    main pgm
    'Example of eight cooperative tasks in Spin.
    '
    CON
      _clkmode        = xtal1 + pll16x
      _xinfreq        = 5_000_000
    VAR
      long OneMS
      long TimeBase
     
    OBJ
      'Create 8 instances of the LED flasher task object
      task_led_0 : "task_led_flasher"
      task_led_1 : "task_led_flasher"
      task_led_2 : "task_led_flasher"
      task_led_3 : "task_led_flasher"
      task_led_4 : "task_led_flasher"
      task_led_5 : "task_led_flasher"
      task_led_6 : "task_led_flasher"
      task_led_7 : "task_led_flasher"
     
    PUB start
      'Initialize 8 LED flasher tasks with different LED pins
      'and flash periods.
      [COLOR=red]dira[16..23]~~[/COLOR]
     
      task_led_0.init([COLOR=red]16[/COLOR], 100)
      task_led_1.init([COLOR=red]17[/COLOR], 110)
      task_led_2.init([COLOR=red]18[/COLOR], 120)
      task_led_3.init([COLOR=red]19[/COLOR], 130)
      task_led_4.init([COLOR=red]20[/COLOR], 140)
      task_led_5.init([COLOR=red]21[/COLOR], 150)
      task_led_6.init([COLOR=red]22[/COLOR], 160)
      task_led_7.init([COLOR=red]23[/COLOR], 170)
     
      OneMS := clkfreq / 1000                'Calculate cycles per 1 millisecond
      TimeBase := cnt                        'Get current count
     
      'Repeatedly run each tasks run method every 1ms
      repeat
        waitcnt(TimeBase += OneMS)           'Wait to start of next millisecond
        task_led_0.run
        task_led_1.run
        task_led_2.run
        task_led_3.run
        task_led_4.run
        task_led_5.run
        task_led_6.run
        task_led_7.run
    

    task_led_flasher.spin
    'LED flasher cooperative task.
    CON
      'Possible task states.
      STATE_OFF = 0
      STATE_ON = 1
    VAR
      LONG state         'State of the task
      LONG ms            'Count milliseconds here
      LONG led           'Pin to use for a LED
      LONG period        'Flash period
    'Call this first to initialize the task.
    PUB init(_led, _period)
    [COLOR=red]led := |< _led     'Decode pin number[/COLOR]             
      period := _period
      DIRA |= led
    'Call this every millisecond to "kick" the task along
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    PUB run
      ms++
      case state
        STATE_OFF:
          if (ms // period) == 0
             OUTA |= led               'Put LED on
            state := STATE_ON
        STATE_ON:
          if (ms // period) == 0
            OUTA &= !led               'Put LED off
            state := STATE_OFF
        OTHER:
          'WTF? 
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-22 14:38
    Hi Ron, now I see what you're thinking with the posted code. It does make pin and LED identification much easier.

    Strange thing happened today. I came back to run the programs that have two files and none of the programs would run correctly. I still haven't figured it out.

    I have both files in the same folder, so there shouldn't be a problem. One program does not run at all (no led light) and the second program does a quick blink on pin p7 (yesterday it was blinking p0 through p7). I'll see about getting this to work today.

    Humanoido
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-22 16:03
    Make sure you select the Top Object File (right click the tab of the top most program)
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-22 19:31
    Make sure you select the Top Object File (right click the tab of the top most program)
    Thanks Ron, I tried that but no effect. I started over with the program, made all the revisions again, and it's still not working - very odd indeed. Since LED 8 is doing some quick blinking, it appears the program is doing something. I'll look at it a third time and wear out the prop book some more, but may need to wait for Heater's help on this one.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 07:58
    Here's the Spin program to flash 8 LEDs on pin 0 through 7 using methods. The code only flashes the LED on pin 7. Is it a variable problem?
  • Heater.Heater. Posts: 21,230
    edited 2010-08-23 08:45
    You have lost the OUTA mods I post a while pack:
    OUTA |= led                'Put LED on
    
    OUTA &= !led               'Put LED off
    

    Try the attached versions which includes Ron's pin decode mod and splits the init and run parts of the main program into separate methods.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 09:56
    Heater. wrote: »
    You have lost the OUTA mods I post a while pack:
    OUTA |= led                'Put LED on
    OUTA &= !led               'Put LED off
    
    Try the attached versions which includes Ron's pin decode mod and splits the init and run parts of the main program into separate methods.
    Heater, when this is run, the LED on pin 7 lights up steady, the others are off. Did that happen when you ran it?
  • Heater.Heater. Posts: 21,230
    edited 2010-08-23 10:16
    Me run it? I haven't fired up the soldering iron yet.

    Can't immediately see what's up. Try commenting out all the run methods except one. Then a different one. etc.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2010-08-23 10:25
    Sorry to be a bolt out of the blue, but PJV wrote the PropRTOS for the Propeller Contest and can do this independenly for many, many LEDs. His example claims over a hundred, and demos 8 in code.

    http://www.parallax.com/PropRTOS/tabid/852/Default.aspx
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 10:35
    Heater, thanks for the suggestions. I commented out all the tasks except the LED on pin 0. Running the program, LED on pin 0 lights up, but no blinking. The bug could be in task_led_flasher.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-23 17:51
    This code for task_led_flasher is even simpler -
    the "run" method is 3 lines...
    'Example of eight cooperative tasks in Spin.
    '
    CON
      _clkmode        = xtal1 + pll16x
      _xinfreq        = 5_000_000
    VAR
      long OneMS
      long TimeBase
     
    OBJ
      'Create 8 instances of the LED flasher task object
      task_led_0 : "task_led_flasher"
      task_led_1 : "task_led_flasher"
      task_led_2 : "task_led_flasher"
      task_led_3 : "task_led_flasher"
      task_led_4 : "task_led_flasher"
      task_led_5 : "task_led_flasher"
      task_led_6 : "task_led_flasher"
      task_led_7 : "task_led_flasher"
    PUB start
      'Initialize 8 LED flasher tasks with different LED pins
      'and flash periods.
      dira[16..23]~~
     
      task_led_0.init(16, 100)
      task_led_1.init(17, 110)
      task_led_2.init(18, 120)
      task_led_3.init(19, 130)
      task_led_4.init(20, 140)
      task_led_5.init(21, 150)
      task_led_6.init(22, 160)
      task_led_7.init(23, 170)
      OneMS := clkfreq / 1000                'Calculate cycles per 1 millisecond
      TimeBase := cnt                        'Get current count
      'Repeatedly run each tasks run method every 1ms
      repeat
        waitcnt(TimeBase += OneMS)           'Wait to start of next millisecond
        task_led_0.run
        task_led_1.run
        task_led_2.run
        task_led_3.run
        task_led_4.run
        task_led_5.run
        task_led_6.run
        task_led_7.run
    
    'LED flasher cooperative task.
    CON
    VAR
      LONG ms            'Count milliseconds here
      LONG led           'Pin to use for a LED
      LONG period        'Flash period
    'Call this first to initialize the task.
    PUB init(_led, _period)
      led := _led
      period := _period
      DIRA[led]~~  
    'Call this every millisecond to "kick" the task along
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    PUB run
      ms++
      if (ms // period) == 0
        !OUTA[led]           'toggle led
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 18:49
    Ron Czapala said: This code for task_led_flasher is even simpler -
    the "run" method is 3 lines...

    Ron, this is fantastic but I have one question - did you run it on your prop board and did it test "working"?
    I will try the code in a few minutes..
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-23 18:58
    I am using it on the demo board which is why I use pins 16 to 23
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-23 18:59
    Could we also please cut down the main object a bit like this (tested on the demoboard)?
    'Example of eight cooperative tasks in Spin.
    '
    CON
      _clkmode        = xtal1 + pll16x
      _xinfreq        = 5_000_000
    
    VAR
      long OneMS
      long TimeBase
     
    OBJ
      'Create 8 instances of the LED flasher task object
      task_led[8]: "task_led_flasher"
    
    PUB start | n
      'Initialize 8 LED flasher tasks with different LED pins
      'and flash periods.
      dira[16..23]~~
    
      repeat n from 0 to 7
        task_led[n].init(16 + n, 100 + n * 10)
    
      OneMS := clkfreq / 1000                'Calculate cycles per 1 millisecond
      TimeBase := cnt                        'Get current count
      'Repeatedly run each tasks run method every 1ms
    
      repeat
        waitcnt(TimeBase += OneMS)           'Wait to start of next millisecond
        repeat n from 0 to 7
          task_led[n].run
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 19:13
    Hi Ron, I ran the code on a Demo Board just now and this shorter version is working. I personally think you have a monopoly on magic wands. :) I look forward to loading the code with more threads and exploring it in more detail when I get the new prop circuit up and running with 32 lights. You know, this is a clever program because it's down to the minimum number of code statements and it's going to make task loading and adding other functions more easy.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 19:15
    I am using it on the demo board which is why I use pins 16 to 23
    Ron, I noticed that and it's a good thing too because you can test it and see if it works and because I have a demo board too for compatibility. It just makes things go more smooth.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 19:34
    Kuroneko wrote: Could we also cut down the main object a bit like this (tested on the demoboard)?

    Yes we could. Great programming and testing. It looks and works very efficient and the thought you put into this is appreciated. This file makes a good companion file Ron's recent file entry. Keeping the code efficient like this is a plus, as we're working inside one cog for the 8 threads, and plan a future expansion.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 20:00
    Kuroneko's EDIT: Could we also please cut down the main object a bit like this (tested on the demoboard)? Last edited by kuroneko; Today at 06:20 PM. Reason: be more polite

    Kuroneko, (thank you for your added politeness) I see you added the word "please" by special edit. It is amazing you did that (one small word - it almost went unnoticed) and it's very kind of you, and thank you very much for being polite. There are many good lessons to learn from you, in addition to Spin programming.

    Humanoido
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-23 20:11
    PUB run
      ms++
      if (ms // period) == 0
        !OUTA[led]           'toggle led
    
    Probably not too important for the intended use but ms++ will overflow at some point and depending on period this will result in the on/off period being slightly inaccurate. May I suggest something like:
    PUB run
      ms++
      ifnot ms //= period
        !outa[led]
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-23 20:54
    kuroneko wrote: »
    Probably not too important for the intended use but ms++ will overflow at some point and depending on period this will result in the on/off period being slightly inaccurate. May I suggest something like:
    PUB run
      ms++
      ifnot ms //= period
        !outa[led]
    
    Actually I believe the timing is important as the flashing of LEDs is only to verify the threads are working. The actual LEDs will be replaced with other routines that may have real time clocks and other timing sensitive code. Thank you for deriving this important improvement to the code.

    Humanoido
  • Heater.Heater. Posts: 21,230
    edited 2010-08-23 23:31
    Ron Czapala,

    Yes you can cut the run method down. Ultimately this whole program all but disappears. But the whole point of the example was to show a way of creating independent tasks that had their own state machine. Without needing multiple COGs and state implicitly maintained by the Spin program counters.

    kuroneko,

    Similarly and array of LED tasks is a neat idea but in the general case the tasks are not all the same.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-24 00:41
    Heater. wrote: »
    Similarly and array of LED tasks is a neat idea but in the general case the tasks are not all the same.

    Point taken. It just looked so annoyingly verbose I couldn't resist :)
  • Heater.Heater. Posts: 21,230
    edited 2010-08-24 00:51
    kuroneko:
    It just looked so annoyingly verbose I couldn't resist

    I am, aren't I?:)

    Now if only Spin objects had inheritance all kinds of different task objects could inherit a "run" method from a "task"object and be handled in an array as you suggest.

    I bet someone here knows a sneaky way to fool Spin into doing that.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-24 06:15
    Heater. wrote: »
    Ron Czapala, Yes you can cut the run method down. Ultimately this whole program all but disappears. But the whole point of the example was to show a way of creating independent tasks that had their own state machine. Without needing multiple COGs and state implicitly maintained by the Spin program counters. kuroneko, Similarly <an> array of LED tasks is a neat idea but in the general case the tasks are not all the same.
    Heater, this is a good point because LEDs will be substituted with actual processing tasks all happening independently in a single cog.

    How shall I refer to each of the two Spin files? A Method file that calls the Object file?

    And most importantly, which version of each file best represents and accomplishes "creating independent tasks that have their own state machine without needing multiple COGs, and state implicitly maintained by the Spin program counters?"

    Humanoido
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-24 07:16
    Heater - Humanoido's original statement was:

    "One tiny spin program in 1 cog multi-tasks 2 simple and separate activities - blinking 2 LEDs. Blinking rate can be slow: half second on/off for one LED, 1 second on/off for the other. What is the smallest code example to do this?"

    Humanoido's goal seems to have evolved from just blinking LEDs to some sort of task manager. Until his specific program requirements are defined (maintaining state, parallel processing with mutliple cogs, etc) we can only speculate what the best approach may be...

    Since he was having trouble getting the program to run (which worked fine after you made the change in post #20 http://forums.parallax.com/showpost.php?p=933016&postcount=20), I simplified the code in his search for the "smallest code".

    In this particular program, the state of an output pin can be checked using something like "if outa[led]" rather keeping the value in a variable.
  • Heater.Heater. Posts: 21,230
    edited 2010-08-24 07:25
    Fair enough Ron,

    Until the spec is tightened up almost any solution will do:)

    I was rather concentrating on the "separate activities" and "multi-tasks" which I take to mean they have their own state. "one cog" meaning we don't have the luxury of real multi tasking. "spin program", we have to do it in Spin.

    Edit: My introduction of a state variable was just to hint that this could be expanded to more complicated tasks.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-24 07:41
    The last system I worked on before I retired was an Intranet application using Visual Studio, SQLSERVER, HTML, Visual Basic, IIS servers, Javascript, and message queues (between IBM mainframes using CICS to web applications).

    Part of our requirements was a stateless programming model because a user might start an update activity but never complete it.
    So depending on your needs, stateless vs stateful becomes an issue.

    The devil is in the details...:smilewinkgrin:

    EDIT: In fact, it is easy to imagine a scenario where trying to maintain state using a variable could introduce a bug. Since the pins are shared resources between cogs, one cog might set an output pin high and save that state in a variable. The next cog may be monitoring a sensor and deterimine that pin needs to be set low. When the first cog gets control and checks the state variable, it indicates the pin is high when actually it is low. The propeller makes it easy to check the pin's status.
Sign In or Register to comment.