![]() |
Forum Index : Microcontroller and PC projects : MMBasic VAR SAVE and VAR RESTORE
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
The Variable save and restore capability saves variables into non volatile memory I have quick question about the practicality of using this, to ensure variables are stored in the event of loss of power, and whether this is sound. how many times can I save the variable out and receive it before I exceed the chips capability, if the chip has a limit. Also, am I using this command in a way it was not intended. Do if event=1 then MyVar=2 MyDate$=Date$ MyTime$=time$ var save MyVar, MyDate$, MyTime$ endif MyVar=0 MyDate$="" MyTime$="" ... ... var restore if MyVar=2 then print MyDate$, MyTime$, "Event 1 happened" endif Loop |
||||
BobD![]() Guru ![]() Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Dave, it's all in the manual. Refer P13. [quote] This facility is intended for saving data such as calibration data, user selected options and other items which changed infrequently. It should not be used for high speed saves as you may wear out the flash memory. The flash in the PIC32MX150/250 series of chips has a very high endurance of over 20,000 writes and erases. With normal use this will never be reached but it can be exceeded by a program that repeatedly saves variables. For example, a program that saved a set of variables once a second would wear out the flash in six hours while a program that saved the same data once a day would run for over 50 years and still not wear out the flash. [/quote] |
||||
atmega8![]() Guru ![]() Joined: 19/11/2013 Location: GermanyPosts: 723 |
I can not see that you use it in a not intended way?! Manual on page 47 describes the Syntax and other things. Of course flash has a limited number of write cycles. Please use the PIC Manual about the max. Number of cycles. So don't use it in Loops or something like Loops.... As i remember, it is a max. of 100.000 cycles. Data is retained for over 20 years. |
||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
So I may be able to reduce the writes by doing a Var restore at program initialisation Then if variable changes during program execution do another var restore and if different from restored variable then save variable Mmmm |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
Hi Dave. ![]() Based on your example code, you would be saving the variables once for every cycle of the main DO/LOOP. This is not good(depending on how long it takes for each cycle of that loop), and as the quote posted by BobD shows, this could quite quickly wear out the flash memory, depending on how much time it takes for your loop to cycle. As far as I know, there is no limit to the number of read-cycles, so you can VAR RESTORE as many times as you like, it is just the VAR SAVE that has to be kept under control. Smoke makes things work. When the smoke gets out, it stops! |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
That is certainly an option. You have to think along the lines of: "How do I minimize the number of VAR SAVE commands?" IF you are needing to save data on a regular basis, or be able to write and read stored data quite a lot, you could consider the OPEN LOG device - it is very cheap, and would add a uSD card to your MM chip, and could allow nice easy read/write without having to worry about wearing out the flash in the chip. Take, for example, an FM transmitter. This is a situation where you would set the carrier frequency, stereo or mono, station name etc, and then use the likes of VAR SAVE to store that. Every time the transmitter is powered up, VAR RESTORE would read those details back in, and restore the product to the preset settings. EDIT: OpenLog is a bit more costly then I thought, at $25. However, if you only needed one of them...... You can read about it HERE, and you can purchase it HERE Smoke makes things work. When the smoke gets out, it stops! |
||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
The Open Log device makes sense and I will explore that option |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
See my edit above. I was sure it was cheaper then that, but as I say - if you only need one or two.... EDIT: I have a couple of these modules that I bought, but then never used, so if you are interested, PM me, and I am sure we can come to an arrangement(cheaper then $25). Smoke makes things work. When the smoke gets out, it stops! |
||||
BobD![]() Guru ![]() Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Dave, if you are thinking about getting uSD cards for the Open Log you could try this one Samsung EVO 32GB Micro SDHC for $10. It's on special and won't last long at this price. Buying one is probably not cost effective when you take into account the delivery charge, delivery insurance, and card fees. I was notified about it this afternoon in a newsletter. They do offer order online and then pickup which could be useful if you live in Melbourne's south east. edit: I forgot to add that they are a reasonable organisation to deal with but I think their delivery charges are sometimes over the top. |
||||
memberx Newbie ![]() Joined: 20/04/2012 Location: AustraliaPosts: 24 |
DELETED |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
@halldave, Have you considered using a FRAM memory chip? These are available with SPI or I2C interfaces, and currently go to 32Kx8 for around £8 (smaller available for less - depends on amount of storage you want). The massive advantage of these are they are like FLASH memory BUT without the limited life expectancy. I strongly recommend these for data loggers OR for any other applications requiring a high number writes. I am considering making a breadboard friendly module - is there any interest out there?? WW |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi David, if your project uses an rtc, there is a module that I am using that has a DS3231 rtc with a 24c32 which has 32kbit of space and a high capacity for write read cycles. Here is one on ebay but I am sure there are more out there like this. This could come in handy for storing stuff and not worrying about the flash in the uMite. Edit, here is the data sheet for the chip, says it has 1 million cycles and 100 year retention. Not too shabby for a cheapy unit. |
||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
Wow, purchased one of these $1.86AUD including delivery to Australia.... This will serve two purposes, RTC and 32k ... Thanks to everyone that has provided feedback... I was sure using the uMite save restore was the wrong idea... |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
I agree with everyone else, and EEPROM is the way to go over the open-log - should have thought to mention that in the first place. ![]() Yes, I also have several of those RTC + EEPROM modules. I only ever used one of them, and never got around to using the EEPROM, but the RTC seemed to work OK. At $1.86, beware of WhiteWizard's comments on quality at that price. However for the purposes of testing, they are probably fine. Smoke makes things work. When the smoke gets out, it stops! |
||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
Totally agree - purchased one for testing. I can't see how you can get reliability / quality that cheap . I won't be storing bit coins on it or any thing to do with sheep stations so all good. |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
Just one little thing I will mention - beware of EEPROM page limits. If you are only saving and reading less then the bytes-per-page figure, or you always start your writes from the start of any one page, there will be no problem, but if you have a page size of 128 bytes, and you write MORE then 128 bytes in a single cycle, or you have a page size of 128 bytes, and you start writing at byte 120 and write more then 8 bytes, the page will overflow, and you will overwrite the first part of the page with the extra data. In your sample code, you are only saving a few byte values, so there won't(read: should not!) be a problem so long as you always write at the start of a page. I only mention this, as it confused the hell out of me, when I first started using EEPROM chips, so I don't want you to have the same issues. If you already know about page boundaries with EEPROM's, you can ignore this post. ![]() In my case, I was wanting to store text messages, so it was easy for the page-boundaries to be reached in a single write command, as I was sending the contents of a string, which had the text message, to the EEPROM as one write command, and was getting errors cos I was crossing the page boundaries depending on where on any one page, I started writing from. The PICAXE forums were the people who explained all this to me and helped me understand pages etc, so full credit to those guys. Smoke makes things work. When the smoke gets out, it stops! |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
Hi Grogster, very interesting. Do you think this code will run correctly? '********************************************
'******************************************** ' for 24V32 (32kBit EEPROM) on DS3231 ' MMBasic 4.5 for Maximite/Duinomite ' ' eeWriteS: writes a string to address ' eeWriteN: writes a number (1 byte) to address ' eeReadN: reads a number (1 byte) from address ' address may be between 0 to 4095 ' ' eeErase: deletes the whole eeprom ' eeDump: shows content of eeprom ' ' ' EEPROM-Collection ' by twofingers 08-2014 ' with parts from MMBasic Library ' (should be public domain) ' '******************************************** '******************************************** Option base 0 T$="The BackShed eeprom test " 'eeErase eeWriteS 70, t$ 'eeWriteN 364, 70 'Print eeReadN(364) eeDump End '****************************** Sub eeWriteN (address, Number) ' Write a number to AT24C32 '****************************** I2CADDR=&H57 ' 24C32-DS3231 I2C open 100,100 'ENABLE I2C msb=Int(address/256) 'MSB lsb=address Mod 256 'LSB I2C write I2CADDR, 0, 3, msb, lsb, Number If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub I2C close Print Number;" written into EEPROM." End Sub '****************************** Function eeReadN (address) ' Read a number from AT24C32 '****************************** I2CADDR=&H57 ' 24C32-DS3231 I2C open 100,100 'ENABLE I2C msb=Int(address/256) 'MSB lsb=address Mod 256 'LSB I2C write I2CADDR, 0,2,msb,lsb I2C read I2CADDR, 0,1,eeReadN If MM.I2C <>0 Then Print "ERROR! 1=NAK 2=TIMEOUT"; MM.I2C:eeReadN=-1:End:EndIf I2C close End Function '****************************** Sub eeWriteS (address, text$) ' Writes a string to AT24C32 '****************************** I2CADDR=&H57 ' 24C32-DS3231 a=0 If Len(text$)+address>4095 Then Print "Error: Address to high!":End I2C open 100,100 'ENABLE I2C For x= address To address+Len(text$) a=a+1 msb=Int(x/256) 'MSB lsb=x Mod 256 'LSB I2C write I2CADDR, 0, 3, msb, lsb, Asc(Mid$(text$,a,1)) If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub Pause 5 Next I2C close Print "At"address" string "+Chr$(34)+text$+Chr$(34)+"is written into EEPROM." End Sub '************************************** ' ERASE WHOLE EEPROM (fill with zero) '************************************** Sub eeErase I2CADDR=&H57 ' 24C32-DS3231 K=&H00 'zero value Print "Erasing ..." I2C open 100,100 'ENABLE I2C For J=&h0 To &hF 'MSB For I=&h0 To &hFF 'LSB I2C write I2CADDR, 0,3,j,i,k Pause 2 ' or Pause 5? Write needs some time ... If MM.I2C <>0 Then Print "1=NAK 2=TIMEOUT"; MM.I2C,j,i:End:EndIf Next i L=(j*256+I) Print "Byte ";L, " ";Chr$(13); Next j I2C close Print "EEPROM HAS BEEN ERASED " End Sub '************************************** ' EEPROM komplett LESEN ' Shows content from AT24C32 '************************************** Sub eedump Dim RTCBUFF(4096) I2CADDR=&H57 ' 24C32-DS3231 For I=0 To 4095 RTCBUFF(I)=&H0 Next I Print " Reading buffer in ..." I2C open 100,100 'ENABLE I2C For J=&H0 To &HF For I=&h0 To &hFF L=(j*256+I) I2C write I2CADDR, 0,2,J,I I2C read I2CADDR, 0,1,RTCBUFF(L) If MM.I2C <>0 Then Print "ERROR! 1=NAK 2=TIMEOUT"; MM.I2C,j,i:End:EndIf Next I Next J I2C close Print " Show buffer (Press any key!) ..." For I=0 To 4095 Step 16 Print "Byte ";Format$(I,"%4g");" ||"; For y = 0 To 15 Print Right$("0"+Hex$(RTCBUFF(I+y)),2);"|"; Next y Print "|"; For y = 0 To 15 If RTCBUFF(I+y) >=32 And RTCBUFF(I+y)<=126 Then ' show ascii only C$=Chr$(RTCBUFF(I+y)) Else C$=" " EndIf Print C$; Next y Print "|" wait Next I End Sub ' wait for any key Sub wait Do While Inkey$="":Loop End Sub Or do you expect some problems? I have no fault found. Michael causality ≠correlation ≠coincidence |
||||
halldave![]() Senior Member ![]() Joined: 04/05/2014 Location: AustraliaPosts: 121 |
@twofingers Thankyou for code, will same us all hours.. ![]() |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi TwoFingers, I tried this out and got an error as follows... [161] Print "Byte ";Format$(I,"%4g");" ||"; Error: Expected a number Not sure what went wrong, will try to experiment a bit. Are using MMedit? edit... This is a full screen of what was on terminal after RUN... RUN At 70 string "The BackShed eeprom test "is written into EEPROM. Reading buffer in ... Show buffer (Press any key!) ... Byte [161] Print "Byte ";Format$(I,"%4g");" ||"; Error: Expected a number > edit2... Forgot to mention I am running on a uMite 28 at 48mhz. Thanks |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
Without reading all your code(which I will do later), any EEPROM writes take time. Reads are instant. Most EEPROM chips have a page-write ability, usually either 128 or 256 bytes per page depending on the EEPROM size. # of pages = total EEPROM size divided by page size. Taking it nice and easy for now, lets assume 128 byte pages. Starting at address 00000, you can write up to address 00127 in one command, then you need to wait for a pre-detirmined time to allow the EEPROM to actually commit the bytes to memory - I think it is 50mS for mose EEPROMS, but you'd need to check the datasheet for the EEPROM in question. If you started at address 00125, then you could only write two bytes, then you would have to wait the 50mS period(or whatever it is), so that the data can be committed to memory by the EEPROM. Using the example above, and assuming page-1, if you tried to write five bytes from address 00125, and the bytes were "ABCDE", then the EEPROM would store them in the following addresses: 00125 - A 00126 - B 00127 - C 00000 - D 00001 - E This is cos you have crossed the page barrier within that write command, so the address pointer goes back to the start of that page. If there was data in addresses 00000 and 00001, then it would be automatically overwritten. This can be a problem, depending on how you are using the EEPROM. IN MY CASE, it was an issue, as I was accidentally corrupting my text messages, cos I was not understanding how the page barriers work. As I say - for small amount of data - less then 128 bytes at a time, you won't have this issue, provided you always start writing from the start of a page. If you only write a single byte at a time, you also will not have page issues - it's only if you are "Page writing" or writing a handful of bytes at the same time, and happen to cross the end of the page address. Smoke makes things work. When the smoke gets out, it stops! |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |