Strange Problem Compiling - when adding just one byte?

Hi,

I have a strange problem with a program I'm working on. I have a place in my code that where if I add just one character to the serial string I send out for debugging the program fails to launch anymore.

Program's Stats:

"Sketch uses 20322 bytes (70%) of program storage space. Maximum is 28672 bytes.
Global variables use 1296 bytes (50%) of dynamic memory, leaving 1264 bytes for local variables. Maximum is 2560 bytes."

example from the code where the problem happens:

        //Test Lines - Adding one more character to any of these causes program not to launch
        //as well as adding 10 bytes to compiled file size (anywhere else I add a character to a string it only add 1 as it should)
        
        Serial.print("This Ok");                   //This works fine
        Serial.print("This Ok");                   //This works fine (unless I add one more character)
        Serial.print("This Ok");                   //This works fine
        Serial.print("This Ok");                   //This works fine

        //Can't enable this???                  This is where I first noticed the problem (when this was uncommented)
        //Serial.println("Inside Setup Loop");

        WaitKey();                                  //When it's running we get here no problem

In any one of those lines above, if I add just one character, the program will no longer boot. Additionally, I noticed that in that location just adding the one character adds ten bytes to the code size rather than 1. Very strange... I also confirmed this behavior on a brand new installation on another computer with the same exact results :disappointed:

Also, I don't know of a good dis-assembler that I might be able to use in the IDE to try and resolve this problem...so if anyone knows of one (or has any insight to this problem!) I would be most grateful to hear from you!

Thanks!!!

Hello mottretop

Use the F-macro:

like old

Serial.println("Inside Setup Loop");

to new

Serial.println(F("Inside Setup Loop"));

for all Serial.println() calls.

Have a nice day and enjoy coding in C++.

Hi Paul,

Thanks for the quick reply...I have dozens of other Serial.print statements that have been working just fine until this.

Any idea why this could happen (so I can develop a better understanding)?

Thanks!

Hello mottretop,

take a view here to gain the knowledge.

Thanks for that link!

While this solves my immediate issue it's not clear why calling it from ROM at print time instead of SRAM would make any difference (but obviously it does).

There doesn't seem to be a "rule" I broke here and the original code should have executed just fine except there must be some underlying issue that the compiler has at this location in the program (hence adding 10 bytes instead of one, where anywhere else adding 1 character adds only 1 to the final size).

Since I came across this problem while actually adding valid code which essentially caused the same problem (and I just backed off to focus on the string) I'm sure I'll see this issue crop up again since I'm only about 50% done with the program...

Thanks again!!

Below, the two character strings are the same, and are stored as just one string.

If you add one character to the second, that is a new 11 byte string, which is stored separately. So adding 1 byte consumes 11 additional bytes of memory.

Serial.print("This Ok");                   //This works fine
Serial.print("This Ok");                   //This works fine (unless I add one more character)

Re:

Global variables use 1296 bytes (50%) of dynamic memory, leaving 1264 bytes for local variables.

If you have a TFT display, that dynamically consumes another 1024 bytes which do not show up in the summary. Likewise an SD card takes up 512 bytes per open file, at run time.

That is one reason why we ask people to post ALL the code.

Hi J,

Ok that I can understand about the weird byte count then!

I'm still stumped on why adding one character causes it to fail...

Here's the entire code...

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Define function prototypes (so the compiler knows they are there)



void Print_Variables();
void Display_Axis();
void displayMenu(const char*, int , int );
void WaitKey1();
void WaitKey2();
void WaitKey3();
void WaitKey4();



int GetIncDecSelect();
int GetKeyCode();


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//OLED_SSD1306_Chart display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

char actualThickness;                                                   //Line Type?

#define ChartX 34
#define ChartY 16
#define ChartWidth 112
#define ChartHeight 48
#define TopSpace 16

#define BufferSize 128

int rawValue;                                                           //Store temp values here
uint16_t scaledValue;

//----------- Keys ---------------------

const int TestKey = 7;                          //Use this pin to stop execution at points

const int NextKey = 8;							//These are the pin numbers that the keys are wired to
const int BeforeKey = 9;
const int IncKey = 10;
const int DecKey = 11;
const int SelectKey = 12;

const int NextKeyCode = 1;						//These are the key codes
const int BeforeKeyCode = 2;
const int IncKeyCode = 3;
const int DecKeyCode = 4;
const int SelectKeyCode = 5;

int nextKeyCount;                               //Accumulate counts of how long a key is down
int beforeKeyCount;
int incKeyCount;
int decKeyCount;
int selectKeyCount;
int nextModeCount;                              //These count how long mode change keys were pressed
int beforeModeCount;

int KeyCode;                                                        //This guy stores the key codes
int thisKeyCode;                                                    //This get KeyCode passed to it for use
int thisSelection;                                                  //Used to determine where Select happened

// Main Setup Select menu

String Main_Setup_String = "  ---- SETUP ----";

const int Num_Main_Menu_Items = 5;
const char* Main_Menu_Items[Num_Main_Menu_Items] = {"Set Lim. + Scale",
                                                    "Configure Graph",
                                                    "Configure Outs",
                                                    "Reset Stats",
                                                    "Exit to Run"};             //The last one is always reserved 
                                                                                //as a retrun vector

int currentSelection = 0;

int cursor_position = 0;
int value;

int power_of_10 ;
int digit;


//------------------------------
// Editable Menus

String Lim_Scl_String = " -- Limit and Scale --";
const int& Lim_Scl_Num_Items = 4;
const char* Lim_Scl_Menu_Items[Lim_Scl_Num_Items] =  {"Trig. Level:",
                                                      "Scale :",
                                                      "Zero Mode",
                                                      "Exit "};

int Lim_Scl_Values[Lim_Scl_Num_Items-1] = {0, 0};

String Cnfg_Grph_String = " -- Config Graph --";
const int& Cnfg_Grph_Num_Items = 4;
const char* Cnfg_Grph_Menu_Items[Cnfg_Grph_Num_Items] =  {"Grph 1:",
                                                      "Grph 2",
                                                      "Grph 3",
                                                      "Exit "};

int Cnfg_Grph_Values[Cnfg_Grph_Num_Items-1] = {0, 0};


String Cnfg_Ana_String = " -- Config Analog --";
const int& Cnfg_Ana_Num_Items = 4;
const char* Cnfg_Ana_Menu_Items[Cnfg_Ana_Num_Items] =  {"Analog 1:",
                                                        "Analog 2",
                                                        "Analog 3",
                                                        "Exit "};

int Cnfg_Ana_Values[Cnfg_Ana_Num_Items-1] = {0, 0};

String Rst_Sts_String = " -- Reset Stats --";
const int& Rst_Sts_Num_Items = 4;
const char* Rst_Sts_Menu_Items[Rst_Sts_Num_Items] =  {"Stat 1:",
                                                      "Stat 2",
                                                      "Stat 3",
                                                      "Exit "};

int Rst_Sts_Values[Rst_Sts_Num_Items-1] = {0, 0};






int ThisMenuItem;
int ThisDigit;
bool ThisEditMode;

bool exitMenu = false;

int DIGITS_PER_VALUE = 3;

int maxValue;
int minValue;




//Y Axis Struff

int LineX		= 30;                                               //These locate the vertical axis
int LineYTop	= 16;
int LineYBot	= 64;

int vTick = 10 ;                                                //Set to how many ticks you want

int TopYValu = 1000;
int BotYValu = -10;


//----------------------------------
// Buffer Stuff

uint16_t OscBuffer[BufferSize];

int BuffInPtr = 0;
int BuffOutPtr = 0;                                             //Probably will need this later to better syns in/out of the buffer

int ChartUpdateSpeed;

uint32_t currentTime;                                           //Used to time the re-drawing of the trace
uint32_t lastUpdateTime;

int PlotValue;

//-------------------------------
//  Mode Stuff

const int MaxModes = 4;                                         //Max Mode number allowed before wrap
int LastMode;                                                   //Used to detect mode transitions
int RunMode;                                                    //  1 = Run Mode
                                                                //  0 = Setup Mode





int setupSel;


//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//--------------------------------------------------------------------
//  Program Setup 

void setup() {
  Serial.begin(9600);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

   
  display.clearDisplay();                         // Clear the display
  display.setTextSize(1);                         // Set text size to 1
  display.setTextColor(WHITE);                    // Set text color to white


  //Display_Axis();                                 //Display the vertical axis (later pass variables?)
  //display.display();                              //Display it

  //while(1);


  lastUpdateTime = 0;
                  
  RunMode = 0;                                    // Startup in Run Mode thinking we need to update display
  LastMode = 99;                                  //Trick it to update the axis        


                                                  //Add code here to look at a switch to be off to go further



 ChartUpdateSpeed = 100;                          //Set this for test !!!

// Timer 3 setup for 10ms to be used to scan the keypad in the background and other fun things

  // Set Timer3 to CTC (Clear Timer on Compare) mode
  TCCR3A = 0;
  TCCR3B = 0;
  TCCR3B |= (1 << WGM32); // set CTC mode
  
  // Set the compare match value to 1562 (10ms with a 16MHz clock and a prescaler of 1024)
  OCR3A = 1562;

  // Set the prescaler to 1024
  TCCR3B |= (1 << CS32) | (1 << CS30);

  // Enable the compare match interrupt for Timer3
  TIMSK3 |= (1 << OCIE3A);


 //------------------------------------------------
 // Keypad Stuff

  pinMode(NextKey, INPUT_PULLUP);                 //Define the keys and pullups. This needs to get changed to IC variety
  pinMode(BeforeKey, INPUT_PULLUP);
  pinMode(IncKey, INPUT_PULLUP);
  pinMode(DecKey, INPUT_PULLUP);
  pinMode(SelectKey, INPUT_PULLUP);
  KeyCode = 0;                                   //Access this variable only through GetKeyCode()
  

  pinMode(TestKey, INPUT_PULLUP);   


}


//--------------------------------------------------------------------------------------------------------
//======================================  Main Loop  =====================================================

void loop() {
 

 


  //---------------------------------------------------------------------------------------------------------
  // RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
  // Run Mode = RunMode = 0

    if (RunMode == 0){
 

        if (LastMode > 0){                                      // If we just came off of setup re-display the axis
    
            display.fillRect(0, 16, 32, ChartHeight, BLACK);
            Display_Axis();                                     //Re-Display the axis
            display.display();
            LastMode = 0;                                       // Indicate we are fully in Run Mode now
            int clrKeyCode = GetKeyCode();                      //Clear any old codes
            Serial.println(" 1st into Run Mode");
            WaitKey();
        }
        


        //----------------------------------------------------------------------------------------------------
        // Update the display while in Run Mode

        uint32_t currentTime = millis();

        // See if it's time to update the display with a new plot.

        if (currentTime - lastUpdateTime >= ChartUpdateSpeed) {

            lastUpdateTime = currentTime;

            //----------------------------------------------------------------------
            // Read analog input from pin A5 and scale it

            rawValue = analogRead(A5);

            // Scale the analog 12 bit value to ChartHeight
            
            scaledValue = map(rawValue, 0, 1023, ChartHeight, 1);

            //----------------------------------------------------------------------
            // Store the scaled value in the circular buffer

            OscBuffer[BuffInPtr] = scaledValue;

            // Move the buffer pointer by one

            BuffInPtr++;

            if (BuffInPtr >= BufferSize) { BuffInPtr = 0; }                               //Check for rollover

            //--------------------------------------------------------------------------------------
            // Plot the buffer back into the OLED Chart Area

            // First clear only the section of the screen for plotting

            display.fillRect(ChartX, ChartY, ChartWidth, ChartHeight, BLACK);

            // Plot the contents of the buffer into the chart area

            BuffOutPtr = BuffInPtr;                                                         //Grab a copy of the pointer we used to put the value in


            for (int x = 0; x < ChartWidth; x++) {                                          //This loops through the buffer ChartWidth times
     
                BuffOutPtr--;                                                               //Decrement the buffer pointer
                if (BuffOutPtr < 0) { BuffOutPtr = BufferSize-1;  }                         //If we decremented past the beginning of the buffer                                      
      
                PlotValue = OscBuffer[BuffOutPtr];                                          //Point to the next element
                display.drawPixel(x + ChartX, PlotValue + TopSpace, WHITE);
      
            }
       

            //------------------------------------------------------------------------------
            // Display the values on the OLED Display

            display.fillRect(0, 0, 128, 16, BLACK);       //Clear the upper yellow part first

            display.setCursor(20, 0);
            display.print("Osc Count: ");
            display.print(rawValue);                  // Adds CRLF
 
  
            display.setCursor(20, 8);
            display.print("Scaled Value: ");
            display.print(scaledValue);


            display.display();

        }
    }





      //------------------------------------------------------------------------------------------------------------------------
      // SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
      //--------------------------------------------------
      //    Setup Mode

    else  if (RunMode == 1) {                                                   //This is Main Menu "Mode"

        //----------------------------------------------------
        //If we are just getting here display the main menu

        if (LastMode != 1){

            currentSelection = 0;                                                               //Start st the top of the menu
            //displayMenu(Main_Menu_Items, Num_Main_Menu_Items, Main_Setup_String, currentSelection);                                                              // Put up the menu
            
            display.clearDisplay(); 
            display.setCursor(0, 0);
            display.println(Main_Setup_String);                                        //Display the header

            
            display.display();
            int clrKeyCode = GetKeyCode();                                              //Clear any old codes
            LastMode = 1;                                                               //Fully in Setup Mode
                
            Serial.println(" 1st into Setup Mode");
            WaitKey();

        }

        // Check for key presses and set the Run Mode accordingly (causes execution to transfer to another menu )

        setupSel = GetIncDecSelect();                                                       //See what we got

        //Serial.print(setupSel);

        if (setupSel == Num_Main_Menu_Items){   RunMode = 0;  }
        if (setupSel == 1) {   RunMode = 2;  }
        if (setupSel == 2) {   RunMode = 3;  }
        if (setupSel == 3) {   RunMode = 4;  }
        if (setupSel == 4) {   RunMode = 5;  }

        //Serial.println("Inside Setup Loop");

        //Test Lines - Adding one more charater to any of these causes program not to launch
        //as well as adding 10 bytes to compiled file size (anywhere else I add a charqacter to a string it only add 1 as it should)

        Serial.print("1his Ok");                   //This works fine
        Serial.print("2his Ok");                   //This works fine (unless I add one more charcter)
        Serial.print("3his Ok");                   //This works fine
        Serial.print("4his Ok");                   //This works fine

        //Can't enable this???                  This is where I first noticed the problem (when this was uncommented)

        //Serial.println(F("Inside Setup Loop"));

        WaitKey();                                  //When it's running we get here no problem

    }

    //Print this once through the loop to see what's doing
    Print_Variables();

}   //Main Loop end



//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
// Routines


//------------------------------------------------------------------
// Increment , Decrement, and Select for Menus
// Note: currentSelection is 0 based and thisSelection starts at 1 (they are offset by 1
//such that thisselection (the returned value ) = 0 when there was no valid key)

int GetIncDecSelect(){

        thisKeyCode = GetKeyCode();                                                             //See if we have any keyes
        thisSelection = 0;

        switch (thisKeyCode) {
            case IncKeyCode:
                if (currentSelection == 0) {
                    currentSelection = Num_Main_Menu_Items - 1;                                 //Set it back to the bottom
                } 
                else {
                    currentSelection--;                                                         //Just go down 1
                }
                break;

            case DecKeyCode:
                if (currentSelection >= Num_Main_Menu_Items-1) {
                    currentSelection = 0;                                                        //Loop to top
                }
                else {
                    currentSelection++;                                                          //Up one
                }
                break;

            case SelectKeyCode:
                thisSelection = currentSelection + 2;                                            // Add in the offset to the position and change to that mode
                break;
        }
    return thisSelection;

}


//--------------------------------------------------------------------------------------------------------------
// Update the display with whatever menu is presented. "currentMenuItem" points to the line to highlight

void displayMenu(const char* menuItems[], int numMenuItems, int currentMenuItem) {

    //display.clearDisplay();     //!!! this may be a problem

    display.fillRect(0, 16, 128, 48, BLACK);                            //Clear the lower blue part
    display.setTextColor(SSD1306_WHITE);
    display.setTextSize(1);

    for (int i = 0; i < numMenuItems ; i++) {                           //Loop till done
        if (i == currentMenuItem) {
            display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
            Serial.println("Reverse Color");
        }
    display.setCursor(0, i*10 + 16);
    display.println(String(i+1) + ". " + menuItems[i]);
    display.setTextColor(SSD1306_WHITE);
    Serial.println("Standard Color");
    //    Serial.println(i);
    }
    display.display();
}


//--------------------------------------------------------------------------------------------------------------
// Display Axis

void Display_Axis(){


    int tickSpacing = (LineYBot - LineYTop) / (vTick - 1);              //calculate spacing between tick marks
    int tickValueSpacing = (LineYTop - LineYBot) / (vTick - 1);         //calculate spacing between tick values
  
    //print axis top and bottom values
    display.setCursor(0, LineYTop );
    display.println(TopYValu);
    display.setCursor(0, LineYBot - 8);
    display.println(BotYValu);
  
    //draw vertical line
    display.drawLine(LineX, LineYTop, LineX, LineYBot, WHITE);
  
    //draw tick marks
    for (int i = 0; i < vTick; i++) {
        int tickY = LineYTop + i * tickSpacing;
        display.drawLine(LineX - 3, tickY, LineX, tickY, WHITE);
    }
    display.display();

}



//--------------------------------------------------------------------------------------------------------------
// Send out variables for debug

void Print_Variables(){

    Serial.print("RunMode: ");
    Serial.println(RunMode);

    Serial.print("LastMode: ");
    Serial.println(LastMode);

    Serial.print("KeyCode: ");
    Serial.println(KeyCode);

	//delay(500);

  if (RunMode == 0) {                                       //Main Running


    Serial.print("Raw ADC: ");
    Serial.println(rawValue);
    Serial.print("Scaled Value: ");
    Serial.println(scaledValue); 
  }

    if (RunMode == 1) {                                     //Setup Main Menu

    Serial.println("Setup Mode");
    Serial.print("Setup Current selection: ");
    Serial.println(currentSelection);
    Serial.print("this key code in Setup: ");
    Serial.println(thisKeyCode);

    

  }


    else if (RunMode == 2) {                                //Set Scale and Limits 

        Serial.println("Set Scale and Limits Mode");

        Serial.print("This Menu Item: ");
        Serial.println(ThisMenuItem);

        Serial.print("This Key Code: ");
        Serial.println(thisKeyCode);   

        Serial.print("This Edit Mode: ");
        Serial.println(ThisEditMode);   

        Serial.print("Max Value: ");
        Serial.println(maxValue);   

        Serial.print("Min Value: ");
        Serial.println(minValue);   

    }

    else if (RunMode == 3) {                                //Configure Graph

        Serial.println("Configure Graph Mode");

    }

   else if (RunMode == 4) {                                //Reset Stats
        Serial.println("Reset Stats");

    }
}



//--------------------------------------------------------------------------------------------------------------
void WaitKey(){

    Serial.println("Wait...Press button to continue...");

    //added another switch for this so as not to mess up key reads

    while (digitalRead(TestKey) == HIGH) {
        delay(10);  // Wait for a short period of time before checking again
    }
     while (digitalRead(TestKey) == LOW) {
        delay(10);  // Wait for a short period of time before checking again
    }
    Serial.println("Button pressed... Code execution resumed.");
}


    
//--------------------------------------------------------------------------------------------------------------
//
// Interrupt Service Routine for Timer3 compare match A

ISR(TIMER3_COMPA_vect) {

const int keyCountTrig = 2;                                                  //Set how many times key needs to be on       

    //First check if mode keys (Before-Next) are in effect in conjunction with select key.
    //This must be first since we require the countes we set last time in here (that they are enough and the user got off the keypad)

    if (nextKeyCount >= keyCountTrig &&  selectKeyCount >= keyCountTrig ) {             //If the two keys had been both down long enough

        if (digitalRead(NextKey) == HIGH || digitalRead(SelectKey) == HIGH  ) {         //AND their firnger has come off either one (or both)
              	
            if (RunMode >= MaxModes) {

      		    RunMode = 0;                                                            //Roll over to Running Mode
            }
		    else {

        	    RunMode++;                                                              //Go to forward to the last one
      	    }

        }
    }

    if (beforeKeyCount >= keyCountTrig &&  selectKeyCount >= keyCountTrig ) {           //If the two keys had been both down long enough

        if (digitalRead(BeforeKey) == HIGH || digitalRead(SelectKey) == HIGH  ) {       //AND their finger has come off either one (or both)
              	
            if (RunMode > 0) {

      		    RunMode--;                                                              //Go to back a Mode
            }
		    else {

        	    RunMode = MaxModes;                                                     //Go to backwards to the last one
      	    }

        }
    }

    //Now we need to sort through and prioritize KeyCode from top to last (or none) from last pass through

    if (nextKeyCount >= keyCountTrig && digitalRead(NextKey) == HIGH) {                 //Wait for them to come off the key
        KeyCode = NextKeyCode;
    } else if (beforeKeyCount >= keyCountTrig && digitalRead(BeforeKey) == HIGH) {
        KeyCode = BeforeKeyCode;
    } else if (incKeyCount >= keyCountTrig && digitalRead(IncKey) == HIGH) {
        KeyCode = IncKeyCode;
    } else if (decKeyCount >= keyCountTrig && digitalRead(DecKey) == HIGH) {
        KeyCode = DecKeyCode;
    }else if (selectKeyCount >= keyCountTrig && digitalRead(SelectKey) == HIGH) {
        KeyCode = SelectKeyCode;
    } else { }                                                                          //Do nothing here for now (keyCodes are cleared after GetKeyCode issues them)

    // Check each key one by one and count how many times it was on (LOW)

    //------------------------------------------------------
    if (digitalRead(NextKey) == LOW) {                                      //Next Key Pressed?

        nextKeyCount++;
    } else {nextKeyCount = 0; }                                             //Reset Count

   //------------------------------------------------------
    if (digitalRead(BeforeKey  ) == LOW) {                                  //Before Key Pressed?

       beforeKeyCount++;
    } else {beforeKeyCount = 0; }                                           //Reset Count

   //------------------------------------------------------
    if (digitalRead(IncKey  ) == LOW) {                                     //Inc Key Pressed?

       incKeyCount++;
    } else {incKeyCount = 0; }                                              //Reset Count

   //------------------------------------------------------
    if (digitalRead(DecKey  ) == LOW) {                                     //Dec Key Pressed?

       decKeyCount++;
    } else {decKeyCount = 0; }                                              //Reset Count 

   //------------------------------------------------------
    if (digitalRead(SelectKey  ) == LOW) {                                  //Before Key Pressed?

      selectKeyCount++;
    } else {selectKeyCount = 0;}                                             //Reset Count 
}


//---------------------------------------------------------------------------------------------
//This guy returns key codes to a calling routine. It functions as a latch to get a key code
//and hold it till it's requested (The keyboard 10ms interrupt only sets codes not clears them)
//Only clear KeyCode in the event we actually had a code to pass back (otherwise 0 gets sent back)

int GetKeyCode (){

    int thisKey = KeyCode;                              //Grab the current code

    if (thisKey !=0){

        KeyCode = 0;                                    //Clear the code
    }
    return thisKey;                                     //return with the KeyCode we grabbed

}



The program fails because it runs out of dynamic memory.

As mentioned, the TFT, and all of these strings take up dynamic memory, too.

const char* Lim_Scl_Menu_Items[Lim_Scl_Num_Items] =  {"Trig. Level:",
                                                      "Scale :",
                                                      "Zero Mode",
                                                      "Exit "};

Take a view here for using the datatype String:

Agreed, get rid of all the Strings. They are never necessary.

Adding one character causes the compiler to slightly rearrange where various data is stored in memory. The new arrangement put something critical in a location that is being overwritten by the display buffer, while previously whatever was being overwritten was not as noticeable. You get the same type behavior when exceeding the bounds of an array, a seemingly completely unrelated change of the code will fix/break the code.

Got it! In order to prevent this I would need a dis-assembler to see where things are being placed...is there one compatible with this IDE (specifically 2.1.0) ?

Thanks again!

Wow...Thanks!!

Got it! In order to prevent this I would need a dis-assembler to see where things are being placed...is there one compatible with this IDE (specifically 2.1.0) ?

Thanks again!

:scream:
:slight_smile:

What you need to do is make sure you have sufficient ram for your sketch. Knowing what is being overwritten doesn’t help, something will still get corrupted and the code will not work properly.

Hi David,

Thanks for that info! I'm not sure how to do that without the aid of a dis-assembler of some sort since I have been told that the problem is the OLED Display uses 1K of SRAM that isn't reported by the stats when assembling the code...

Thanks again!

A disassembler will not show the memory used by the display buffer, that is allocated at run-time.

Since that's obviously problematic how can you tell when you are about to start having problems?

The OLED display is going to get 1K of SRAM which still would have left several hundred bytes available for my use but the program was failing to launch under those conditions.

So my question is how can I account for the memory actually available?

Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.