Shop OBEX P1 Docs P2 Docs Learn Events
Need Help running multiple cogs — Parallax Forums

Need Help running multiple cogs

garyggaryg Posts: 420
edited 2014-09-30 18:32 in Propeller 1
Hi
I'm working on setting up a pump timer gizmo.
It's my 1st OBEX plus cut/paste/modify project.
I'm using FullDuplexSerial, RealTimeClock.spin, RTC_DEMO.spin and another object I'm trying to
run on yet a separate cog.

I modified, With Help, RTC_DEMO to drive my LCD serial display.
It appears to be working correctly

Now, I'm trying to get my PumpControl.spin to play along.
I'm sure there is something very fundamental that I'm not understanding.

This is how I'm trying to start the PumpControl:

'Start Real time clock
RTC.Start

'Start the Pump Control
Pumps.Start 'The PumpControl.spin needs the start/stop subroutines set up properly to run in a new cog.
'Now this Pumps.Start compiles correctly without errors.
'ON STARTUP PROGRAM STOPS WHEN IT GETS TO Pumps.Start

'Preset time/date... nice demostration of rollovers..
RTC.SetTime (hrset,minset,secset) '(23,59,50) '10 seconds to midnight
RTC.SetDate(16,9,14) '31,12,07 'New years eve, 2007

'
'


The following is the PumpControl.spin
{{
 I'm starting my Pump Control by saving the RealTimeClock.spin file as PumpControl.spin
 I'll set up simialar variable blocks etc and try to get this thing to turn on the Blue LED's
 Blue LED's on the Quickstart board when a particular hour and minute are reached.
 

}}
                                         
VAR
             
  ''Global vars...
  'long Cog                                              'Cog issued tracking
  long PumpStack[32]                                     'Stack for PumpControl object in new cog
  byte Pumps                                             'Pumps stores the CogID of the new cog.
 'gg I'm not sure what this start:Success thing is all about
 'I Kept it in case I need it later.
  
'PUB Start:Success 'Start the RTC object in a new cog...

 ' If not cog                                            'RTC not already started
 '   Success := Cog := Cognew(RtcMain(@LclRtc),@RtcStack)  'Start in new cog
 
'PUB Stop 'Stops the Real Time Clock object, frees a cog.

 ' If Cog
 '   Cogstop(Cog)


PUB Start             'Start is from Spin Language Reference -COGNEW page 81
  Stop
  Pumps := cognew (Pump1, @PumpStack)
PUB Stop                     'Stop is from Spin Language Reference -COGNEW page 81 
  if Pumps>-1
    cogstop(Pumps)    
PUB Pump1 

   ' Pin 16 is the buzzer, make it an output and set it low.
  dira[16] := 1
  outa[16] := 0
  
  'Pin 20 is the center LED on the Quickstart board, Make it an output and set it low.
  dira[20] := 1
  outa[20] := 0
                 
  Blink20 
PUB Blink20

'I want the P20 center led on the Quickstart to start blinking at some rate while the
'clock is running and displaying things on the LCD monitor.


  repeat
  !outa[20]
  waitcnt(3_000_000+cnt)

            
 'This should run forever in a single new cog.


When I run the program, I can set the current time and start RTC, but the PumpControl causes everything to stop working.
If I remark out the Pumps.Start line, I get proper time display, but my pumps blue flashing led does not work.
If you need more information to help me out, please ask.

Thanks
Garyg

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-09-17 14:39
    I'm not sure if this will solve your problem but the way the method "Blink20" is currently written it won't blink the LED. You need to indent the code after the repeat command as shown below.
    PUB Blink20
    
    'I want the P20 center led on the Quickstart to start blinking at some rate while the
    'clock is running and displaying things on the LCD monitor.
    
    
      repeat
        !outa[20]
        waitcnt(3_000_000+cnt)
    
                
     'This should run forever in a single new cog.
    
  • garyggaryg Posts: 420
    edited 2014-09-17 14:54
    Thanks Duane
    I modified the Blink20 method.
    I should have seen that.
    Now the repeat tracking lines show up.

    However:
    Program still does not seem to continue after running the Pumps.start line.
    I'm thinking that I goofed up in the PUB Start, PUB Stop part of this object.
    This is the 1st time I'm trying to get something I've written running on a separate cog.

    garyg
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-09-17 15:03
    I'm not sure what you're trying to do.

    The Start method start a new cog but the original cog is left to die.

    The RTC stuff looks incomplete. Did you just post a portion of the code?
  • Mike GreenMike Green Posts: 23,101
    edited 2014-09-17 15:12
    You really need to post your entire program including any referenced objects. I suggest making an archive using the Propeller Tool or the Zip function of SimpleIDE including everything. That way we can be sure we're looking at the same version as you are. Post the archive using the forum's file manager that you get by clicking on the Go Advanced button.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-09-17 15:21
    Tips:

    -- Describe the outcome in bigger terms -- defining it in code that you're struggling with isn't very helpful
    -- Use named constants for pins -- "magic numbers" often lead to bugs and can cause one part of a program to interfere with another
    -- Do you need an RTC? Or do you just want to run for a specific amount of time?
    -- You may be able to start your RTC in the global space

    If you just want to run your pump and flash an LED for a specific time -- in a separate cog -- the attached demo will be helpful.
  • garyggaryg Posts: 420
    edited 2014-09-17 16:30
    Hi again, Thanks for your comments.
    I'll attempt to clarify. This may get a bit long winded.

    Duane, " The Start method start a new cog but the original cog is left to die".
    That is exactly what I don't want to happen, but death of the original cog is exactly my problem.

    Mike, I used the Propeller Tool to make an archive
    I'll attempt to attach it. RTC_DEMO-GGMODIFIED3-PumpControl2 - Archive [Date 2014.09.17 Time 18.14].zip

    Jonny, My computer wants to save your attachment as a PNG file. I don't know what that is.
    I attempted to clean up my commenting of code, but am still using pins.

    I'll Submit this reply, then post again explaining exactly what this gizmo is supposed to do.
  • garyggaryg Posts: 420
    edited 2014-09-17 16:58
    Hi again.
    In post #7 I tried to answer requests of post #6.

    Now in this post, I'll explain exactly what it is and what it will do.

    I'm working on a timer system to be used in next years Hydroponic Garden.
    The timer will control water flow to neutrient feed pumps and makeup water pumps.

    I'm using a Propeller Quickstart board and 2line Parallax Serial LCD display to show time.

    On Propeller Reset, The program places 0,0,0 as current time and waits until I wish to set the current time.
    I press button 15 and hold it while pressing either button 11(sets hours) or button 12(sets minutes)
    I keep pressing button 15 until my watch reads the same as my setting, then I release button 15.
    My initial time setting is now complete.

    RTC real time clock starts at the time I set and displays current time on my LCD display.

    I display the hours number on the 2nd line of the display, just to show I can use hours from the RTC raw data.

    Now that the display is working correctly, It keeps very accurate time over a number of days as far as I can tell so far.
    I want to control pump cycle times.

    My thought is to start by getting another object, PumpControl2, to run in a separate cog.
    For now, PumpControl2 should only flash the blue LED P20 on the Quickstart board.

    I wanted to keep PumpControl2 as simple as possible because I do not understand how to set up the PumpControl2 to
    run in a separate cog.

    If the LCD clock keeps good time and the P20 LED is flashing, this would tell me that I have successfully started the
    Pumpcontrol in it's own cog.

    The end game here is to always have the LCD display showing correct time, When pumps are running I will display pump1 on/off Pump2 on/off
    on the 2nd line of the LCD display.

    I have come up with a simple uninterruptable power strategy using a simple relay circuit.
    With battery connected and power switch turned on, the power comes from the battery.
    When I plug in my 7.5Vdc wall wart supply, the relay picks and the power to the Quickstart circuitry comes from the Wall Wart.
    I needed to add 2000uF capacitor to the regulated side of my supply to make up for the time in which the relay is changing states,
    but it appears to be working pretty good so far.

    I'll attempt to Post my code.

    This is the main program:
    CON ''System Parameters
    
      _CLKMODE = XTAL1 + PLL16X                             {Clock type HS XTAL, + P.L.L. with 16x multiplier}
      _XINFREQ = 5_000_000                                  {Crystal frequency 5.000Mhz}       
      '(16*5Mhz) = 80.000Mhz clock
    
      _STACK = 1024                                         {reserve 1K of longs for stack... overkill!!}
    
    CON ''Date string return format type constants..
    
      UkFormat = 0                                          'False (zero)
      UsaFormat = 1                                         'True (non-zero)
    
      'GG added the following line, copied from other program.
      TxPin = 8   'TXPIN IS PIN #8 ON THE QUICKSTART BOARD.                                                   
    VAR
    
      byte Counter
      byte Secs                                             'Seconds passed
      word hrset                                            'gghours number
      word minset                                           'ggminutes number
      word secset                                           'ggseconds number
    OBJ
    
      RTC: "RealTimeClock"
      LCD : "FullDuplexSerial"
      Pumps : "PumpControl2"
    PUB Main  'Real time clock initial setup
     
      'set up for initial gg preset of the clock by pushing buttons
      '12 Oclock Midnight is written 0hours, 0minutes, 0seconds
      hrset:= 0
      minset:= 0
      secset:= 0
      
    
    ' Make pins 11,12 and 15 input
    ' Pin 15 will allow setting of time, Pin 11 will be hours, pin 12 will be minutes.  Seconds will stay at 0.
    dira[11] := 0
    dira[12] := 0
    dira[15] := 0
    
    ' Pin 16 is the buzzer, make it an output and set it low.
    dira[16] := 1
    outa[16] := 0
      
    
      LCD.start(TxPin, TxPin, %1000, 9_600)  'This is setting for LCD display.LCD will replace CommPort in this program.
    
    'Set up and display initial clock LCD view.
       
      WaitCnt(ClkFreq / 100 + Cnt)          ' Pause to initialize
      LCD.tx(12)                            ' Clear
      LCD.tx(17)                            ' Turn on backlight
      LCD.str(String("Time"))               ' First line
      LCD.tx(13)                            ' Line feed
      LCD.str(String("ON/OFF"))             ' Second line
      LCD.tx(212)                           ' Set quarter note
      LCD.tx(220)                           ' A tone             
      'WaitCnt(ClkFreq * 3 + Cnt)           ' Wait 3 seconds
      LCD.tx(18)                            ' Turn off backlight
    
    
      DisplayTime 
                                            'Set up and display initial time values
    pub DisplayTime                                   
     'This needs to leave the Time and ON/OFF text alone.
     'Then clear the space used to display the Time and ON/OFF values and
     'print the initial values of Time and ON/OFF.
     'The repeat needs to drop out when the Pin15 button is pressed.
     'This was originally used in the Motor1 Motor2 speed display.
     
      LCD.TX(134)                    'Move cursor to line 0, position 6
      LCD.Dec(hrset)                 'Print hourset data to LCD display                         
      LCD.TX(137)                    'Move cursor to line0, position 9
      LCD.Dec(minset)                'Print minset data to LCD
      LCD.TX(139)                    ' Move cursor to line 0, position 11
      LCD.Dec(secset)                'Print minsec data to LCD 
      WaitCnt(ClkFreq * 1 + Cnt)     ' Wait 1 second, This is important so speed changes happen not too quickly.
      
      TimeSetting
    pub TimeSetting
     'if pushbutton is pressed, increase or decrease the hours, minutes and seconds.
      repeat
             Waitpeq (|<15, |<15, 0)                      'Pause program execution until button is pressed and held.
                                           
    
                                                 
         If INA[11]==1 and INA[15]==1                     'Holding pushbuttons 11 and 15 should increment the hours
           'increment the hours from 0 thru 24
           hrset:=hrset+1
           if hrset > 23
             hrset:=0
           DisplayTime
            WaitCnt(ClkFreq * 1 + Cnt)     
        
         If INA[12]==1  and INA[15]==1                   'Holding pushbuttons 12 and 15 should increment the minutes.
           'increment the minutes from 0 thru 60
           minset:=minset+1
           If minset >59
             minset:=0
           DisplayTime
            WaitCnt(ClkFreq * 1 + Cnt)     
         If INA[15]==0
           quit                
     
    'Start Real time clock
      RTC.Start
                                     
    'Start the Pump Control
      Pumps.Start  'The PumpControl.spin needs the start/stop subroutines set up properly to run in a new cog.
                   'Now this Pumps.Start compiles correctly without errors.
                   'ON STARTUP PROGRAM STOPS WHEN IT GETS TO Pumps.Start                                               
    
      'Preset time/date... nice demostration of rollovers..
      RTC.SetTime (hrset,minset,secset)                     'On startup this will be (0, 0, 0)
      RTC.SetDate(16,9,14)                                  '31,12,07 New years eve, 2007
    
    '-------------------------------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------------------------------
    
    LCD.tx(12)                                             'Form Feed, Cursor is moved to position 0 on line 0 and
      WaitCnt(ClkFreq * 1 + Cnt)                            
                                           
     ' LCD.tx(17)           'Turn on backlight
      
      LCD.str(String("Time"))    ' First line  'CommPort.Str(String("Time:"))                                     
    
    '-------------------------------------------------------------------------------------------------------  
     repeat
      
        'Wait for next second to pass, rather than constantly sending time/date to debug comms
        Secs := RTC.ReadTimeReg(0)                          'Read current second
        repeat while Secs == RTC.ReadTimeReg(0)             'Wait until second changes
             '
                  LCD.TX(134)                               'Move cursor to line 0, position 6
             LCD.Str(RTC.ReadStrTime)                       'Time should display here. 
                  LCD.TX(10)                                'gg Linefeed to LCD. This should clear lower line to make ready for hour data.
                  LCD.TX(148)                               'gg Move cursor to line 1 position 0
             LCD.Dec(RTC.ReadTimeReg(2))                    'gg This should print the hour from raw data in RTC program.    
    
    
       
            
    '-------------------------------------------------------------------------------------------------------
    'End of Object Code.
    

    This is the real time clock code.
    {{
    
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474; RealTimeClock.spin       Version 1.01    &#9474;
    &#9474; Author: Mathew Brown                     &#9474;               
    &#9474; Copyright (c) 2008 Mathew Brown          &#9474;               
    &#9474; See end of file for terms of use.        &#9474;                
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    
    Real time clock object/methods.
    
    Starts a real time clock in a new cog.
    This clock tracks both time, and date, and includes days in month/leap year day corrections.
    
    Time/date can be set using the following...
    
    1) Via direct writes to timekeeping registers
    2) Via time & date setting methods
    3) Via loading with a 32 bit packed Microsoft format time
    
    Time/date can be read using the following...
    
    1) Via direct reads from timekeeping registers
    2) Via return as strings representing time / date
    3) Via return of a 32 bit packed Microsoft format time
    
    ------------------------------------------------------
    Revision 1.01 changes:-
    Added day of week funtionality.
    ------------------------------------------------------  
    }}
                                             
    VAR
                 
      ''Global vars...
      long Cog                                              'Cog issued tracking
      long RtcStack[32]                                     'Stack for RTC object in new cog
    
      'The following must be contigious...
      '[
      Byte LclRtc[7]                                        'Local real time clock counters
      Byte TimeDate[7]                                      'Time/date return registers
      ']
    
      
    PUB Start:Success 'Start the RTC object in a new cog...
    
      If not cog                                            'RTC not already started
        Success := Cog := Cognew(RtcMain(@LclRtc),@RtcStack)  'Start in new cog
     
    PUB Stop 'Stops the Real Time Clock object, frees a cog.
    
      If Cog
        Cogstop(Cog)
      
    PUB ReadTimeReg(Index):Value 'Allows calling object to query timekeeping registers, individually
    
    { Index = 0, indexes seconds       .. 'value' in range 0 to 59
      Index = 1, indexes minutes       .. 'value' in range 0 to 59
      Index = 2, indexes hours         .. 'value' in range 0 to 23
      Index = 3, indexes days          .. 'value' in range 1 up-to 31 (month dependant)
      Index = 4, indexes months        .. 'value' in range 1 to 12
      Index = 5, indexes years         .. 'value' in range 0 to 99    (00 = 2000.... 99 = 2099)
      Index = 6, indexes day of week   .. 'value' in range 1 to 7     (1 = Sunday.... 7 = Saturday)       
    }
    
      Value := byte[@TimeDate][Index]                       'Read data from double buffered read registers
    
      If Lookdown(Index:3,4,6)                              'Adjust 0 indexed days/months/day of week, to 1 indexed
        Value++
       
    PUB WriteTimeReg(Index,Value) 'Allows calling object to write to timekeeping registers, individually
    
    { Index = 0, indexes seconds       .. 'value' in range 0 to 59
      Index = 1, indexes minutes       .. 'value' in range 0 to 59
      Index = 2, indexes hours         .. 'value' in range 0 to 23
      Index = 3, indexes days          .. 'value' in range 1 up-to 31 (month dependant)
      Index = 4, indexes months        .. 'value' in range 1 to 12
      Index = 5, indexes years         .. 'value' in range 0 to 99    (00 = 2000.... 99 = 2099)
      NOTE:- WEEKDAY IS CALCULATED AUTOMATICALLY, BASED UPON TODAYS DATE    
    }
    
      If Lookdown(Index:3,4)                                'Adjust 1 indexed days/months, to zero indexed
        Value--
        
      byte[@LclRtc][Index] := Value                         'Write data to master time keeping registers
    
    PUB SetTime(Hours,Minutes,Seconds) 'Set time
    'Has method dependency 'WriteTimeReg'
    
      WriteTimeReg(2,Hours)                                 'Write hours data
      WriteTimeReg(1,Minutes)                               'Write minutes data
      WriteTimeReg(0,Seconds)                               'Write seconds data
      
    PUB SetDate(Day,Month,Year) 'Set Date
    'Has method dependency 'WriteTimeReg'
    
      WriteTimeReg(3,Day)                                   'Write day data
      WriteTimeReg(4,Month)                                 'Write month data
      WriteTimeReg(5,Year)                                  'Write year data
    
    PUB ReadStrDate(UsaDateFormat):StrPtr 'Returns pointer, to string date,either as UK/USA format
    'Has method dependency 'ReadTimeReg' & 'IntAscii'   
    
      StrPtr := String("??/??/20??")                        'Return string
    
      If UsaDateFormat
      
        'TRUE .... USA format date string
        IntAscii(StrPtr,ReadTimeReg(4))                     'Overwrite first two chars in string with month number 01-12
        IntAscii(StrPtr+3,ReadTimeReg(3))                   'Overwrite next two chars, after "/" with day number 01-31
        IntAscii(StrPtr+8,ReadTimeReg(5))                   'Overwrite next two chars, after "20" with year number 00-99
    
      else
        
        'FALSE .... UK format date string
        IntAscii(StrPtr,ReadTimeReg(3))                     'Overwrite first two chars in string with day number 01-31
        IntAscii(StrPtr+3,ReadTimeReg(4))                   'Overwrite next two chars, after "/" with month number 01-12
        IntAscii(StrPtr+8,ReadTimeReg(5))                   'Overwrite next two chars, after "20" with year number 00-99
      
    PUB ReadStrTime:StrPtr 'Returns pointer, to string time
    'Has method dependency 'ReadTimeReg' & 'IntAscii'
     
      StrPtr := String("??:??:??")                          'Return string  
    
      IntAscii(StrPtr,ReadTimeReg(2))                       'Overwrite first two chars in string with hour number 00-23
      IntAscii(StrPtr+3,ReadTimeReg(1))                     'Overwrite next two chars, after "/" with minutes number 00-59
      IntAscii(StrPtr+6,ReadTimeReg(0))                     'Overwrite next two chars, after "/" with seconds number 00-59
    
    PUB ReadStrWeekday:StrPtr 'Returns pointer, to a 3 letter string, representing the day of the week
    
      StrPtr := @DayOfWeek + (4* Byte[@TimeDate][6]) 
       
    PUB ReadMsTime:MsTime  'Returns current time & date, as compressed 32 BIT Microsoft Time format
    'Has method dependency 'ReadTimeReg'
     
      ''Create 32 bit packed Microsoft format date/time
      MsTime := ((ReadTimeReg(5)+20)<<25)                   'Bits 31 - 25 are years since 1980
      MsTime += (ReadTimeReg(4)<<21)                        'Bits 24 - 21 are month (1 to 12)
      MsTime += (ReadTimeReg(3)<<16)                        'Bits 20 - 16 are day (1 to 31)
      MsTime += (ReadTimeReg(2)<<11)                        'Bits 15 - 11 are hour (0 to 23)
      MsTime += (ReadTimeReg(1)<<5)                         'Bits 10 - 5 are minute (0 to 59) 
      MsTime += (ReadTimeReg(0)>>1)                         'Bits 4 - 0 are seconds/2 (0 to 30)
      
    PUB WriteMsTime(MsTime) 'Sets time/date registers using compressed 32 BIT Microsoft Time format
    'Has method dependency 'WriteTimeReg'
    
      WriteTimeReg(0,(2*MsTime) & %11111 )                  'Extract seconds from MsTime & write to time register
      WriteTimeReg(1,(MsTime>>5) & %111111)                 'Minutes
      WriteTimeReg(2,(MsTime>>11) & %11111)                 'Hours
      WriteTimeReg(3,(MsTime>>16) & %11111)                 'Days
      WriteTimeReg(4,(MsTime>>21) & %1111)                  'Months
      WriteTimeReg(5,(MsTime>>25)-20)                       'Years
    
       
    PRI IntAscii(Pointer,Number) 'Low level conversion of integer 00-99, to two ASCII chars...
    
      byte[Pointer][0] := (Number/10) +"0"                  'First character is tens (division by 10, + ASCII offset)
      byte[Pointer][1] := (Number//10) +"0"                 'Second character is units (modulus 10 + ASCII offset)
       
    PRI RtcMain(Pointer)|SysCnt,Counter,LapsedDays 'Timekeeping method.. runs in a new cog
    'All timekeeping registers are zero indexed!!!
    
      SysCnt := Cnt                                         'Set timer reference
    
      repeat                                                'Do forever
    '-------------------------------------------------------------------------------------------------------
    'Wait until 1 second has passed
    
        SysCnt += ClkFreq                                   'Increment timer reference count + 1 second
        waitcnt(SysCnt)                                     'Wait for 1 second to expire
    
    '-------------------------------------------------------------------------------------------------------
    'Make leap year correction to month length lookup table
    
        If (Byte[Pointer][5]&3)
              
          byte[@MonthLen][1] := 28 'Modify table data for February, for not Leap year
                          
        else
              
          byte[@MonthLen][1] := 29 'Modify table data for February, for Leap year
          
    '-------------------------------------------------------------------------------------------------------
    'Modify rollover table, so that days rollover entry is correct for days in this month...
    
        byte[@RollOvers][3] := byte[@MonthLen][ Byte[Pointer][4] ] 'Modify table data for month rollover data
    
    '-------------------------------------------------------------------------------------------------------
    'Increment time
    
        repeat Counter from 0 to 5                          '6 time/date fields to possibly increment/rollover
    
          ++Byte[Pointer][Counter]                          'Increment time
          Byte[Pointer][Counter] //= byte[@RollOvers][Counter] 'Perform modulus (rollover)
    
          If Byte[Pointer][Counter]                         'Test for rolled-over to zero...   If not rolled-over...
            quit                                            'Exit repeat loop
            
    '-------------------------------------------------------------------------------------------------------
    'Calculate the day of the week, based upon todays date
    
       LapsedDays := 6                                      '1st January 2000, was a Saturday
       
       LapsedDays +=  Byte[Pointer][5] * 365                'Add 365 days, for each full year passed
       LapsedDays += (Byte[Pointer][5] +3 )/4               'Peform leap year corrections...
    
       Repeat Counter from 0 to Byte[Pointer][4]            'Add days for full months passed this year
         LapsedDays += (Byte[@MonthIdx][Counter])           '... Using month length lookup table (previously leap year corrected!!)  
    
       LapsedDays +=  Byte[Pointer][3]                      'Add current day of this month
       
       Byte[Pointer][6] := LapsedDays // 7                  'Write data, modulus 7 ... 7 days in a week
               
    '-------------------------------------------------------------------------------------------------------
    'Write double buffered time/date data, for use by main object
    
        'Copy double buffered data
        Bytemove((Pointer+7),Pointer,7)                     'Copy data
    
    
    
    
    DAT
    
      '[ The following must be contigous
      MonthIdx  byte 0                                      'January .. 0 days to add to lapsed days, for day of week calculation
      MonthLen  byte 31,28,31,30,31,30,31,31,30,31,30,31    'Month lengths lookup table
      ']
      
      RollOvers byte 60,60,24,31,12,100                     'Time/date rollover limits sec,min,hrs,days,month,year
      DayOfWeek byte "Sun",0,"Mon",0,"Tue",0,"Wed",0,"Thu",0,"Fri",0,"Sat",0
    
    DAT
         {<end of object code>}
         
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    

    This is the pump code
    {{
     Pump Control, for now needs to run in it's own cog.
     At this time, Pump Control only flashes the center blue LED on the Quickstart Board.
    
    }}
                                             
    VAR
                 
      long PumpStack[32]                                     'Stack for PumpControl object in new cog
      byte Pumps                                             'Pumps stores the CogID of the new cog.
     'gg I'm not sure what this start:Success thing is all about
     'I Kept it in case I need it later.
      
    'PUB Start:Success 'Start the RTC object in a new cog...
    
     ' If not cog                                            'RTC not already started
     '   Success := Cog := Cognew(RtcMain(@LclRtc),@RtcStack)  'Start in new cog
     
    'PUB Stop 'Stops the Real Time Clock object, frees a cog.
    
     ' If Cog
     '   Cogstop(Cog)
    
    
    PUB Start             'Start is from Spin Language Reference -COGNEW page 81
      Stop
      Pumps := cognew (Pump1, @PumpStack)
    PUB Stop                     'Stop is from Spin Language Reference -COGNEW page 81 
      if Pumps>-1
        cogstop(Pumps)    
    PUB Pump1 
    
       ' Pin 16 is the buzzer, make it an output and set it low.
      dira[16] := 1
      outa[16] := 0
      
      'Pin 20 is the center LED on the Quickstart board, Make it an output and set it low.
      dira[20] := 1
      outa[20] := 0
                     
      Blink20 
    PUB Blink20
    
    'I want the P20 center led on the Quickstart to start blinking at some rate while the
    'clock is running and displaying things on the LCD monitor.
    
    
      repeat
        !outa[20]
        waitcnt(3_000_000+cnt)
    
                
     'This should run forever in a single new cog.
    
  • garyggaryg Posts: 420
    edited 2014-09-17 18:57
    Hi again

    After I made the archive of the not functional program, Wrote a better description of outcome in bigger terms and posted all of the code involved,

    I got to thinking about Duane's comment about the original cog left to die.

    I went back and looked over the top 3 sections of the program.
    I made the sections I had remarked out active again and added the Long cog statement
    I deactivated the part that I thought I needed.
    Then I replaced some of the terms that looked incorrect to me and EVERYTHING STARTED WORKING.

    Below is the working code.
    LCD display is reading and updating correct time, while the Blue P20 LED is blinking away.
    {{    This is PumpControl2.spin
     The VAR section, PUB Start:Success and PUB Stop sections appear to be very important.
     Pump Control, for now needs to run in it's own cog.
     At this time, Pump Control only flashes the center blue LED on the Quickstart Board.
    
    }}
                                             
    VAR
      long cog           
      long PumpStack[32]                                     'Stack for PumpControl object in new cog
      byte Pumps                                             'Pumps stores the CogID of the new cog.
     'gg I'm not sure what this start:Success thing is all about
     'I Kept it in case I need it later.
      
    PUB Start:Success 'Start the RTC object in a new cog...
    
      If not cog                                            'RTC not already started
        Success := Cog := Cognew(Pump1,@PumpStack)  'Start in new cog
     
    PUB Stop 'Stops the Real Time Clock object, frees a cog.
    
      If Cog
        Cogstop(Cog)
    
    
    'PUB Start             'Start is from Spin Language Reference -COGNEW page 81
     ' Stop
    '  Pumps := cognew (Pump1, @PumpStack)
    'PUB Stop                     'Stop is from Spin Language Reference -COGNEW page 81 
    ' ' if Pumps>-1
    '    cogstop(Pumps)    
    PUB Pump1 
    
       ' Pin 16 is the buzzer, make it an output and set it low.
      dira[16] := 1
      outa[16] := 0
      
      'Pin 20 is the center LED on the Quickstart board, Make it an output and set it low.
      dira[20] := 1
      outa[20] := 0
                     
      Blink20 
    PUB Blink20
    
    'I want the P20 center led on the Quickstart to start blinking at some rate while the
    'clock is running and displaying things on the LCD monitor.
    
    
      repeat
        !outa[20]
        WaitCnt(ClkFreq * 1 + Cnt) 
         waitcnt (50_000_000 + cnt) 
                
     'This should run forever in a single new cog.
    


    I'm sure I'll be having more questions as I develop this timer gizmo.
    I really don't understand exactly why this works, but it appears to work.
    and
    I really would like to figure out how to use the PNG file Jonny had attached to his comments.

    Thanks again
    Garyg
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-09-17 20:12
    garyg wrote: »
    I got to thinking about Duane's comment about the original cog left to die.

    I'm glad my comment helped but I'm starting to think I might not have been correct. I was assuming the object you had posted was the top object but if it was a child object then the control would return to the parent object and the cog wouldn't be left to die.
    garyg wrote: »
    and EVERYTHING STARTED WORKING.

    There's a lot to be said for working code. This is good to hear.
  • garyggaryg Posts: 420
    edited 2014-09-30 18:27
    Hi
    I've attempted to use all of the words of wisdom provided by all who replied.
    The end result is that I now have a working multicog program.
    I learned a lot from this exercise.

    The completed file is attached here. RTC_DEMO-GGMODIFIED3-PumpControl2REV2 - Archive [Date 2014.09.30 Time 17.57].zip

    I'm hoping that someone would have a look at my now working pump timer.
    I tried to make documentation as clear as I can.
    Some of my timing programming might appear to be clutzy, but for now,
    it's the very best I can do.

    Any suggestions as how I can improve this program or my documentation would
    be greatly appreciated.

    I'll make another post to show where this all came from and where it is going.

    Thanks for all your help.
  • garyggaryg Posts: 420
    edited 2014-09-30 18:32
    When I attempted to attach the, where this came from and where it's going, my post, just went away.

    So,
    I've been running my 3Timer, 4Terminal strip with Hot Male interconnection for about 12Years with good success.
    my timers started giving me trouble last summer, I could not find exactly what I needed without rebuilding the
    entire thing.

    These are photos of my old timer rig and my test rig running the new program.

    OldHydroponicTimerRig.jpg
    TestRigWithTimer.jpg



    Thanks again
    Garyg
    1024 x 768 - 119K
    1024 x 768 - 106K
Sign In or Register to comment.