Shop OBEX P1 Docs P2 Docs Learn Events
Need help with time counter an video out — Parallax Forums

Need help with time counter an video out

JoarJoar Posts: 3
edited 2009-09-16 00:57 in Propeller 1
I hope some of you genius can help me with this.
I guess it's not so wery difficult... but I'm quite new to spin.
A firend of me has told me that this is a hopeless project... He is all into Atmel. But I think propeller / spin is more interesting. I like the video out option.

Here is my code:
CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000


OBJ

  text : "tv_text"
  

PUB start | count

waitcnt(clkfreq + cnt)

dira [noparse][[/noparse]16] := 1 

   
  text.start(12)
Repeat Count From 5 To 0       'For every loop, Count decrements by one sec.  
   text.out(13)                 'Ny linje
   text.out(13)
   text.out(13)  
   text.str(string("               Text 1"))
   text.out(13)
   text.out(13)    
   text.out(13)
   text.str(string("             Text 2"))
   text.out(13)
   text.out(13)
   text.out(13)
   text.out(13)
   text.str(string("                        "))    'Sends a text string to the video monitor.
   text.dec(Count)                             'Sends a numeric value to a video monitor.
    
   waitcnt(clkfreq + cnt)

   text.out(0)                  'Blank screen 



text.start(12)  
repeat Count from 0 to 50000000
   outa [noparse][[/noparse]16] := 1   
   text.out(13)
   text.out(13)  
   text.str(string("   Time       "))     'Send a text string and counts number           
   text.dec(Count)
   waitcnt(clkfreq + cnt)
   text.out(0)                               'Blanks screen





As you can see I want a delay at power on, while displaying at text.
After this it sets pin [noparse][[/noparse]16] high, for switching another video signal to the monitor.
This part I got working.
The next I whant is to count the power on time (aprox in min, and I know my code is useless for this...)
And I need it to be stored in EEPROM when it looses power (one pin goes low), and read from EEPROM at next power on and continued to count.
For making the readout easy i need it to be put out on the monitor.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-13 22:17
    For reading and writing EEPROM, get the Basic_I2C_Driver from the Object Exchange. This will allow you to store the time in minutes in the EEPROM. Instead of counting the seconds, have 2 variables for seconds and minutes since starting.
    var
       long minutes, lastWritten, timeStack[noparse][[/noparse] 15 ]
    
    pub countUp | seconds
       seconds := 0
       waitcnt(clkfreq + cnt)   ' wait for a second
       if ++seconds == 60
          seconds~
          minutes++
    


    To start this up do a "COGNEW(countUp,@timeStack)" and it will maintain a minutes clock indefinitely. Saving the clock to EEPROM depends on whether you want to use the EEPROM for other things. You'd like to have "countUp" record the time every time the minutes increments, but, if other parts of your program are using the EEPROM, you need to lock it so that the "countUp" routine doesn't try to use the I2C bus or EEPROM at the same time some other routine is using it.

    Post Edited (Mike Green) : 9/13/2009 10:38:20 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-13 22:28
    Under normal circumstances, you can write a value to the space on the EEPROM where a variable is loaded from during Propeller initialization. The is cleared to zeroes when a program is downloaded, but not changed until the next download from the Propeller Tool. If you're using "Basic_I2C_Driver", a routine to save the time would look like
    pub saveTheTime | temp, startTime
       temp := minutes
       if temp <> lastWritten and temp <> 0
          if i2c.WritePage(i2c#BootPin, i2c#EEPROM, @minutes, @temp, 4)
             abort ' an error occured during the write
          startTime := cnt ' prepare to check for a timeout
          repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, @minutes)
             if cnt - startTime > clkfreq / 10
                abort ' waited more than a 1/10 second for the write to finish
          lastWritten := temp
    


    Somewhere at the beginning of your program, you'd need to put
    OBJ i2c : "Basic_I2C_Driver"
    


    If the power goes off or other Propeller reset occurs, when the program is reloaded from the EEPROM, the value of "minutes" will be the value last saved.

    You can call "saveTheTime" as often as you like. It will only write a value to the EEPROM if the time has changed and only if "saveTheTime" has been called at least twice.

    Post Edited (Mike Green) : 9/13/2009 10:39:30 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-13 22:33
    Note: I changed "countUp" so it doesn't initialize "minutes".
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2009-09-14 02:40
    Okay, the following is probably unneeded speculation and complexity, so feel free to skip it. Anyway, I don't know how often you're expecting power downs, but if it's often, I'm wondering if you might want to alternately store two versions of the time in the EEPROM, each version being stored separately and somewhat displaced in time, such that if power went out during a write to the EEPROM and corrupted the writing, the alternate time version would likely still be available (having already been committed, say, a few milliseconds before). However, I don't even know for sure if a write to the EEPROM can be corrupted in this way (perhaps the chip is designed to handle such power out situations). Moreover, it seems unlikely that you'd be experiencing a lot of power downs, and, probably, for the one chance in a million that it did corrupt the writing of the time, perhaps you could live with that and all would be well upon the next cycle. As such, I'd probably ignore my comment in terms of the code that you need to write, except for being aware that you are ignoring this once-in-a-million scenario. Besides, even if you wanted to handle it, it's usually best to write code step-by-step, testing as you go as much as is possible. In summary, ignore this comment, but get busy learning how to use the object Mike advised, again, step-by-step and probably in isolation of (separate from) your current progress. Then, when you can store to the EEPROM, integrate it with your project code. You probably know all this; sorry for obvious advice, but the step-by-step, test-as-you-go, break-it-down-into-parts strategy is sooooo important in hitting one's target, even for experienced coders.
  • JoarJoar Posts: 3
    edited 2009-09-14 16:55
    Thank you!
    I'll read and try later today (and tomorrow..).
    The power loss, is every time the user pull the power plug...
    The counter is only for my use if the "customer" tells me that "the s hit only worked for 5 hours", then its good to know that the "s hit" has been powered up for 105 hours.
    This user I dont trust for pressing a power button. When they are finished filming they will most likely pull the plug or stop the generator.
    The timing is not a problem (I hope), I was thinking about connecting some parts directly from 12V and into one input pin. When this drops below 10V it's loosing power but if I have a capasitor on the 5V (or 3,3V) this will keep the power for the time it need for writing.
    This I'm planning to use in a "field camera unit" or something like that. The users are smart as a bread when it comes to electronics...
  • JoarJoar Posts: 3
    edited 2009-09-15 22:18
    Hi

    Can anyone explain how i get the counter up on the lcd?
    I only get "0"

    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    var
    
       long minutes, lastWritten, timeStack[noparse][[/noparse] 15 ], saveStack[noparse][[/noparse] 15 ]
    
    OBJ
    
      text : "tv_text"
      i2c  : "Basic_I2C_Driver"
    
    PUB start | count
    
    COGNEW(countUp,@timeStack)      'Starts countUp in a new cog          
    COGNEW(saveTheTime,@saveStack)  'Starts save rutine in a new cog
    
    waitcnt(clkfreq + cnt)
    
    dira [noparse][[/noparse]16] := 1                  'Set i/o 16 to output 
    
       
      text.start(12)
    Repeat Count From 5 To 0        'For every loop, Count decrements by one sec.   
       text.out(13)                 'New linje
       text.out(13)
       text.out(13)  
       text.str(string("               Text 1"))
       text.out(13)
       text.out(13)    
       text.out(13)
       text.str(string("             Text 2"))
       text.out(13)
       text.out(13)
       text.out(13)
       text.out(13)
       text.str(string("                        "))    'Sends a text string to the video monitor.
       text.dec(Count)                                 'Sends a numeric value to a video monitor.
        
       waitcnt(clkfreq + cnt)
    
       text.out(0)                           'Blanks screen 
    
    
    text.start(12)
    repeat
      outa [noparse][[/noparse]16] := 1                      'Turns on pin 16
      text.out(13)
      text.out(13) 
      text.str(string("   Time       "))     'Send a text string and counts number
      text.dec(minutes)                      'What do I put her to get the countup up on the lcd?                                                                              
       waitcnt(clkfreq)
       text.out(0)                           'Blanks screen
    
    
    pub countUp | seconds 
    
       seconds := 0
       waitcnt(clkfreq + cnt)   ' wait for a second
       if ++seconds == 60
          seconds~
          minutes++
    
    
    
    pub saveTheTime | temp, startTime
       temp := minutes
       if temp <> lastWritten and temp <> 0
          if i2c.WritePage(i2c#BootPin, i2c#EEPROM, @minutes, @temp, 4)
             abort ' an error occured during the write
          startTime := cnt ' prepare to check for a timeout
          repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, @minutes)
             if cnt - startTime > clkfreq / 10
                abort ' waited more than a 1/10 second for the write to finish
          lastWritten := temp
    
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-16 00:57
    1) saveTheTime was not designed to be run in a separate cog. It was intended to be called from a loop in the main cog

    2) In the last "repeat" in your main method, you've got "waitcnt(clkfreq)". It should be "waitcnt(clkfreq + cnt)"

    3) Calling "text.start(12)" twice in your program doesn't do what you may think it does.· First it stops any existing video driver which causes the screen to blank.· Then it starts up a new video driver and clears the screen buffer.· Best thing is to only call "text.start(12)" at the beginning of your program.

    Post Edited (Mike Green) : 9/16/2009 1:06:15 AM GMT
Sign In or Register to comment.