Shop OBEX P1 Docs P2 Docs Learn Events
How long should this repeat loop take with RCSLOW clock @ 20 kHz? — Parallax Forums

How long should this repeat loop take with RCSLOW clock @ 20 kHz?

How long should this repeat loop timeout if the input pin remains at zero?
    HR14 := 5000
    CLKSET(%000_00_001, 20_000)                       ' RCSLOW @ 20 kHz
    repeat while ina[24] == 0
      if not HR14--                                     
        shutdown                                      ' Remove power if HR14 reaches zero
My measurements show that it takes approximately 10 minutes to shutdown. Does 10 minutes seem about right?

By my calculations, 10 minutes is 600 seconds, which is 12,000,000 clock cycles at 20kHz. The loop repeats 5000 times, which gives 2400 clock cycles per loop. That seems excessive.

What I'd really like to know is, what value should HR14 be for shutdown to occur in 14 hours? Accuracy is not a biggie.

Comments

  • Heater.Heater. Posts: 21,230
    edited 2015-08-09 16:39
    Why would you doubt your own measurements?

    Don't forget that the Prop take 4 clock cycles per machine instruction. So you would have only 600 machine instructions per loop.

    That stills sounds a lot but Spin is compiled to byte codes and each byte code takes many machine instructions to execute it. So may we are in the right ball park here.

    You want 14 hours or 840 minutes. You have 10 minutes so you need 84 time more. Set HR14 to 84 * 5000 = 420000.

    Having said that, often the reason for using a slow clock speed like this is to save power. In which case I would not have an endlessly executing loop like that but rather do a WAITCNT, for one second say. Use that to count seconds, minutes and hours. This will have the Prop in low power mode most of the time.
  • Mike GreenMike Green Posts: 23,101
    edited 2015-08-09 17:07
    RCSLOW varies quite a lot and is temperature and supply voltage dependent. The datasheet indicates that it can range from 13KHz to 33KHz. There are at least 10 operations involved in the loop and these might take 10-20 instructions each (just eyeballing here). That's maybe 800 or more clock cycles (say 1000). With HR14 at 5000, that's 5,000,000 clock cycles. At RCSLOW of 13KHz, that's roughly 380 seconds. Given my very rough guessing, I'm not too far off.

    Hook up an LED to an I/O pin and turn it on and off in a loop like:
    CLKSET(%000_00_001, 20_000)
    repeat loopCount from 1 to 10   ' try several different values
       dira[ LEDio ] := 1   ' turn LED on
       outa[ LEDio ] := 1
       HR14 := loopCount * 100   ' actual count 100 to 1000
       repeat while ina[ 24 ] == 0   ' duplicate your loop
          if not HR14--
              outa[ LEDio ] := 0   ' turn off LED rather than shutdown
              waitcnt( 20_000 + CNT )  ' wait about a second
              quit
    
    This way you can time your loop and see what RCSLOW comes out to for your chip and operating conditions.
  • Does the 20_000 in my CLKSET statement do anything useful if the clock can vary from 13 kHz to 33 kHz?

    This is a sealed system with no access to pins, except Rx and Tx. I'll think about hooking up something to one of those pins.

    I like the idea of spending most of the time in waitcnt and checking ina[24] every second or so. The increase in loop machine cycles by the added waitcnt statement will be more than offset by fewer repeat loops.
  • Heater.Heater. Posts: 21,230
    I forget the details now but in theory telling the Prop what frequency it runs at means that timeouts using CNT and CLKFRQ will automatically adjust to give you the right time out. You don't have to find all such timeouts in your code and tweak them individually when running on a machine with a different frequency. This way a Spin object developed on a machine with a 10MHz XTAL can be used by people with machines with different frequency XTALs with no changes.

    Now, specifying 20_000 is only accurate if the clock is 20KHz of course. Being an RC clock it may be out a bit and drift around so as it changes from 13 to 33KHz all your program timing will change.




  • dbpagedbpage Posts: 217
    edited 2015-08-09 19:32
    I changed the code as follows:
    HR14 := 10
    CLKSET(%000_00_001, 20_000) ' RCSLOW @ 20 kHz 
    repeat while ina[24] == 0 
      waitcnt(clkfreq + cnt)
      If not HR14-- 
        shutdown ' Remove power if HR14 reaches zero
    

    I timed several HR14 values. Using linear regression, I calculate the slope to be approximately 1.21 and y-intercept to be about 1.33. If I subtract 1.33 from the desired number of seconds and divide the result by 1.21, I get a value for HR14 for the number of seconds desired. This suggests an initial overhead of about 33% (including the initial HR14 and CLKSET statements), and a repeating overhead of about 21%.

    The resulting timeout periods are reasonably accurate within a few tenths of a percent, plenty accurate for my purposes. As the temperature and battery voltage changes, additional error will occur, but that's OK.

    With your help, I now have confidence that there isn't something else wrong with the unit.

    Thanks!
  • Heater.Heater. Posts: 21,230
    Cool.

    What are you making there by the way ?

  • Heater,
    Sorry, we will have to wait until the NDA is lifted.

    Mike Green,
    Just remembered that I can access 2 additional pins for a temporary LED or equivalent.

    Dennis
  • Know that you don't have to put 20_000 in the CLKSET command. You are dividing the number of seconds desired by 1.21 to get the HR14 value. If you use 16_529 instead of 20_000, then H14 should come out in seconds, multiplier 1.0. Hmm, or should it be 24_200? The former I think.

    Lacking other pins, tx and rx can be fine to serve as outputs for the timing test. Also, if the device happens to have a built-in real time clock, it can measure its own RCslow frequency.



  • By using waitcnt() you are now only checking ina[24] 10 times in 14 hours, or about once every 1.4 hours. If this is a power good input or push button, then are you okay not responding to it for up to that long?
  • Sapphire,
    It is a push button. The device seems adequately responsive with the posted code. By my observation of the posted code, ina[24] is checked once per second. Is this not accurate?

    Tracy Allen,
    After discovering the percentage of time that is spent on overhead for the simple repeat loop, I got spooked if I were to add RTC communication. Communication with the RTC would require the following statements:
    i2c.start                              ' (4 statements)
    i2c.write(WrRTC)                       ' (9 statements)
    i2c.write(secondsregister)             ' (9 statements)
    i2c.stop                               ' (5 statements)
    i2c.write(RdRTC)                       ' (9 statements)
    secs := i2c.read(NAK) & SecMask        ' (38 statements for 8 bit read)
    i2c.stop                               ' (5 statements)
    
    By my count, the RTC would add an overhead 79 statements, or 316 cycles (at 4 cycles each statement), not including logic to interpret the result. Please convince me that reading the RTC is better than my current code. The RTC would be more accurate, but accuracy is not important. It's the difference between infinity and 14 hours more or less until shutdown.

    Note: My RTC allows me to set an alarm interrupt, so I could test for an alarm register or pin, but a pin is not available in this particular device. All pins are allocated. I'm stuck with software access, which is painfully slow at RCSLOW.

    Dennis
  • I wasn't suggesting that the program read the i2c RTC within the RCslow loop. Rather, use the real time clock once in situ to measure the RCslow frequency and use that actual value subsequently in the clkset command.
    Pseudosnippet for measurement:
    set RTC to zero
    clkset(1,20_000)   ' RCslow
    waitcnt(2_000_000 + cnt)  ' nominally 100 sec.
    clkset(0,12_000_000)   ' RCfast at 12MHz
    read elapsedSeconds from RTC
    slowFreq := 2_000_000 / elapsedSeconds.
    
    For example, if elapsedSeconds comes out at 110 seconds instead of 100, the RCslow clock is slower than 20kHz, and 18181 Hz is a better approximation. For that Prop. At around that temperature.

    It's too bad there is not a pin on your setup for the RTC alarm. If it is like the DS1307 and other such chips, the alarm pin can be set up to toggle up and down with a period of 1 second or so. That gives a great way to count down exact intervals with RCslow, or to measure the actual RCslow frequency with stopwatch accuracy.
  • Tracy Allen,
    I like your self-calibration suggestion. That will compensate for variations between individual units. Additionally, the device has enough battery capacity to jump out of RCSLOW periodically (e.g., once every x hours) to check the time.

    This is getting interesting.

    Dennis
Sign In or Register to comment.