Объем памяти в большинстве компьютеров исчисляется гигабайтами, но в Arduino Uno ее всего 2 Кбайт. То есть более чем в миллион раз меньше, чем в обычном компьютере. Однако ограниченный объем памяти удивительным образом способствует концентрации мысли в процессе программирования. Здесь нет места для расточительства, которым страдает большинство компьютеров.
Писать эффективный код, конечно, важно, но необязательно делать это за счет усложнения чтения и сопровождения. Даже при таких ограниченных ресурсах, как в Arduino, большинство скетчей оказываются далеки от использования всего объема оперативного запоминающего устройства (ОЗУ). Беспокоиться о нехватке памяти приходится, только когда создается действительно очень сложный скетч, использующий массу данных.
Память в Arduino
Сравнивать объем памяти в Arduino и в обычных компьютерах не совсем корректно, так как в них память ОЗУ используется для разных целей. На рис. 6.1 показано, как используется память в компьютере, когда запускается программа.
Когда компьютер запускает программу, он сначала копирует ее целиком с жесткого диска в ОЗУ, а затем запускает эту копию. Переменные в программе занимают дополнительный объем ОЗУ. Для сравнения на рис. 6.2 показано, как используется память в Arduino, когда запускается программа. Сама программа действует, находясь во флеш-памяти. Она не копируется в ОЗУ.

Рис. 6.1.Как используется память в компьютере

Рис. 6.2.Как используется память в Arduino
ОЗУ в Arduino используется только для хранения переменных и других данных, имеющих отношение к выполняющейся программе. ОЗУ является энергозависимой памятью, то есть после отключения питания оно очищается. Чтобы сохранить данные надолго, программа должна записать их в ЭСППЗУ. После этого скетч сможет считать данные в момент повторного запуска.
При приближении к границам возможностей Arduino придется позаботиться о рациональном использовании ОЗУ и, в меньшей степени, о размере программы внутри флеш-памяти. Так как в Arduino Uno имеется 32 Кбайт флеш-памяти, этот предел достигается нечасто.
Уменьшение используемого объема ОЗУ
Как вы уже видели, чтобы уменьшить используемый объем ОЗУ, следует уменьшить объем памяти, занимаемой переменными.
Используйте правильные структуры данных
Самым широко используемым типом данных в Arduino C, бесспорно, является тип int. Каждая переменная типа int занимает 2 байта, но часто такие переменные используются для представления чисел из намного более узкого диапазона, чем –32 768…+32 767, и нередко типа byte с его диапазоном 0…255 для них оказывается вполне достаточно. Большинство встроенных методов, принимающих аргументы типа int, с таким же успехом могут принимать однобайтовые аргументы.
Типичным примером могут служить переменные с номерами контактов. Они часто объявляются с типом int, как показано в следующем примере:
// sketch_06_01_int
int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
void setup()
{
for (int i = 0; i < 12; i++)
{
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], HIGH);
}
}
void loop()
{
}
Массив типа int без всяких последствий можно преобразовать в массив байтов. В этом случае функции в программе будут выполняться с той же скоростью, зато массив будет занимать в два раза меньше памяти.
По-настоящему отличный способ экономии ОЗУ — объявление неизменяемых переменных константами. Для этого достаточно добавить слово const в начало объявления переменной. Зная, что значение никогда не изменится, компилятор сможет подставлять значение переменной в местах обращения к ней и тем самым экономить ОЗУ. Например, массив из предыдущего примера можно объявить так:
const byte ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
Не злоупотребляйте рекурсией
Рекурсией называется вызов функцией самой себя. Рекурсия может быть мощным инструментом выражения и решения задач. В языках функционального программирования, таких как LISP и Scheme, рекурсия используется чуть ли не повсеместно.
Когда происходит вызов функции, в области памяти, называемой стеком , выделяется фрагмент. Представьте подпружиненный дозатор для леденцов, например Pez™, но позволяющий вталкивать леденцы и выталкивать их сверху (рис. 6.3). Под термином «вталкивать» понимается добавление чего-то на стек, а под термином «выталкивать» — извлечение со стека.
Читать дальше