Shop OBEX P1 Docs P2 Docs Learn Events
Problem with date generator program — Parallax Forums

Problem with date generator program

kenmackenmac Posts: 96
edited 2007-10-20 10:49 in Propeller 1
Hi folks,
I have a RTC program operating OK on a Prop. (secs/mins/hours)
Recently I decided to add the date functions.
Most of it worked but it has a problem that I don't understand.
The code shown below is a "stripped down" version with only the affected bits shown.
Basically, the date is initialised as a "day" number and then interpreted into day/month variables and subsequently displayed.
I have used a Case list to interpret the totalday number into day/month variables.
That is what is supposed to happen, but the day/month numbers do not work correctly.
I set up a display Cog to monitor the values resulting from various initial "totalday" values.
With the code as shown, the "day" is OK until the totalday= 120, and the "month" until it = 181.
Anything above that value reads as 00.
If the Check_leap code is remarked out, the values change to: "day" limit is totalday = 243 and "month" until it = 304.
Above that reads 00 also.
I haven't a clue as to what is going on here. (it is the same on two Props.)
Is there a problem with the code method?


con
  _clkmode = xtal1
  _clkfreq = 5_000_000                 ' 5 mHz
  lsb = 16                      
  msb = 22
  
var
  long stack0[noparse][[/noparse]100]
  word totalday
  byte year
  byte day
  byte month
  word dayPtr
  word monthPtr
  byte Feb_days
 

obj
   LCD:"ahmLCD_2"                                       ' LCD program

pub main
   dayPtr := @day                                          ' set pointer to day variable
   monthPtr := @month                                   ' set pointer to month variable
   cognew(display(dayPtr, monthPtr), @stack0)   'start a Cog to display day/month numbers
   
 { initial  preset date }
   year := 07
   totalday := 181                                            ' initial value

   check_rollover                                             ' interpret total days
  
{check for leap year}
pub check_leap
   if year//4 == 0
      Feb_days := 29
   else
      Feb_days := 28
       
pub check_rollover
     
   check_leap                                               ' check for leap year

{Interpret totalday into day/month   }
   case totalday
        01..31 : month := 01                            ' January
                 day := totalday
        32..59 : month := 02                            ' February
                 day := totalday - 31
        60..90 : month := 03                            ' March
                 day := totalday - 59
        91..120 : month := 04                           ' April
                 day := totalday - 90
        121..151 : month := 05                          ' May
                 day := totalday - 120        
        152..181 : month := 06                          ' June
                 day := totalday - 151        
        182..212 : month := 07                          ' July
                 day := totalday - 181        
        213..243 : month := 08                          ' August
                 day := totalday - 212        
        244..273 : month := 09                          ' September
                 day := totalday - 243        
        274..304 : month := 10                          ' October
                 day := totalday - 273        
        305..334 : month := 11                          ' November
                 day := totalday - 304        
        335..365 : month := 12                          ' December
                 day := totalday - 334
                        
{ display day/month on LCD   }
pub display(dPtr, mPtr) | D, M, daytens, dayunits, monthtens, monthunits    
  D := byte[noparse][[/noparse]dPtr]
  M := byte[noparse][[/noparse]mPtr]
  LCD.init
  repeat
     LCD.pos(1,1)
     daytens := D/10                                       
     LCD.write(daytens + 48)                           ' display day/tens
     dayunits := D//10
     LCD.write(dayunits + 48)                          ' display day/units
     LCD.write("/")
     monthtens := M/10
     LCD.write(monthtens + 48)                         ' display month/tens
     monthunits := M//10
     LCD.write(monthunits + 48)                        ' display month/units 





kenmac

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8

Comments

  • Nick MuellerNick Mueller Posts: 815
    edited 2007-10-19 09:31
    > I haven't a clue as to what is going on here. (it is the same on two Props.)

    Maybe I'm wrong, but in your Display, you only display daytens and not day.


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • kenmackenmac Posts: 96
    edited 2007-10-19 10:40
    Hi Nick,

    The display works, OK - it's what ends up in the variables "day" and "month" that is the problem!
    These values are passed via pointers to the display code.

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • simonlsimonl Posts: 866
    edited 2007-10-19 11:45
    Hi Ken,

    Looks like it _may_ be something in your display routine; I've converted you spin to display using TV_Text, run it on GEAR, and it's working fine!

    Here's my version:
    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      lsb = 16                      
      msb = 22
      
    var
      long stack0[noparse][[/noparse]100]
      word totalday
      byte year
      byte day
      byte month
      word dayPtr
      word monthPtr
      byte Feb_days
     
    
    obj
       tv:"TV_Text"                                       ' tv program
    
    pub main
       dayPtr := @day                               ' set pointer to day variable
       monthPtr := @month                           ' set pointer to month variable
       cognew(display(dayPtr, monthPtr), @stack0)   'start a Cog to display day/month numbers
       
     { initial  preset date }
       year := 07
       totalday := 364                              ' initial value
                                                    
       check_rollover                               ' interpret total days
      
    {check for leap year}
    pub check_leap
       if year//4 == 0
          Feb_days := 29
       else
          Feb_days := 28
           
    pub check_rollover
         
       check_leap                                   ' check for leap year
    
    {Interpret totalday into day/month   }
       case totalday
            01..31 :
              month := 01                    ' January
              day := totalday                
            32..59 :
              month := 02                    ' February
              day := totalday - 31
            60..90 :
              month := 03                    ' March
              day := totalday - 59
            91..120 :
              month := 04                   ' April
              day := totalday - 90
            121..151 :
              month := 05                  ' May
              day := totalday - 120        
            152..181 :
              month := 06                  ' June
              day := totalday - 151        
            182..212 :
              month := 07                  ' July
              day := totalday - 181        
            213..243 :
              month := 08                  ' August
              day := totalday - 212        
            244..273 :
              month := 09                  ' September
              day := totalday - 243        
            274..304 :
              month := 10                  ' October
              day := totalday - 273        
            305..334 :
              month := 11                  ' November
              day := totalday - 304        
            335..365 :
              month := 12                  ' December
              day := totalday - 334
                            
    { display day/month on tv   }
    pub display(dPtr, mPtr) | D, M, daytens, dayunits, monthtens, monthunits    
      D := byte[noparse][[/noparse]dPtr]
      M := byte[noparse][[/noparse]mPtr]
      tv.start(12)
      repeat
        tv.str(string($A,16,$B,12))
        daytens := D/10                                       
        tv.out(daytens + 48)               ' display day/tens
        dayunits := D//10
        tv.out(dayunits + 48)              ' display day/units
        tv.str(string("/"))
        monthtens := M/10
        tv.out(monthtens + 48)             ' display month/tens
        monthunits := M//10                
        tv.out(monthunits + 48)            ' display month/units
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • kenmackenmac Posts: 96
    edited 2007-10-19 12:23
    Thanks Simon.
    The LCD itself is OK and the code used to display the numbers is normal and should work.
    It displays the numbers OK up to those limits mentioned.
    Tomorrow I think I'll try a new Prop. and see what happens.
    If I can locate my LCD TV screen I'll try your code also.

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-10-19 13:28
    > Tomorrow I think I'll try a new Prop. and see what happens.

    When programming, you have to be aware of one thing:
    The error is always in your code. Don't look in the hardware.


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • Stan671Stan671 Posts: 103
    edited 2007-10-19 13:49
    Your program does not work as expected and the first thing you suspect is the Prop chip hardware screwing up? Well, you have far more faith in your programming skills that most people do and far less faith in Parallax's ability to make good hardware than most people do.

    Personally, I would not bother with using byte and word variable types and just use long for everything. Then you don't have to worry about byte alignments in memory, propagation of sign bits, etc.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Stan Dobrowski
  • simonlsimonl Posts: 866
    edited 2007-10-19 14:32
    Hi Ken,

    I think the 'should' in your reply is the indicator!

    Given that I've only really changed the output driver - from LCD to TV_Text - I would suggest that the problem lay in the LCD driver object...

    Might be worth posting that object here to see if anyone can spot the problem (though I admit, it seems a bit weird that a driver would do this.)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-10-19 14:32
    Ken, I have your solution, you owe me one for this!!

    I found that when I commented out check_leap it worked which made no sense at all, I looked at all the possible overwriting of memory location options and nothing made sense.

    Then just by accident I had a thought, he is trying to display the data using his new cog before he has even created it using check_rollover, the call the check_leap gave the display cog even more time to get running before is started to display.

    The two options to fix it are to either run check_rollover before calling display or put the:

    D := byte[noparse][[/noparse]dPtr]
    M := byte[noparse][[/noparse]mPtr]

    in the display loop.

    The reason is started at a certain date was because it had to do more case checks so delaying the check_rollover routine further.

    Graham
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-10-19 14:36
    Simon, it probably ran OK in gear because the cognew delay may be different? It certainly did not run OK with my dongle and prop terminal.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-10-19 14:41
    Something I noticed in check_leap:
    if year // 4 == 0
    If year is a multiple of 400, then it is NOT a leap year.

    regards peter
  • mparkmpark Posts: 1,305
    edited 2007-10-19 16:53
    Peter Verkaik said...
    Something I noticed in check_leap:
    if year // 4 == 0
    If year is a multiple of 400, then it is NOT a leap year.

    regards peter

    No, if a year is a multiple of 100 then it is not a leap year UNLESS it is also a multiple of 400.

    From Wikipedia:
    The Gregorian calendar, the current standard calendar in most of the world, adds a 29th day to February in all years evenly divisible by 4, except for centennial years (those ending in -00) which are not evenly divisible by 400. Thus 1600, 2000 and 2400 are leap years but 1700, 1800, 1900, 2100, 2200 and 2300 are not.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-10-19 17:04
    Mpark,
    That's right.
    Thanks for the correction.

    regards peter
  • simonlsimonl Posts: 866
    edited 2007-10-19 17:12
    Hi Graham,

    Thanks for the heads-up - I'd not realised GEAR had that effect.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2007-10-19 17:53
    Why aren't you using the tx_text's PUB dec(value) | i '' Print a decimal number?
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-10-19 19:52
    Because he is emulating the code of kenmac, who is sending ascii to his display hence the +48 (ascii 0 = 48). Using just tv.out will show the char this corresponds to.

    Graham
  • kenmackenmac Posts: 96
    edited 2007-10-20 01:19
    Peter, MPark.
    I don't think I'll be around for the next multiple of 100.
    The clock is only intended to cover the next 10-20 years.


    Graham,
    Thanks for your "in depth" look at it.
    What you say makes sense - I would never have worked that out, except maybe by trial and error with the code.
    I need to clear my head and come back to it in a couple of days.

    Incidentally, my reference to "trying another Prop. " was the result of a very tired mind.(and frustration!)

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8

    Post Edited (kenmac) : 10/20/2007 1:23:59 AM GMT
  • kenmackenmac Posts: 96
    edited 2007-10-20 09:08
    Graham,
    I moved the "read the global variables" lines into the loop and that fixed it.
    The display wasn't updating from the initial values because the read commands were outside the loop.
    I should have spotted that one, but you stare at the code for so long you become blind to the obvious!
    It's great to have someone else check it - much appreciated.
    I now have a fully working RTC, and can complete the remainder of the project.
    Thanks again.

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2007-10-20 10:49
    Glad to help

    Graham
Sign In or Register to comment.