Недостаточно памяти
Я делаю простой калькулятор на Arduino Uno R3. Здесь есть только +, -, x и /.
Я использую 3 библиотеки:
- Это использование для ЖК-дисплея с модулем I2C. Arduino-LiquidCrystal-I2C-library
- Это использование для клавиатуры 4x4. Chris--A/Keypad
- А это: jamesgregson/expression_parser
Мой код:
#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"));
}
}
}
}
Я запустил его и получил ошибку:
Глобальные переменные используют 3302 байта (161%) динамической памяти, а для локальных переменных остается -1254 байта. Максимум — 2048 байт. Недостаточно памяти; см. http://www.arduino.cc/en/Guide/Troubleshooting#size для получения советов по уменьшению твой след. Ошибка компиляции для платы Arduino/Genuino Uno.
И что мне делать?
@Thành Đỗ, 👍3
Обсуждение2 ответа
Ваши собственные объявленные глобальные переменные не занимают много места.
Остерегайтесь использования строки: ее можно расширять в ходе выполнения программы, таким образом используя больше.
Проблема в библиотеках.
Что вы можете сделать:
- Оставьте включаемый и связанный код для каждой библиотеки, чтобы увидеть, какая из них занимает много глобального пространства.
- Когда вы выясните, что вызывает проблемы, попробуйте проследить за внутренним устройством библиотеки, чтобы увидеть, есть ли какая-то буферизованная память, которую вы можете уменьшить.
Если нет, то, боюсь, единственное решение — перейти на Arduino с большим объемом памяти (например, Arduino Mega с 8 КБ).
С помощью PROGMEM вы сможете сэкономить место
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};
Поскольку он будет размещен во Flash, а не в SRAM, но это сэкономит вам всего 24 байта.
При беглом взгляде на эти библиотеки мне кажется, что парсер выражений потребляет _намного_ больше оперативной памяти, чем два других. Он содержит множество сообщений об ошибках и код для работы с трансцендентными функциями: вещи, которые ОП не использует., @Edgar Bonet
Перейдите на плату на базе '1284P. Они имеют 16 КБ SRAM и еще 12 контактов ввода-вывода, что даст вам достаточно места для добавления и расширения дополнительных функций позже.
Я предлагаю платы 1284P в нескольких форм-факторах на сайте www.crossroadsfencing.com/BobuinoRev17/
Его легко добавить в IDE с помощью MegaCore от MCUdude. https://github.com/MCUdude/MegaCore
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
анализатор выражений использует много оперативной памяти, избавьтесь от него. Вы выполняете всего 4 основные операции, поэтому все, что вам нужно сделать, это небольшой набор операторов IF и проанализировать сами числа, что Arduino может сделать без большой библиотеки., @dandavis
Самая эффективная система, которую вы можете использовать, называется «[Обратная польская нотация](https://en.wikipedia.org/wiki/Reverse_Polish_notation)» или *RPN*. Это система на основе стека, и она может очень эффективно работать в системах с очень небольшим объемом памяти. Просто надо привыкнуть правильно вводить уравнения..., @Majenko
какую плату Arduino вы используете?, @Rohit Singh