Running out of memory

rmeldo

Senior Member
Hi,

I am running out of space for the code in the 18M2 I am using for my project and I was wondering whether there are good tricks to use when coding the Picaxe to reduce the memory footprint to make more room for extra functionality.


The project is nothing new for this forum, but it is for me, and a very good fun to do:

1) use of an AXE110 datalogger board to log the time at which the magnetic pulses from a domestic gas meter occur
2) send an hourly summary of the counts to a website using an ESP8266 WIFI module.
3) use an AXE33 LCD display which I use as a way of displaying the current readings and selecting a datalink mode (with push switches) to upload the logged pulses to a PC via the AXE027 cable

Because I am using an AXE110 board I cannot upgrade the Picaxe to a more roomy one so I am looking for tips and suggestions for doing what I need using less memory.

I do not have much experience in writing code for small environments so it would be greatly appreciated if someone could take a look at this program to suggest ways of making it smaller.

The code includes:

1) a section which reacts to the pulse from the gas meter
2) a section which reads the time from the RTC when a pulse occur, writes to the EEPROM and check it has been written correctly
3) a section which converts the RTC date and time readings to BCD for display
4) a section which reads the battery voltage and converts to a decimal number (e.g. 4.35V)
5) a section which deals with the transmission of the readings to the PC via the AXE027 cable
6) a section which uses the LCD and the push switches to display different messages and enter the datalink mode
7) a section which drives the ESP8266 WIFI module to upload the hourly summaries to the web server

What I still haven't dealt with is the error handling associated with the connection of the ESP to the router, the web server and the sending of the data. Something like the approach suggested by Hemi345 in this thread: http://www.picaxeforum.co.uk/showthread.php?26811-ESP8266-WiFi-serial-module/page3.

I have however RUN OUT OF MEMORY SPACE.

The code is attached. Any help or tips would be much appreciated.

View attachment Axe110_and_ESP8266_V1_for_forum.bas

Many Thanks
Riccardo
 

BESQUEUT

Senior Member
I think that you can use some GOSUB within the Write Data :

Code:
writedata:
   low B.5  ' write enable eeprom
   i2cslave %10100000, i2cfast, i2cword
   ;------
   Value=sec : GOSUB WriteValue
   Value=minute: GOSUB WriteValue

   ;------
   high B.5        ; write protect AXE110 eeprom
RETURN


WriteValue:
   hi2cout address, (Value)
   pause 10
   hi2cin address, (chkData)
   if chkData <> Value then ee_error
   pause 10
   inc address
return
Any code after
goto addStringLength
will never be executed...
You can remove it...
 

AllyCat

Senior Member
Hi,

You're attempting to put quite a lot of functionality into a humble PICaxe, but as Besqueut says, using subroutines for any "similar" sections of code is probably the answer.

In particular, those "sec, minute, hour..." groups can be replaced with a bptr = 17 (seconds pointer) and then use @bptrinc in the subroutine. Where a second parameter is involved, use peek with another pointer, or maybe read the values from EEPROM.

Similarly, most of the "character strings" can be pulled from EEPROM or DATA memory rather than stored in the program area.

Finally, if you get desperate, I believe there is a second program "slot" in the 18M2+, when used with PE6.

Cheers, Alan.
 

rmeldo

Senior Member
I think that you can use some GOSUB within the Write Data :

Code:
writedata:
   low B.5  ' write enable eeprom
   i2cslave %10100000, i2cfast, i2cword
   ;------
   Value=sec : GOSUB WriteValue
   Value=minute: GOSUB WriteValue

   ;------
   high B.5        ; write protect AXE110 eeprom
RETURN


WriteValue:
   hi2cout address, (Value)
   pause 10
   hi2cin address, (chkData)
   if chkData <> Value then ee_error
   pause 10
   inc address
return
Any code after
goto addStringLength
will never be executed...
You can remove it...
Thanks for that BESQUET. I made the modification you suggested and saved 39 bytes.

I need the code after addStringLength. I had an error, the addStringLength subroutine was missing a return and the goto needed changing to gosub.


ALLYCAT:

I will study the use of the pointers, as it seems like an efficient coding practice.

Could you please elaborate on storing and retrieving the character strings from the DATA area?

Many thanks
Riccardo
 

AllyCat

Senior Member
Hi,

PICaxe Basic doesn't support string variables as such, so it's necessary to write a small loop of code which reads individual bytes from the EEPROM and sends them to the display (or whatever). Of course it needs to determine the number of bytes, perhaps with a leading number or "end" marker, so it's only worthwhile with fairly long strings. I think it's a technique sometimes used in the published PICaxe LCD/OLED driver routines.

A few other observations: sometimes a subroutine isn't the most efficient method (e.g. if used only once) and in your case I think something as simple as #define screenToSleep low c.0 is slightly more compact (but normally macros are less efficeint than subroutines).

The GUIscreen1: subroutine (180 bytes) would probably be more compact with an initial section sending the "Counts:", then a loop which compares "delta" with a variable initialised as 1 and multiplied by 10 on each pass, sending a <space> ($20) until the comparison fails. Then send the "#delta", etc.

Cheers, Alan.
 

rmeldo

Senior Member
Thanks for that.
I will try out your suggestions.
I believe it is also possible to store strings into the axe033.
I will try that too
Riccardo
 

rmeldo

Senior Member
There certainly is with PE6:
http://www.picaxe.com/docs/pe6.pdf
on page 4
New Enhanced Features for Existing PICAXE Microcontroller Parts
Second additional program slot for 14M2, 18M2+ and 20M2 parts, effectively doubling their program capacity.
Thanks westaust55. I looked into this, but got more questions:

1) do I have a 18M2+? I bought the chip recently (~a couple of month ago) . At the moment the Picaxe shop doesn't sell 18M2+ chips. The PE6 anly allow 18M2 and 18M2(v2.C) types
2) Am I already using the additional memory slot? The compiler tells me that the maximum program capacity is 2048 bytes. The manual mentions 600 to 1000 lines of code, but I did not see a figure for a specific number of bytes
3) If I am not using the additional memory yet, how can I enable that space?

Many thanks
Riccardo
 

rmeldo

Senior Member
Reply to my own question 1 above: I do have an 18M2. Just checked with PE6 feature "check Picaxe type connected".

EDIT: this was a typo. I have indeed a 18M2+.
 
Last edited:

AllyCat

Senior Member
Hi,

I'm surprised if a recently purchased chip is still an 18M2 because AFAIK that goes back about 5 years or more, so often the + is not quoted. What does the chip label say?

It's better to consider the slot(s) as "alternative memory" (which runs an alternative program) rather than "extra memory". It's a feature that has been available with X2 chips for some time, so much of the documentation may be there. Personally, I've not yet found the need to use it, but basically I believe you use the RUN slot command which starts the alternative program at its beginning. All variables are NOT reset, so you can transfer a "pointer" to direct the alternative program flow, but all relevant subroutines and interrupts need to be duplicated in each slot.

Cheers, Alan.
 

techElder

Well-known member
Yeah, you have to remember to "run slot#" after you declare variables and set any constant values. Otherwise, you have to do it again in the slot you run.

EDIT: I also find it just as easy to use an #INCLUDE for symbol definitions in each slot.

I use it to keep auxiliary programs separate from the main program. Programs that run when you power up with a button held down, etc. Programs out of the normal operation of the project.
 

lbenson

Senior Member
There is also the "table" command--useful for storing strings. From the description in Manual 2, I am uncertain whether strings stored in "table" are separate from program memory or occupy program memory (which would not help you).

Hmm, the following program is reported in PE 6 as using the same number of bytes with or without the table command commented out, so it would appear that table memory is separate from program memory.
Code:
#picaxe 18m2

table 0, ("Hello, World")

sertxd("Hello")
]
By the way, nice project.
 
Top