Недостаточно памяти при использовании OneSheeld.h

memory error

Я фермер, занимающийся молочной фермой, и я новичок в использовании Arduino. Я создал код для отправки мне SMS, когда мое оборудование перестает работать должным образом, но я сталкиваюсь с "Недостаточно памяти" ошибка. Вот мой код:

#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);
}

Вот сообщение об ошибке:

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 советы по уменьшению занимаемой площади.

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.

Есть идеи, как решить эту проблему?

, 👍5

Обсуждение

Комментарии не для расширенного обсуждения; этот разговор был [перемещен в чат] (https://chat.stackexchange.com/rooms/138330/discussion-on-question-by-farmerchuck-not-enough-memory-error)., @Majenko


2 ответа


6

Включение всей библиотеки, что вы и делаете, не работает на таких маленьких платах, как ваша. Вместо этого вы должны использовать только те части библиотеки, которые вам нужны.

К счастью, библиотека OneSheeld предоставляет простой способ сделать это с помощью пары директив #define перед подключением библиотеки.

Поскольку вы используете только функцию SMS, вам нужно только включить эту функцию, поэтому начните свой скетч с:

#define CUSTOM_SETTINGS
#define INCLUDE_SMS_SHIELD

перед строкой #include <OneSheeld.h>, и он будет скомпилирован.

,

3

Ваша проблема вызвана использованием слишком большого объема ОЗУ, а не программной памяти, как указано в сообщении об ошибке:

Глобальные переменные используют 2087 байт (101%) динамической памяти, оставляя -39 байт для локальных переменных. Максимум 2048 байт.

Используемая вами библиотека, вероятно, занимает большой объем оперативной памяти. Однако в настоящее время ваши предупреждающие сообщения также хранятся в оперативной памяти, что приводит к превышению лимита. Чтобы компилятор сохранял строки в памяти программ (флеш-память) вместо оперативной памяти, вы можете обернуть каждую строку в макрос F(). Например,

SMS.send("613xxxxxx6", "ProFeed 2020 остановился вдали от зарядной станции.");

становится

SMS.send("613xxxxxx6",F("ProFeed 2020 остановился вдали от зарядной станции."));

(Вы также можете обернуть номер телефона, чтобы сэкономить еще больше оперативной памяти, но, поскольку ограничение было превышено только на 39 байт/символов, в этом нет необходимости.)

Ответ Маженко потенциально может сработать, так как исключенные части библиотеки могут сэкономить достаточно оперативной памяти, но метод F() по-прежнему удобен.

,

Функция sms.send не принимает флэш-строку. поэтому он использует версию со строкой и создает временную строку, @Juraj

Интересно. Это делает удаление включает в себя единственное решение., @Victor Liu