Shop OBEX P1 Docs P2 Docs Learn Events
Why is this P2 second cog does not work? — Parallax Forums

Why is this P2 second cog does not work?

msiriwardenamsiriwardena Posts: 301
edited 2021-02-08 20:06 in Propeller 2

I am trying to display, Time and temp on the LCD and Display Temp and humidity on the 7Seg LED.
Also trying to start second cog to run either of the methods : 1. RealTime()
2.TempHumidity()
I have placed the " cogspin(1, TempHumidity(), @tempStack) statement in:
1.setup()
2.In "RealTime() method"
3.InTempHumidity method()
3.In the main method() 1.before setup()
2. after setup
3. in the setup() method
The result is either the LCD displays- time & temp OR the 7Seg LED displays
Humidity & Temp. Both displays but not the display at the same time.

I hope some one point out the mistake and show the correct way start a second cog.
A clear example of starting a second cog is appreciated.

Thank you,

Siri
PS: archived file attached.
Sir

Comments

  • Cluso99Cluso99 Posts: 18,069

    This is likely your problem

       cogspin(1,TempHumidity() ,@tempStack) 
       'cogspin(0, RealTime(), @stack)                                                  '
        cogspin(1,TempHumidity() ,@tempStack)
    

    Here you are starting cog #1 with TempHumidity. And then restarting it again.
    Note cog #0 restart is commented out.

    You may have other cogs running depending on the objects - I didn;t look. If so, then the first is likely cog #1 and you would be clobbering it.

    It's preferable to use cog #16 (pre-defined in spin as COGEXEC_NEW) which is a placeholder to start the next available cog.
    But you have other cogs running and one of those is already using cog #1 so you are clobbering that code.

    Here is an example of starting a free cog (pasm example). Note it returns the cog+1 number of the cog started (a common usage for P1 & P2), and 0 if not started (error)

      cog := coginit(COGEXEC_NEW, @uart_mgr, @rxp) + 1              ' start uart manager cog
    
  • @Cluso99

    Thanks helping me.
    What really worked is : cogspin(1, TempHumidity(), @tempStack)
    cogspin(0, RealTime(), @timeStack)

    If the cog(O) was started first the program will not work.The cog(1) had to be started firrst and the cog(0).
    Seems wired but thats how I resoved my cog issue.

    Thanks again for helping me

    Siri

  • AJLAJL Posts: 515
    edited 2021-02-09 13:30

    When your program first starts it is running in cog0. If you then do a coginit (or cogspin) on cog0 it will stop the running program and anything after that will not run.
    Unless you have some particular need to use cog0 you are better off launching new processes in the other cogs.
    In general, unless you feel the need to launch your code in a particular cog you should use cog16, as Cluso has already mentioned.

  • @Cluso99

    I understand what your pointing out. But if i do this -

    setup()

    RealTime()

    cogspin(1, TempHumidity(), @tempStack)
    ' cogspin(0, RealTime(), @timeStack) - " this line is commented out"

    Only the TempHumidity is executed and RealTime method is not executed.

    Thanks again for your help,

    Siri

  • cgraceycgracey Posts: 14,133
    edited 2021-02-09 14:08

    Is it because the 2nd COGSPIN is commented out?

    Also, always remember that when you set some pin outputs and then launch another Cog, that new cog does not inherit the prior cog's output configuration, but must set its own.

  • msiriwardenamsiriwardena Posts: 301
    edited 2021-02-09 15:33

    @Gracey

    Thanks for the help.
    I seem to have an hardware issue. When I start my jonnymac board with P2 edge first thing in the morning,
    the program that is in the flash does not run completely only one that is in cog(0) and also if I turn P2 board off
    and restart same issue recur. Then when I press the reset button the whole program runs as expected.
    Since the cog(0) starts automatically and run main() as this is the first method.
    If I change the code to ;

    pub main() 
       setup()
         RealTime()                                                                           - this is executed  by cog(0)
        cogspin(1, TempHumidity(), @tempStack)                     - this to be executed by cog(1)      - which does not execute
    

    The cog(1) will not start and execute the method "TempHumidity()".The cog(0) executes the method " RealTime()".No matter what cog number I use , the cog will not run.

    Thanks again,

    Siri

  • This is your main method.

    pub main()
    
      setup()
      RealTime()
      cogspin(1,TempHumidity() ,@tempStack)
    

    It calls a RealTime() which never returns, so the cogspin doesn't run.

  • @JonnyMac

    I have no idea at all how to make the ReaTime() return to the main().
    I looked in the P1 manual for " return" and added return to the end of the RealTime() method.
    I still have the same issue.
    I know this is a minor issue but I have run out of ideas.

    Thanks for Helping me,

    Siri

  • JonnyMacJonnyMac Posts: 8,927
    edited 2021-02-09 18:00

    I looked in the P1 manual for " return" and added return to the end of the RealTime() method.

    That method uses a repeat loop that never breaks, hence it cannot return

    If you want RealTime() to run forever, that's fine -- start your background cog first and then drop into RealTime().

  • JonnyMacJonnyMac Posts: 8,927
    edited 2021-02-09 20:44

    Programming requires thought; the copy-and-paste-and-hope game is usually not enough.

    • You don't need to consume valuable cogs
    • You are attempting to launch a method into a cog from within that method -- this won't work.

    To prove that you don't need cogs, I had a cup of coffee (to give myself time to think), and then recrafted the program so that the displays are updated as desired. Once it was working, I analyzed it and found that the MAX7219 display (I use the smart pins version) takes 6 milliseconds to refresh, and the LCD takes 41ms to update. This leaves a lot of time in your main loop to do other things. Mind you, those 6 and 41 millisecond delays only happen when the displays are updated; when it's not time for an update the call takes about 5 microseconds to check the timer.

    Instead of separate cogs I am using a simple scheduling mechanism. The MAX7219 is updated every 2 seconds, and what gets displayed is controlled by a phase variable. Likewise, the LCD is updated every second. Note that the DHT22 is checked first and its values stored in global values so that they can be used in the LCD update.

    I will repeat what I said in my first presentation on Propeller programming: spend 80% of your time thinking, 20% of your time doing. I will amend that to say it's even more critical when copying code from previously-working programs -- there is a danger of taking things for granted and falling into giant potholes.

  • @ jonnymac
    You have showed me the real art of programming .I will study your program at every stage and understand your thought process so I can emulate
    in my future programing. You are an patient and great teacher.
    In my profession(physician) there many(majority) of them treat patients symptomatically(patch work - as my programming ). The good physicians make
    have list of differential diagnosis and rule each one out to come to a final diagnosis. This how I taught the residents but most of them opt out to do the easy
    way by treating the symptoms having no idea what disease they are treating only to get patients into more severe stages of the disease.

    Thank you for opening the door to real programming.

    Siri

  • JonnyMacJonnyMac Posts: 8,927
    edited 2021-02-12 05:01

    Programming is a technical art, and as humans, artists will approach in their own ways. When I started programming, I looked at examples of other programs -- I was not just looking for a solution, but the logic to that solution. I will never claim that mine was is the right way, but I will defend it as right for me. I will also be able to defend my logic (many fail at that part).

    My acting teacher, the amazing Cliff Osmond, used to say, "There are many great roads that lead to Rome." What he meant is that each actor is different, so he was skilled in all of the schools of acting training and would apply it individually to the actor.

    Your program could have been accomplished with multiple cogs (again, many great roads). When I started programming, resources were very scarce so I conserved them. In the Propeller world, I only start a cog if I absolutely have to. In the P1 this is more frequent than the P2.

    I'm sure that during a complex diagnosis you start by verifying what is right, which helps to isolate what is wrong. You probably decide the order of testing based on dependencies. That's what I did with your program; I took these steps

    -- connected hardware to my JonnyMac PCB
    -- verified that each device worked independently
    -- analyzed your desired outcome to determine best behavior
    -- plotted a course
    -- worked through that one piece at a time

    You'll note the decision to check temperature before time; this decision was made because the time display also includes the temperature.

    Hopefully, too, you've learned a new strategy for handling multiple processes without consuming valuable cogs. Now, in some cases we will be required to use a cog -- for example, when the timing of events is absolutely critical. Updating time and temperature displays do not fall into that category. This means that you could add more code to your main loop. Even if that ran a little long, the other processes would catch up.

    This code, which determines if the method should run now or immediately return is very deliberate:

      if ((getms()-timer1) < 0)                                     ' time to update?
        return                                                      ' no
      else
        timer1 += TMR_TEMP                                          ' yes, set next update time
    

    The first line checks for the expiration of the desired period. Note that anything below 0 means NO, anything 0 or above means YES. This gives us wiggle. Note, too, that when the timer has expired that we advance it based on the previous target, not the actual time. This allows the system to re-align with the original timer start.

    My final step was to take measurements of the time required to update both displays -- turns out that it's less than 50ms when both displays are updated, and that 50ms is not consumed during every loop. This means there is a lot of free time to do other things.

    Funny, my two favorite TV shows about physicians are "Doc Martin" and "House." Both fictional doctors are kind of cranky (I am, too), but love their job, and dedicate themselves to thinking through problems. As a physician, you know how to think through complex issues; with a bit of practice, you will learn to apply your ability to think to coding projects -- and magic will happen.

  • @JonnyMac
    Your explanation how you planned your action to my desired outcome shows me you took your precious time to help me to understand the art of programming.
    It is identical to taking care of the critically ill patients, first take care of the emergent issues then plan the extended care while patient recovers from the emergency,
    evaluating the progress along the way to recovery and making necessary adjustments to the management.

    Thank you very much

    siri

  • @msiriwardena said:
    @JonnyMac
    Your explanation how you planned your action to my desired outcome shows me you took your precious time to help me to understand the art of programming.
    It is identical to taking care of the critically ill patients, first take care of the emergent issues then plan the extended care while patient recovers from the emergency,
    evaluating the progress along the way to recovery and making necessary adjustments to the management.

    That is a very astute metaphor! I will definitely remember that one, it puts a very useful-in-practice spin on things :)

Sign In or Register to comment.