![]() |
Forum Index : Microcontroller and PC projects : MMBasic VAR SAVE and VAR RESTORE
![]() ![]() |
|||||
Author | Message | ||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hey Grogster, can you provide a code example of writing something that is bigger than one page? I'm trying to make head or tails of this and really appreciate that you brought this up before us uMiters lost too much hair over this. A big Thank you in advance!!! |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
I'm beginning to wonder if I should have even brought it up.... ![]() I have never written any MM code for EEPROMS, but I will do it for an experiment. All my previous experiments with EEPROMS were in PICAXE chips. The concept remains the same, though. Your confusion is exactly the same as mine was at the time, and page-boundries in EEPROM chips seem to trip up lots of people. I MAKE NO CLAIM TO BEING ANY KIND OF EXPERT HERE - I am just sharing what I found out when I started using EEPROMS. Other members here may have better examples, or may be able to explain it better then I. I will have to research a little on EEPROMS cos I have not used them myself for a year or two, now preferring the ease of SD card files and the likes of the MaxiMite. From memory(pardon the pun!), to page write, the first byte sent is the address, and any subsequent bytes are treated as data, with the EEPROM advancing the address pointer automatically. Anything more then 5mS or whatever the commit period is, and you have to send another address byte before the data bytes. I need to check up on all this, and will have a read and post back some examples later, but the key rule here is: - On any one page, do not cross the page barrier in any one write command. Provided you don't do that, you can store data anywhere you like, and it will be where it is expected to be. Smoke makes things work. When the smoke gets out, it stops! |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
From the Microchip datasheet for the 24LC64 EEPROM(8KB), page 8: That might make it easier to understand then my ramblings..... Smoke makes things work. When the smoke gets out, it stops! |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
@viscomjim the code above is for MAXImite, sorry. Maybe some print-functions are different on µmite? I have no access to µmites. On my Duinomite the output from eeDump looks like this: Perhaps this will work on your µmite also (needs no format$-function)? ' example: T$="The BackShed eeprom test " eeWrite$ 70, t$ Print eeRead$(70,Len(t$))+"<" Print eeGet$(70)+"<" end '****************************** Sub eeWrite$ (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$) 'writes 0-byte at the end! 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 x I2C close Print "At"address" string "+Chr$(34)+text$+Chr$(34)+"is written into EEPROM." End Sub '****************************** Function eeRead$ (address, bytes) ' Reads a string from AT24C32 '****************************** I2CADDR=&H57 ' 24C32-DS3231 eeRead$="" If address>4095 Then Print "Error: Address to high!":End If bytes>255 Then Print "Error: String too long!":End I2C open 100,100 'ENABLE I2C For x= address To address+bytes-1 msb=Int(x/256) 'MSB lsb=x Mod 256 'LSB I2C write I2CADDR, 0,2,msb,lsb I2C read I2CADDR, 0,1,tmp If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub eeRead$=eeRead$+Chr$(tmp) Next x I2C close End Function '****************************** Function eeGet$ (address) ' Gets a zero-terminated string from AT24C32 '****************************** I2CADDR=&H57 ' 24C32-DS3231 eeGet$="" If address>4095 Then Print "Error: Address to high!":End I2C open 100,100 'ENABLE I2C Do msb=Int(address/256) 'MSB lsb=address Mod 256 'LSB I2C write I2CADDR, 0,2,msb,lsb I2C read I2CADDR, 0,1,tmp If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C: End Sub If tmp=0 Then Exit 'leave loop eeGet$=eeGet$+Chr$(tmp) address=address+1 Loop While Len(eeGet$)<255 I2C close End Function Michael causality ≠correlation ≠coincidence |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
@Grogster I think you'll confirm that for Byte Write, as in my code, no problems should be expected? Page Write has some advantage but it maks things more complicated. The Microchip datasheet says a 24C32 has a page size of 8 bytes. Also interesting: 10,000,000 E/W cycles for the first 512 bytes is nice! Important for DS3231-modul user: The 24C32 voltage operating range is 4.5V to 5.5V. The DS3231 should run on 3,3V but I guess 5V is better. I got a strange behavior with 3,3V for the DS3231 (I could not reproduce). Michael causality ≠correlation ≠coincidence |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi TF, I copied this from the amtel website... • Low-Voltage and Standard-Voltage Operation – 2.7 (VCC = 2.7V to 5.5V) – 1.8 (VCC = 1.8V to 5.5V) • Low-Power Devices (ISB = 2 μA at 5.5V) Available • Internally Organized 4096 x 8, 8192 x 8 • 2-Wire Serial Interface • Schmitt Trigger, Filtered Inputs for Noise Suppression • Bidirectional Data Transfer Protocol • 100 kHz (1.8V, 2.5V, 2.7V) and 400 kHz (5V) Clock Rate • Write Protect Pin for Hardware Data Protection • 32-Byte Page Write Mode (Partial Page Writes Allowed) • Self-Timed Write Cycle (10 ms max) • High Reliability – Endurance: 1 Million Write Cycles – Data Retention: 100 Years • Automotive Grade and Extended So, I am guessing that 3.3v should be ok? Also, check the speed... 400khz only at 5v But the Microchip version, which apparently is an obsolete device now has these specs.... • Voltage operating range: 4.5V to 5.5V - Peak write current 3 mA at 5.5V - Maximum read current 150 μA at 5.5V - Standby current 1 μA typical • Industry standard two-wire bus protocol, I2C compatible - Including 100 kHz and 400 kHz modes • Self-timed write cycle (including auto-erase) • Power on/off data protection circuitry • Endurance: - 10,000,000 Erase/Write cycles guaranteed for High Endurance Block - 1,000,000 E/W cycles guaranteed for Standard Endurance Block This one is 4.5v to 5.5v. I will have to zoom into my ds3231/24c32 module and see if I can decipher which manufacturer made the eeprom. As far as the ds3231 it can definitely run on 3.3v. That is all I've ever used with no problems... From Maxim data sheet... Fast (400kHz) I²C Interface 3.3V Operation |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
Hi viscomjim, thanks! You are right. Next time I had to take better befor a look on my modules: its a Atmel! Perhaps i should test the endurance with a now obsolete DS1307/24C32 module. I'm not sure about that. Michael causality ≠correlation ≠coincidence |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
I checked my module also and it is an Atmel. Yeah! I will try your code next. HERE is the link for DS3231. Check the voltage... |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
@viscomjim I have not doubted your words. I know the spezification of the DS3231. Only my experience says something different. For example: I connected to 3,3V and suddenly I lost exact a whole minute, seconds are okay. Or the temperature varies between 0 and 22 °C ... later then everything seems okay again. The reason could be perhaps the wiring, but with 5V are there no issues. But this DS3231 discussion is here off-topic? If I know more then I will tell you. Michael causality ≠correlation ≠coincidence |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi TF, do you have more than one module that you can test? Maybe there is something flaky with that module, but at least it works properly at 5V. Just don't use it in a pacemaker or something like that. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Cheap module . . Something flaky . . . Surely not, how is that possible! ![]() |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
@viscomjim enough! ![]() I hope I will not need such a device in the near future. ![]() @WhiteWizzard Cheap module . . AND cheap wires! I got what I paid for. ![]() 1. working 5V RTC 2ppm drift 2. 4KB EEPROM 3. thermometer 4. CR2032 5. a signal generator (32768 Hz) 6. ... for 1,8 bucks! Thats exactly what I need for my 25 EUR Duinomite or my little 2 EUR arduinos. regards Michael causality ≠correlation ≠coincidence |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9501 |
Confirmed - and exactly right. Byte writing is not a problem, page-writing IS. ...IF you page write, which is what I was doing in my application, then you can easily get yourself into a hell of a mix, which is what happened to me, until the guys over at the PICAXE forums explained pages to me, so I just did not want anyone here having that same issue. The reason your screen-dump works fine, is cos you have the pause 5 after every byte write to the I2C bus, which gives the EEPROM time to commit it, so with that delay in place within the loop, you should have no problems at all byte-by-byte writing across the page boundry. Try doing that as a page write WITHOUT the 5ms delay. ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
@Grogster this way? ![]() '**************************************
' ERASE WHOLE EEPROM (fill with zero) ' using PAGE WRITE '************************************** Sub eeErase Dim fill(34) ' fill will contain 2 bytes for address + 32 fillbytes I2CADDR=&H57 ' 24C32-DS3231 K=&H00 'zero value or some fill value For i = 2 To 34:fill(i)=K: Next i Print "Erasing ..." I2C open 100,100 'ENABLE I2C For J=&h0 To &hF 'MSB For I=&h0 To &hFF Step 32'LSB fill(0)=j:fill(1)=i 'fill(0)+(1) = MSB + LSB I2C write I2CADDR, 0,34,fill(0) 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 Seems to be somewhat faster! The "Page Write" reminds me of the old days with 8086-Assembler, DOS and the "memory segmentation" (in german: Speichersegmentierung). ![]() Michael causality ≠correlation ≠coincidence |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1533 |
As a small supplement or replacement to the code above. eeSaveF and eeLoadF are new. Now you can save and load your floatingpoint vars to/from EEPROM AT24V32. for string handling use ' eeWrite$ ' eeRead$ ' eeGet$ from code above or here: EEPROM0.5.zip edit (21-08-2014):obsolete! ! Some parts are for MAXIMITE-Basic V4.5 only! '******************************************** '******************************************** ' for ATMEL 24V32 (32kBit EEPROM) on DS3231 ' MMBasic 4.5 for Maximite/Duinomite '******************************************** '******************************************** ' ' eeWrite$: writes a string to address ' eeRead$: some bytes from address ' eeGet$: reads a string from address ' eeWriteN: writes a number (1 byte) to address ' eeReadN: reads a number (1 byte) from address ' address may be between 0 to 4095 ' ' eeSaveF: writes a 32 bit floatinpoint number ' eeLoadF: reads a 32 bit floatinpoint number ' to/back from EEPROM using PEEK and POKE ' uses eeWriteN respectively eeReadN ' ' eeErase: deletes the whole eeprom ' eeDump: shows content of eeprom ' ' ' EEPROM-Collection v0.5 ' by twofingers 08-2014 ' with parts from MMBasic Library ' (should be public domain) ' '******************************************** '******************************************** ' example code: Dim Z(20) 'debug = 1 ' debugmode switch test = Pi Print "Save: "test eeSaveF (0, test) test=0 Print "Set to zero:"test eeLoadF (0, test) Print "Restored: "test Print:Print ' test an array For i = 1 To 20 Z(i)=1/i Print "Save: ",i, Z(i) eeSaveF (i*4, z(i)) z(i)=0 Print "Set to zero:",i, Z(i) eeLoadF (i*4, z(i)) Print "Restored: ",i, Z(i) wait "<Press any key>" Next i eeDump End '********** END EXAMPLE CODE ************ '**************************************** '****************************** Sub eeSaveF (address, v) ' Saves a floatingp. var to AT24C32 '****************************** local i For i = 0 To 3 eewriteN address+i, Peek(VAR v,i) Next i End Sub '****************************** Sub eeLoadF (address, v) ' Load a floatingp. var from AT24C32 '****************************** local i For i = 0 To 3 Poke VAR v,i, eeReadN(address+i) Next i End Sub '****************************** Sub eeWriteN (address, Number) ' Write a number to AT24C32 '****************************** local MSB, LSB 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 Pause 5 If MM.I2C <>0 Then Print "Error! 1=NAK 2=TIMEOUT"; MM.I2C:End:EndIf I2C close If debug Then Print Number;" written into EEPROM." End Sub '****************************** Function eeReadN (address) ' Read a number from AT24C32 '****************************** local MSB, LSB 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 '************************************** ' EEPROM komplett LESEN ' Shows content from AT24C32 '************************************** Sub eedump Local i, j, y, L, 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 prompt$ If prompt$<>"" Then Print prompt$ Do While Inkey$="":Loop End Sub Michael causality ≠correlation ≠coincidence |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |