M2 Memory

ac21

Member
I have a 20m2 and writing a program the memory became full at about line 638 and I have exceeded 2048 bytes.. and i have a about 300 or so bytes to go to complete the project.

I was looking to buy a 20x2 or 28x2
but in my research ran into this which is kinda confusing.
under the m2 parts other then 08m2 it says x2...what does this mean?
 

Hemi345

Senior Member
It means you can use the new feature of the latest PICAXE Program Editor to use slots to essentially double the program space. See:

http://www.picaxe.com/BASIC-Commands/Directives/hash-slot/

and

http://www.picaxe.com/BASIC-Commands/Advanced-PICAXE-Configuration/run/
 

tony_g

Senior Member
this is a nice new added feature, i have recently been using this alot with 14m2 and 20m2 chips, it allowed me to break my code down between the two slots and run one or the other depending on certain conditions, i dont think i could do without it now lol
 

jims

Senior Member
I have been using this new PE6 feature extensively for several months on 20m2 chips. It works vey well and allows me to add additional features and embellishments to my controllers. The only caution I can give is to be aware that when using the PE6 simulation in this Beta version you can't use a "run 1", or "run 2" statement (you will get a notice from the Picaxe editor that "Run command is not currently simulated"). However these commands work perfectly on real chips. This is the only limitation that I have found, and it's very easy to do a "work around".
Use of the additional slot is another great feature of PE6. Jims
 

erco

Senior Member
That's certainly a noteworthy improvement over PE5 and exactly what it will take to get me to download & use PE6. Clearly the potential was in the chip all along, but PE5 wasn't able to access the second memory slot.
 

ac21

Member
I used up both slots on my 20m2 :(

I read alot of text msgs in the form of:
Code:
            [color=Blue]let [/color][color=Black]LCD1 [/color][color=DarkCyan]= [/color][color=Navy]1     
           [/color][color=Blue]gosub [/color][color=Black]wrins
       [/color][color=Blue]let [/color][color=Black]LCD1 [/color][color=DarkCyan]= [/color][color=Navy]130     
           [/color][color=Blue]gosub [/color][color=Black]wrins
      [/color][color=Blue]for [/color][color=Black]loopcounter [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Navy]17
            [/color][color=Blue]lookup [/color][color=Black]loopcounter,[/color][color=Blue]([/color][color=Red]"  Current Run Time"[/color][color=Blue])[/color][color=Black],LCD1
            [/color][color=Blue]gosub [/color][color=Black]wrchr
           [/color][color=Blue]next [/color][color=Black]loopcounter  
           
      [/color][color=Blue]let [/color][color=Black]LCD1 [/color][color=DarkCyan]= [/color][color=Navy]148     
           [/color][color=Blue]gosub [/color][color=Black]wrins
      [/color][color=Blue]for [/color][color=Black]loopcounter [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Navy]9
            [/color][color=Blue]lookup [/color][color=Black]loopcounter,[/color][color=Blue]([/color][color=Red]"Fuel Level"[/color][color=Blue])[/color][color=Black],LCD1
            [/color][color=Blue]gosub [/color][color=Black]wrchr
           [/color][color=Blue]next [/color][color=Black]loopcounter [/color]
uses a lot of memory so i was thinking since i have 32k of i2c memory I'll store all the text there..

writing the data i would do something like so:
Code:
[color=Blue]hi2csetup i2cmaster[/color][color=Black], [/color][color=Navy]%10101110[/color][color=Black], [/color][color=Blue]i2cslow[/color][color=Black], [/color][color=Blue]i2cword
      hi2cout [/color][color=Navy]10[/color][color=Black], [/color][color=Blue]([/color][color=Red]"  Current Run Time  "[/color][color=Blue])
      hi2cout [/color][color=Navy]20[/color][color=Black], [/color][color=Blue]([/color][color=Red]"Fuel Level          "[/color][color=Blue])[/color]
reading it back and sending it to the LCD is the part i don't understand .
I was thinking a for/loop would work..maybe

Code:
 let LCD1 = 128
	     gosub wrins
	for loopcounter = 10 to 29
	      hi2cin loopcounter , (LCD1)
	      gosub wrchr
	     next loopcounter 

	 let LCD1 = 148
	     gosub wrins
	for loopcounter = 30 to 49
	      hi2cin loopcounter , (LCD1)
	      gosub wrchr
	     next loopcounter
whats the best way to do this? Would this reduce much space for a program with 15(about 20 to be exact) different msgs? Would this reading and writing this way cause much of a difference as far as execution time?

With the AT24C32 i'm using where do I have to stop or run out of memory byte wise ..hi2cout ?, (b0) ?
 
Last edited:

westaust55

Moderator
At post 1 you had filled 2048 bytes and only needed 300 bytes more.
Now you have filled both slots (4096 bytes) of program space.

You can certainly use an external EEPROM for messages - 15 messages at 20 characters each will save around 300 bytes.
Possibly less as you still need code to read the data in from EEPROM and SEROUT commands to pass the messages to the display.

Reading back from EEPROM can be of the form:
Code:
hi2csetup i2cmaster, %10101110, i2cslow, i2cword
 b0 = 10 (later 20 for second message)
b1 = b0 + 9
For b2 = b0 to b1      
  hi2cin b2, (b3)
  SEROUT <pin>, <Baudrate>, (b3)
Next b2
Maybe time to post your entire code so folks here can see where there may be opportunity for optimisation to reduce program space.

also if writing 10 byte messages to EEPROM be aware of the typically 64 byte page boundary. Trying to wring past a 64 byte boundary with a mutli byte i2c write command will result in wrap around within the EEPROM page and data in EEPROM plus messages when read back will be corrupted. Read about page writes in the EEPROM datasheet.
 

AllyCat

Senior Member
Hi,

Are yoiu using the PICAXE's internal EEPROM? That can be loaded directly when programming, you wouldn't need to write extra code to write the message data into the external EEPROM chip. Also, are you using one of the PICaxe display boards that have optional messages available within the (18M2) processor?

256 bytes of on-chip EEPROM might not contain all your messages, but you might get very close with a few "tricks" such as starting each string with a numerical value that specifies how many spaces are located at the start (and/or end) of the text (and of course omitted from the strings themselves).

You are correct that "messages" do use a lot of program space, but there are also probably many other ways that the code can be written more efficiently (compactly).

Cheers, Alan.

PS: Ah, this post has started a new page, make sure you take in the details of westy's previous post.
 

ac21

Member
At post 1 you had filled 2048 bytes and only needed 300 bytes more.
Now you have filled both slots (4096 bytes) of program space.
Yes with the new found space I started adding features and got carried away
I'm working on a generator piggyback control module..
I added a menu for the 20x4 display which took most of the space.
I know the code can be written more efficiently but i'm at the point where i want to get this done, or at a presentable state and then go back and work on it. If that makes any sense:confused:

15 messages at 20 characters each will save around 300 bytes.
that may work:p

also if writing 10 byte messages to EEPROM be aware of the typically 64 byte page boundary. Trying to wring past a 64 byte boundary with a mutli byte i2c write command will result in wrap around within the EEPROM page and data in EEPROM plus messages when read back will be corrupted. Read about page writes in the EEPROM datasheet.
This is a datasheet for the same type (AT24C32) i'm using.
The 32K/64K EEPROM is capable of 32-byte page writes.
Is the page boundary 32 bytes or does it mean at one time?

It says
(EEPROM) organized as 4096/8192 words of 8 bits each
and not bytes .. what does this mean?


Code:
[color=Navy]#terminal 9600[/color]
[color=Blue]setfreq m8
hi2csetup i2cmaster[/color][color=Black], [/color][color=Navy]%10101110[/color][color=Black], [/color][color=Blue]i2cslow[/color][color=Black], [/color][color=Blue]i2cword
      for [/color][color=Purple]w3 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Navy]62000
            [/color][color=Blue]hi2cout [/color][color=Purple]w3 [/color][color=Black], [/color][color=Blue]([/color][color=Red]"T"[/color][color=Blue])
                  pause [/color][color=Navy]4
              [/color][color=Blue]hi2cin [/color][color=Purple]w3 [/color][color=Black], [/color][color=Blue]([/color][color=Purple]w1[/color][color=Blue])
             sertxd ([/color][color=Black]#[/color][color=Purple]w3[/color][color=Black],[/color][color=Red]"="[/color][color=Black],[/color][color=Purple]w1[/color][color=Black],[/color][color=Red]" "[/color][color=Blue])
           next [/color][color=Purple]w3[/color]
in this code what can i expect w3 to stop writing at if w3 wasn't limited. (around 65535?)

Also, are you using one of the PICaxe display boards that have optional messages available within the (18M2) processor?
no i'm running a display in four bit mode off the 20m2

PS: Ah, this post has started a new page, make sure you take in the details of westy's previous post.
I wont miss anything, but taking in the details is another thing.
there is a option in the settings where the forum doesn't break down to pages so often.
 
Last edited:

Rick100

Senior Member
Hello ac21,
How long do your messages need to be? I would organize the data for the 24c32 in 16 byte chunks. Each chunk would start on a 16 byte boundary so you would avoid the page boundary problem. Your messages could be a max of 16 bytes or terminated with a zero. The 24c32 holds 4096 bytes, so it could hold 256 messages of 16 bytes or shorter. I have some code for using this method. It uses one program for programming data into a seeprom 256 bytes at a time. I also have a print string routine that prints a zero terminated string from a seeprom. I can post them if your interested. They could also be modified for 32 byte messages if 16 bytes isn't enough.

Good luck,
Rick
 

ac21

Member
Hey Rick100, I wanted to write the messages 20 bytes at a time so it would be easier to write to the 20x4 display.

When you say terminated with a zero what does that do?

Yes can you please post that code.
 

Rick100

Senior Member
When you say terminated with a zero what does that do?
Hello ac21,

Zero terminated string just means the value zero is used to marked the end of the string of text characters. The print string routine will fetch characters from the seeprom and print them to an LCD, or in the test code to the serial terminal, until it reads a zero.
Here is the code for filling the seeprom. It works by transferring 256 bytes from the Picaxe internal eeprom to the i2c seeprom. To use it, you will have to enter your text into the eeprom commands. Enter a maximum of 16 characters for each eeprom command. You can enter fewer than 16 bytes by adding the zero terminator. Each eeprom command has an address that is a multiple of 16. The program reads the Picaxe internal eeprom 16 bytes at a time and writes them to the 12c eeprom. To program more than addresses 0 - 255 of the i2c eeprom, you have to change the eeprom statements to the next 256 bytes of data and change the seepromAddOffset variable. The code has examples remarked out for different address blocks. To program the entire 4096 bytes of your 24c32 you would have to modify and run the code 16 times. I've run the code on a tinyrtc board with a ds1307 rtc and a 24c32 eeprom.

Here's the seeprom filling code:
Code:
'program i2c seeprom by transferring all 256 bytes of Picaxe eeprom in 16 byte blocks
'useful for putting text in seeprom
'seepromAddOffset controls start address of where block will be written into seeprom
'seepromAddOffset should be multiple of 256 ex: 0,256,512,768
'program will have to be run multple times with Picaxe eeprom data and seepromAddOffset changed to fill seeprom
'should work on 24x32 on up
'tested on a tinyrtc board with  a ds1307 and a 24c32 seeprom 
'used i2cslow so ds1307 wouldn't get confused

#picaxe 08M2

symbol eepromAdd = b4	'address for Picaxe eeprom
symbol loopCnt = b5
symbol loopCnt2 = b7
symbol inByte = b8

symbol seepromAdd = w10	'address for serial eeprom
symbol seepromAddOffset = w11	'offset where 1st byte of data will be wriiten into seeprom


	setfreq m8
	pause 1000
	
	hi2csetup i2cmaster, %10100000, i2cslow_8, i2cword
	
	seepromAddOffset = 0	'address 0 - 255 of seeprom
	'seepromAddOffset = 256	'address 256 - 511 of seeprom
	'seepromAddOffset = 512	'address 512 - 767 of seeprom
	'seepromAddOffset = 768	'address 768 - 1023 of seeprom
	'seepromAddOffset = 3840	'address 3840 - 4095 of seeprom / last 256 bytes of 24x32
	'etc...



	seepromAdd = seepromAddOffset
	eepromAdd = 0

	for loopCnt = 0 to 15
	sertxd("Programming Address = ",#seepromAdd,13,10)
		'read 16 bytes of data out of eeprom and store in ram stating at address 64
		bptr = 64
		read eepromAdd,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptr 'read 16 bytes from eeprom
		'write the 16 bytes starting at ram address 64 into seeprom
		bptr = 64
		hi2cout seepromAdd,(@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptr) 'write 16 bytes to seeprom
		pause 10	
		eepromAdd = eepromAdd + 16	'point to start of next 16 bytes in eeprom for next read
		seepromAdd = seepromAdd + 16	'point to start of next 16 bytes in seeprom for next write
	next


	'now read what we just programmed into the seeprom and print it
	sertxd("dump",13,10)
	seepromAdd = seepromAddOffset
	for loopCnt = 0 to 15
		sertxd(#seepromAdd," ")	'print the address
		for loopCnt2 = 0 to 15
			hi2cin seepromAdd,(inByte)	'read a byte from th seeprom
			if inByte > 31 and inByte < 127 then	'only printable characters
				sertxd(inByte)
			else
				sertxd("#")	'unprintable characters
			endif
			inc seepromAdd
		next
		sertxd(13,10)	'new line
		
	next

	end
	
'---------------------------------------------------
'256 bytes of eeprom data (address 0 - 255) in 16 byte blocks
eeprom 0,("123456789012345",0)	'max 16 bytes
eeprom 16,("test 1",0)	'max 16 bytes
eeprom 32,("Hello World",0)	'max 16 bytes
eeprom 48,("1234567890123456")	'max 16 bytes
eeprom 64,("123456789012345",0)	'max 16 bytes
eeprom 80,("123456789012345",0)	'max 16 bytes
eeprom 96,("123456789012345",0)	'max 16 bytes
eeprom 112,("123456789012345",0)	'max 16 bytes
eeprom 128,("123456789012345",0)	'max 16 bytes
eeprom 144,("123456789012345",0)	'max 16 bytes
eeprom 160,("123456789012345",0)	'max 16 bytes
eeprom 176,("123456789012345",0)	'max 16 bytes
eeprom 192,("123456789012345",0)	'max 16 bytes
eeprom 208,("123456789012345",0)	'max 16 bytes
eeprom 224,(0)							'max 16 bytes
eeprom 240,("123456789012345X")	'max 16 bytes


The next program is test code that uses the printString subroutine. It prints to the terminal but you can change it to send the characters to your LCD. To use it set the seepromAdd variable to the seeprom addres for the start of the message. This will be a mulyiple of 16. For example the first message(message 0) will have an address of 0 or 0*16, the second(message 1) will have an address of 16 or 1*16. The last message in the first 256 bytes(message 15) will have a start address of 240 or 15*16. The printString routine will fetch and print 16 characters or stop when it fetches a zero. Change the line "sertxd(inByte)" to send the inByte to your LCD.

Code:
#picaxe 08M2
#no_data

symbol loopCnt = b5
symbol inByte = b8	'data byte for printString
symbol temp = b9

symbol seepromAdd = w10	'address for seeprom read
symbol loopCnt2 = w11


	setfreq m8
	pause 1000
	sertxd(13,10)	'new line

	hi2csetup i2cmaster, %10100000, i2cslow_8, i2cword	'set up the i2c bus for seeprom
	
	seepromAdd = 16		'message 0
	'seepromAdd = 4080	'last 16 byte message
	'seepromAdd = 4064	'next to last 16 byte message
	gosub printString
	sertxd(13,10)
	
	seepromAdd = 240		'message 15
	gosub printString
	sertxd(13,10)
	
	
	
'	for loopCnt2 = 0 to 240 step 16
'		seepromAdd = loopCnt2
'		sertxd("add = ",#seepromAdd," ")
'		gosub printString
'		sertxd(13,10)
'	next
	
	end

'print a string in seeprom pointed to by seepromAdd terminated with zero or 16 characters long
printString:
	temp = seepromAdd // 16	'check that address is on 16 byte boundry
	if temp != 0 then
		sertxd("address ",#seepromAdd," not on 16 byte boundry",13,10)
		goto exPrintString
	endif
	loopCnt = 0
	hi2cin seepromAdd,(inByte)	'read a byte from th seeprom
	do while inByte <> 0 and loopCnt < 16
		sertxd(inByte)		'output to terminal or LCD
		inc loopCnt
		inc seepromAdd
		hi2cin seepromAdd,(inByte)	'read a byte from th seeprom
	loop
exPrintString:
	return	'printString

Good luck,
Rick
 
Top