Forum Index
what to do with ever changing values?

 
Author Message
cadillackid



Joined: 22 Aug 2009

Posted: 03 October 2009, 18:33 PM    Post subject: what to do with ever changing values?

In my HVAC project, I am trying to find a way to store ever changing values without ruining my persistent memory...

anytime a setting is changed I want to store it, so in the event of an electrical power failure the controller recovers to its previous settings...

obviously i can use persistent bytes... however it will eventually ruin the non volatile memory if i write to it each time a setting changes.. I realize a million writes is a lot.. is there an external chip I can use?

also how many bytes of persistent memory exist on a ZX-328n and a ZX-1281n that I can use? maybe I can rotate writing different bytes so that I dont ruin the memory as fast?
-Christopher
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Location: Portland, OR

Posted: 03 October 2009, 18:53 PM    Post subject: Re: what to do with ever changing values?

cadillackid wrote:
is there an external chip I can use?
An FRAM device like the FM25256B may be useful. It has an SPI interface and claims 10^14 cycles lifetime.

cadillackid wrote:
how many bytes of persistent memory exist on a ZX-328n and a ZX-1281n that I can use?
Check the ZX Device Parameter web page. It is also available as an Excel spreadsheet.

cadillackid wrote:
maybe I can rotate writing different bytes so that I dont ruin the memory as fast?
Wear leveling is a well-known procedure. I believe that Atmel and Microchip both have application notes on the topic.
Back to top
Don_Kirby



Joined: 15 Oct 2006

Posted: 03 October 2009, 19:52 PM    Post subject:

I used wear leveling in order to extend the life of a hour meter project. Using an array of 200 persistent variables I was able to extend the lifespan of the product from the advertised 100,000 writes, to 20,000,000 writes. It's been running for 2 years nonstop so far, writing once per minute, without any problems. I gather it will run for another 36 years before I see a failure.

The other method worth mentioning is power failure detection. Monitor the incoming power supply for a loss of power. Provide enough backup power (usually in the form of capacitance) to write the current value to persistent memory, but only do it when the power fails.

Neither of the above techniques require additional components, which is a plus.


-Don Kirby
Back to top
GTBecker



Joined: 18 Jan 2006
Location: Cape Coral

Posted: 03 October 2009, 20:47 PM    Post subject:

http://www.atmel.com/dyn/resources/prod_documents/doc2526.pdf

Here's an example I wrote some time ago, from the BX-24 Yahoo list. Note that lTwoDaysInTicks applies a trick to the BX-24 RTC that probably does not work in ZBasic machines. Adjust accordingly.

Code:
' Hobbs-like Running Time Meter on BX-24
'   0.001 hour resolution (or 0.01)
'   Resettable ~1165 hour maximum count (11650)
'   12000 hour minimum endurance (120000)

'   2006-03-28  Tom Becker  GTBecker@RighTime.com

 const Pin_Input_Reset_Count_Not as byte = 10
 const ilenCircularBuffer as integer = 120
 dim laCircularBuffer(1 to ilenCircularBuffer) as New PersistentLong
 dim iXMax as integer
 const lThousandthHourInTicks as Long = 1843   '0.001hr = 3.6seconds * 512ticks = ~1843 (0.01% error)
 const lTwoDaysInTicks as long = 88473600      'RTC T0, well beyond 24 hours; won't reset at midnight

sub Main()
   call PutPin (Pin_Input_Reset_Count_Not, bxInputPullup)   'reset switch pin
   if FirstTime then
      call Reset
   end if
   iXMax = iGetLargestRunningTimeIndex   'find index of largest in ring, resume
   call SetRTCTicks(laCircularBuffer(iXMax) * lThousandthHourInTicks)   'start timer from there
   call ShowRunningTime   'show start time

   do   'endless
      if (lGetRTCTicks \ lThousandthHourInTicks) <> (laCircularBuffer(iXMax)) then
         iXMax = iXMax mod ilenCircularBuffer + 1   'next in ring
         laCircularBuffer(iXMax) = lGetRTCTicks \ lThousandthHourInTicks   'store each 0.001 hour
         call ShowRunningTime
      end if
      if GetPin(Pin_Input_Reset_Count_Not) <> 1 then
         call Reset
         call ShowRunningTime
      end if
   loop
end sub

function lGetRTCTicks() as long
   lGetRTCTicks = register.RTCTick - lTwoDaysInTicks   'RTC count is offset to avoid midnight
end function

sub SetRTCTicks(byval lTicks as long)
   register.RTCTick = lTicks + lTwoDaysInTicks
end sub

sub ShowRunningTime()
   debug.print strRunningTimeInHours(laCircularBuffer(iXMax))
end sub

function strRunningTimeInHours(byval lT as long) as string   '1165.210hr max; (2^31-1/512/3600)-48hrs
   dim strH as string*5, strF as string*4
   strF = cStr(lT mod 1000 + 1000)   'hour fraction
   lT = lT \ 1000   'discard fraction
   strH = cStr(lT + 10000)   'hours
   strRunningTimeInHours = mid(strH, 2, 4) &"."& mid(strF, 2, 3)
end function

sub Reset()
      call ResetRunningTime   'zero ring
      call SetRTCTicks(0)   'zero RTC
end sub

sub ResetRunningTime()
   dim iX as integer
   debug.print " Reset"
   for iX = 1 to ilenCircularBuffer   'this takes about four seconds on BX-24
      laCircularBuffer(iX) = 0
   next
end sub

function iGetLargestRunningTimeIndex () as integer
   dim iX as integer
   debug.print " Resume"
   iGetLargestRunningTimeIndex = 1
   for iX = 1 to ilenCircularBuffer   'get index of largest value
      if laCircularBuffer(iGetLargestRunningTimeIndex) < laCircularBuffer(iX) then
         iGetLargestRunningTimeIndex = iX
      end if
   next
end function


Like Don, I have one of these running without a failure for several years.
Back to top
cadillackid



Joined: 22 Aug 2009

Posted: 04 October 2009, 14:34 PM    Post subject:

I think im going to go the route of rotating data in the persistent areas... I realized that even if the thermostat settings changed 1000 times per day(which is an awful lot of adjusting...roughly once every 1.4 minutes).. I would hit close to the 1 million mark little less than once a year... im only using about 10 bytes of persistent memory.. so if I rotate in 100 bytes It should last about 10 years.... but then who is going to adjust their settings 1000 times / day...

I dont want the controller to stay active during a power failure as in HVAC its not a good idea to "bang" equipment... however the controller is powered by the A/C unit which is 5 volts so I could just read a pin and have a capacitor as suggested earlier to hold power up long enough for me to start the time delay and save the settings....
-Christopher
Back to top
spamiam



Joined: 13 Nov 2005

Posted: 04 October 2009, 16:27 PM    Post subject:

I have also had good results with FRAM (from Ramtron), though now some other products incorporate this type of memory. For instance the Dallas DS32X35 incorporates a VERY accurate RTC and FRAM in the same package. The two currently available have 2K and 8K of FRAM. Fram wil not wear out, so you do not have to worry about wear levelling. I beleive you already have an I2C bus on your device, and these are I2C devices, though Ramtron also offers SPI FRAM devices.

If you are going to need an RTC, then the Dallas chip might make sense.

-Tony
Back to top
stevech



Joined: 23 Feb 2006

Posted: 04 October 2009, 16:48 PM    Post subject:

I have a ZX that uses the rotating fixed length data record approach. Each record is numbered (ascending). So at startup, the code looks for the highest numbered record. The writing code uses circular buffer and overwrites the lowest numbered record.

THis has been running here for 2 years or so - with 4 or so records added per day. Using onboard EEPROM
Back to top
Display posts from previous:   
Page 1 of 1

 



ZBasic Microcontrollers Home
All content Copyright © 2005, 2006, 2007, 2008, 2009, 2010 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group