user50301: I am making a simple calculator with Arduino Uno R3. It only has +, -, x and /.
I use 3 libraries:

This use for LCD with I2C module. Arduino-LiquidCrystal-I2C-library
This use for keypad 4x4. Chris--A/Keypad
And this: jamesgregson/expression_parser

My code:
#include "expression_parser.h"
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x3F, 16, 2);

const byte ROWS = 4; 
const byte COLS = 4; 

char keys[ROWS][COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'.', '0', '=', '/'}
};

byte rowPins[ROWS] = {10, 9, 8, 7}; 
byte colPins[COLS] = {6, 5, 4, 3}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

String s = "";  
char ex[16];

void setup() {
  Serial.begin(9600);
  lcd.init();          
  lcd.backlight();      
  lcd.setCursor(0, 0);  
}

int cur = 0;
bool enter = false;

void loop() 
{
  char key = keypad.getKey();   

  if ((key != '=') && (key != NO_KEY) ) {
    if (!enter) {               
      Serial.println(F("key"));
      if(key=='/')
        lcd.print(F("':'"));
      else 
      if (key=='*')
        lcd.print(F("'x'"));
      else
        lcd.print(F("key"));
      s = s + key;              
      cur++;                    
      lcd.setCursor(cur, 0);    
    } else {                    

      lcd.setCursor(0, 0);      
      lcd.print("");
      enter = false;
      lcd.setCursor(0, 0);
      cur = 0;
      lcd.print(F("key"));
      s = "";
      s = s + key;
      cur++;
      lcd.setCursor(cur, 0);
    }
  } else if (key == '=') {    
    enter = true;

    if ((s[0] == '=') || (s[0] == '/') || (s[0] == '*') || (s[0] == '.')) {
      lcd.setCursor(0, 1);
      lcd.print("Error");
    } else {
      lcd.setCursor(0, 1);
      lcd.print("");
      s.toCharArray(ex, 16);
      Serial.println(F("s"));
      int re = parse_expression(ex); 
      String check = String(re);
      if (check.length() > 15) {
        lcd.setCursor(0, 1);
        lcd.print("Overflow");
      } else {
        Serial.println(re);
        lcd.setCursor(0, 1);
        lcd.print("=");
        lcd.print(F("re"));                
      }
    }
  }
}

I ran it and got error:
Global variables use 3302 bytes (161%) of dynamic memory, leaving -1254 bytes for local variables. Maximum is 2048 bytes.
Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
Error compiling for board Arduino/Genuino Uno.
So what should I do? 

user31105: Your own declared global variables do not use up much space.
Watch out for using string, this can be extended during the flow of the program thus using more.
The problem is in the libraries. 
What you can do:

Leave out the include and related code per library to see which is using up a lot of global space.
When you find out which causes problems, try to follow the internals of the library to see if there is some buffered memory that you can decrease.

If not, I'm afraid the only solution is to move to an Arduino with more memory (like the Arduino Mega which has 8 KB).
With the use of PROGMEM you can save some space on
char keys[ROWS][COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'.', '0', '=', '/'}
};

byte rowPins[ROWS] = {10, 9, 8, 7}; 
byte colPins[COLS] = {6, 5, 4, 3}; 

Because it will be placed in Flash instead of SRAM, but it will save you just 24 bytes.

50301: <p>I am making a simple calculator with Arduino Uno R3. It only has +, -, x and /.</p>

<p>I use 3 libraries:</p>

<ol>
<li>This use for LCD with I2C module. <a href="https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library" rel="nofollow noreferrer">Arduino-LiquidCrystal-I2C-library</a></li>
<li>This use for keypad 4x4. <a href="https://github.com/Chris--A/Keypad" rel="nofollow noreferrer">Chris--A/Keypad</a></li>
<li>And this: <a href="https://github.com/jamesgregson/expression_parser" rel="nofollow noreferrer">jamesgregson/expression_parser</a></li>
</ol>

<p>My code:</p>

<pre><code>#include "expression_parser.h"
#include &lt;Keypad.h&gt;
#include &lt;Wire.h&gt;
#include &lt;LiquidCrystal_I2C.h&gt;


LiquidCrystal_I2C lcd(0x3F, 16, 2);

const byte ROWS = 4; 
const byte COLS = 4; 

char keys[ROWS][COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'.', '0', '=', '/'}
};

byte rowPins[ROWS] = {10, 9, 8, 7}; 
byte colPins[COLS] = {6, 5, 4, 3}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

String s = "";  
char ex[16];

void setup() {
  Serial.begin(9600);
  lcd.init();          
  lcd.backlight();      
  lcd.setCursor(0, 0);  
}

int cur = 0;
bool enter = false;

void loop() 
{
  char key = keypad.getKey();   

  if ((key != '=') &amp;&amp; (key != NO_KEY) ) {
    if (!enter) {               
      Serial.println(F("key"));
      if(key=='/')
        lcd.print(F("':'"));
      else 
      if (key=='*')
        lcd.print(F("'x'"));
      else
        lcd.print(F("key"));
      s = s + key;              
      cur++;                    
      lcd.setCursor(cur, 0);    
    } else {                    

      lcd.setCursor(0, 0);      
      lcd.print("");
      enter = false;
      lcd.setCursor(0, 0);
      cur = 0;
      lcd.print(F("key"));
      s = "";
      s = s + key;
      cur++;
      lcd.setCursor(cur, 0);
    }
  } else if (key == '=') {    
    enter = true;

    if ((s[0] == '=') || (s[0] == '/') || (s[0] == '*') || (s[0] == '.')) {
      lcd.setCursor(0, 1);
      lcd.print("Error");
    } else {
      lcd.setCursor(0, 1);
      lcd.print("");
      s.toCharArray(ex, 16);
      Serial.println(F("s"));
      int re = parse_expression(ex); 
      String check = String(re);
      if (check.length() &gt; 15) {
        lcd.setCursor(0, 1);
        lcd.print("Overflow");
      } else {
        Serial.println(re);
        lcd.setCursor(0, 1);
        lcd.print("=");
        lcd.print(F("re"));                
      }
    }
  }
}
</code></pre>

<p>I ran it and got error:</p>

<p>Global variables use 3302 bytes (161%) of dynamic memory, leaving -1254 bytes for local variables. Maximum is 2048 bytes.
Not enough memory; see <a href="http://www.arduino.cc/en/Guide/Troubleshooting#size" rel="nofollow noreferrer">http://www.arduino.cc/en/Guide/Troubleshooting#size</a> for tips on reducing your footprint.
Error compiling for board Arduino/Genuino Uno.</p>

<p>So what should I do? </p>
 31105: <p>Your own declared global variables do not use up much space.</p>

<p>Watch out for using string, this can be extended during the flow of the program thus using more.</p>

<p>The problem is in the libraries. </p>

<p>What you can do:</p>

<ul>
<li>Leave out the include and related code per library to see which is using up a lot of global space.</li>
<li>When you find out which causes problems, try to follow the internals of the library to see if there is some buffered memory that you can decrease.</li>
</ul>

<p>If not, I'm afraid the only solution is to move to an Arduino with more memory (like the Arduino Mega which has 8 KB).</p>

<p>With the use of PROGMEM you can save some space on</p>

<pre><code>char keys[ROWS][COLS] = {
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'.', '0', '=', '/'}
};

byte rowPins[ROWS] = {10, 9, 8, 7}; 
byte colPins[COLS] = {6, 5, 4, 3}; 
</code></pre>

<p>Because it will be placed in Flash instead of SRAM, but it will save you just 24 bytes.</p>
