Sketch Size too close for comfort :-)

Hi,

I'm working on a little project which is now too big :-)..... Binary sketch size: 30,720 bytes (of a 30,720 byte maximum).

I suspect this is going to cause me problems when the code is running so I have a couple of questions:

  • How many bytes should one really have spare at the end of compile to be safe?
  • I suspect the code below can be optimised to skip the arrays I'm using to convert from floats but not sure how?

Any pointers appreciated as always.

char packetBuffer [60] = {};
    ltoa (nodeRTC, nodeRTCArray, DEC);
    dtostrf(eTS, 0, 2, eTSArray);
    dtostrf(eTA, 0, 2, eTAArray);
    dtostrf(eRH, 0, 2, eRHArray);
    dtostrf(eSR, 0, 2, eSRArray);
    dtostrf(bat_voltage, 0, 2, eBMArray);
    dtostrf(RTCbat_voltage, 0, 2, eBCArray);
    
    strcat(packetBuffer, nodeRTCArray); 
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eTSArray);
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eTAArray);
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eRHArray);
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eSRArray);
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eBMArray);
    strcat(packetBuffer, ":");
    strcat(packetBuffer, eBCArray);

It's hard for us to say anything, as there is not enough code to make a call. You need to post all of your code.

point5:
Hi,

I'm working on a little project which is now too big :-)..... Binary sketch size: 30,720 bytes (of a 30,720 byte maximum).

I suspect this is going to cause me problems when the code is running so I have a couple of questions:

  • How many bytes should one really have spare at the end of compile to be safe?
  • I suspect the code below can be optimised to skip the arrays I'm using to convert from floats but not sure how?

That sketch size is what is written to flash. It does not change at run time. It is fixed. UNO has 32K flash.

What you should be concerned about is RAM usage that generally does change during operation.
Here's a function to test free ram that your stack must fit in.

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Are your buffers such as eTSArray used anywhere else? If not you could reduce to one and intersperse the dtostrf statements with the strcat.

For more fun you could have dtostrf write direct to the appropriate address in the packet buffer.

yup, worry about RAM.
using the correct datatype helps like don't use INT or LONG if you know the number is not more than 10.

Hey Folks,

Many thanks indeed - now shaved 700 bytes off the compile thanks to recycing the Array used to convert the numbers to chars (thanks wildbill).... moving over to checking RAM now :slight_smile:

Hej GoForSmoke , wondering what sort of numbers are good and bad when reported by your freeRam (); function? Ta

That's going to show you the heap size that grows from bottom of RAM up.
You still need room for the stack that starts at the top (in this memory model) and grows down.
How much room you need for stack depends on your function calls (return address is put on the stack) and what args you pass (all go on the stack) and how many levels of those calls get made (a function calls another) and how many local variables of what size each function uses (they go on the stack) which is entirely dependent on the code including library calls. Also note that loops use the stack, for-loops a bit moreso, and that nested loops push the stack deeper.

Still I don't think that on average the stack goes more than 256 bytes and often much less. Add a library and the bets are off though most seem well behaved.

Generally when the heap overwrites the stack the crash will come soon. When the stack overwrites the heap though, there may not be a crash but anomalous behavior you'd expect when bad data gets used.

Often the first clue either way is the Arduino restarting itself.

You could make a big array at the top of the heap and initialize it with a pattern then when the program is "done", have a function check the pattern and find out how far down the stack did reach that time.

If you're really good then you may compute about how much heap and stack your sketch uses, but you'd need to know how the compiler deals with all of it. I'm not that good because I don't try that hard. So instead I keep to practices that minimize indenting and function calls, like using state machines and not nesting loops.

I just wanted to mention...

GoForSmoke wrote "UNO has 32K flash."

32K is not "...a 30,720 byte maximum", but some flash memory gets used for the boot and reprogramming software.

32K is 32768. IIRC boot is now down to either 1024 or 1536 bounded bytes.

I don't know his code or what he's trying to do. There may be lots of room to save. There usually is.

How many constants are in too-big variables, or just aren't needed?
So many fingers type int where short or byte would do purely out of habit.

Would a different approach be smaller?

There's a programmer's saying that was old in 1985: If you want to write a program right, do it twice and throw the first one away. I wonder if two is enough.

I agree with GoForSmoke.

Interestingly, 32768-30720 = 2048 = Two to the eleventh power.

Why 2048 rather than 1024 or 1536? I don't know.

2K bootloader?