4

I'm a dairy farmer and I'm new to playing around with Arduino's. I created a code to send me SMS's when my equipment stops working as it should, but I run into a "Not enough memory" error. Here's my code:

#include <OneSheeld.h> 
int IPFeed = 13;                
int IPScraper = 12;             
int IPPump = 11;                 
int XVal = 0;           
int TFeedCharge = 0;
int TFeedRun = 0;
int TScraper = 0;
int TPump = 0;  
int TLFeedCharge = 60;         
int TLFeedRun = 60;           
int TLManure = 2;                               
int TInc = 60000;               
          
void setup() {
  pinMode(IPFeed, INPUT);     
  pinMode(IPScraper, INPUT);  
  pinMode(IPPump, INPUT);   
  OneSheeld.begin(); 
}

void loop() {
  XVal = digitalRead(IPFeed); 
  if (XVal == HIGH) {            
    TFeedRun = 0;
    TFeedCharge = TFeedCharge +1;
    if (TFeedCharge == TLFeedCharge) {
      delay(150);
      SMS.send("613xxxxxx6","ProFeed 2020 is stoped at the charging station.");
      delay(150);
      SMS.send("613xxxxxx9","ProFeed 2020 is stoped at the charging station.");
      TFeedCharge = 0;                     
    } 
  }
  else {
    TFeedCharge = 0;
    TFeedRun = TFeedRun +1;
    if (TFeedRun == TLFeedRun) {
      delay(150);
      SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");
      delay(150);
      SMS.send("613xxxxxx9","ProFeed 2020 is stopped away from the charging station.");
      TFeedRun = 0;                    
    }
  }
        
  XVal = digitalRead(IPScraper); 
  if (XVal == HIGH) {            
    TScraper = TScraper +1;
    if (TScraper == TLManure) {
      delay(150);
      SMS.send("613xxxxxx6","The manure scraper has stopped working.");
      delay(150);
      SMS.send("613xxxxxx9","The manure scraper has stopped working.");
      TScraper = 0;                     
    } 
  }    
    
  XVal = digitalRead(IPPump);  
  if (XVal == HIGH) {            
    TPump = TPump +1;
    if (TPump == TLManure) {
      delay(150);
      SMS.send("613xxxxxx6","The manure pump has stopped working.");
      delay(150);
      SMS.send("613xxxxxx9","The manure pump has stopped working.");
      TPump = 0;                     
    } 
  }    

  delay(TInc);
}

Here is the error message:

Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P"

Sketch uses 24812 bytes (80%) of program storage space. Maximum is 30720 bytes.

Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.

Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint.

data section exceeds available space in board

Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Any ideas on how to fix this issue?

New contributor
FarmerChuck is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
3
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Majenko
    2 days ago
  • tip: TFeedCharge++; is cleaner than TFeedCharge = TFeedCharge +1;
    – jsotola
    2 days ago
  • minor tip: use const int for pin number settings to make it clear to others (or future you) that the numbers are constants (const prevents the code from modifying the value of the variable)
    – Victor Liu
    2 days ago

2 Answers 2

5

Including the whole library, which is what you are doing, does not work on small boards like yours. Instead you have to only use the parts of the library that you need.

Fortunately the OneSheeld library provides a simple way of doing that, through the use of a couple of #define directives before you include the library.

Since you are only using the SMS functionality you only need to turn on that functionality - so start your sketch with:

#define CUSTOM_SETTINGS
#define INCLUDE_SMS_SHIELD

before the #include <OneSheeld.h> line and it will compile.

2

Your problem is caused by using too much RAM, not program memory, as the error message says:

Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.

The library you are using is likely occupying a large amount of RAM. However, currently your alert messages are stored in RAM as well, causing the limit to be exceeded. To make the compiler store the strings in program memory (flash) instead of RAM, you can wrap each string in an F() macro. For example,

SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");

becomes

SMS.send("613xxxxxx6",F("ProFeed 2020 is stopped away from the charging station."));

(You can also wrap the phone number to save even more RAM, but as the limit has only been exceeded by 39 bytes/characters it is unnecessary.)

Majenko's answer might potentially work too as the excluded parts of the library might happen to save just enough RAM, but the F() technique is still handy.

2
  • sms.send function doesn't accept a flash string. so it uses the version with String and creates a temporary String
    – Juraj
    yesterday
  • 1
    Interesting. That makes removing includes the only solution.
    – Victor Liu
    yesterday

Your Answer

FarmerChuck is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.