Всем привет! Создаю статичный трёхмерный массив в Arduino IDE: Код (Text): byte angel[28][3][80] = { /*здесь куча цифр*/}; . Для проверки работоспособности кидаю числа из массива в Serial-порт, а там пусто. Беру массив поменьше размером: Код (Text): byte a[3][2][3]={/*заполняем числами*/} . Во втором массиве, все числа прекрасно выводятся в порт. Числа в массивах из диапазона (0-180). Размер загруженного счетча около 10кб. Заливаю в Arduino UNO. Не могу поверить что проблема из-за больших размеров первого массива. Мне очень нужен первый массив, в чём проблема, почему он не показывает свои значения? Может кто в курсе?
Mihej, а вы не забыли, что у ATmega328 всего 2Кб оперативной памяти (SRAM)? Вы пытаетесь в ней разместить массив размером в 28*3*30=6720=6.5625Кб т.е. более, чем в три раза, больше доступной памяти.
Пихайте массив в программную память. См. PROGMEM. Unixon, а почему компилятор это проглотил? Это же статический массив, вроде должен был ругнуться... или нет?
Вот мой код: Код (Text): byte a[3][2][3]={ { {1,2,3}, {3,2,1}, }, { {4,5,6}, {6,5,4}, }, { {7,8,9}, {9,8,7}, } }; byte angel[28][3][80] = { //Этот массив огромный, писать не буду }; void setup() { Serial.begin(9600); } void loop() { Serial.println(angel[0][0][0]); //Пытаемся отправить любое число из массива delay(500); }
То есть получаеться, что мне лучше разбить исходный массив на 28 двумерных массивов, а потом сделать массив указателей на двумерные массивы? Тогда в оперативку будет подгружаться только определённый двумерный массив?
Дело в том что компилятор при объявлении переменной выделает под нее память, даже если вы там ничего не вводите. Это примерно как склад скажем на 100м/куб .... вы отправляете заявку (объявляете переменную) на то что вам нужно место под 25 м/куб которые вы ВОЗМОЖНО туда сложите, то есть склад резервируется, но это не значит что вы реально привезете туда груз и заполните. Таким образом размер склада для других уже будет лишь 75 м/куб так как 25 вы зарезервировали. Хотя по факту место пустует но заведующий склада считает это место занятым и не важно есть там груз или нет Таким образом объявляя массив вы пытаетесь зарезервировать места больше чем может вам быть предоставлено.
Вроде заработало во так: Код (Text): #define __PROG_TYPES_COMPAT__ #include <avr/pgmspace.h> prog_uchar angel[28][3][80] PROGMEM = {/*Куча цифр*/}; void setup() { Serial.begin(9600); } void loop() { Serial.println(prog_int16_t(angel[1][0][0])); //Кидаем какое нибудь число из массива delay(500); } Всем большое спасибо за ответы, если бы не PROGMEM - тупил бы я ещё долго
В том то и дело, что там набор углов поворота 3-х сервоприводов, которые задают движение механической руки (вперёд, вверх), так чтобы клешня всегда была параллельно поверхности стола.
Блин, теперь такой бред, делаю в цикле: Код (Text): for(int i=0; i< 80; i++) { Serial.println(prog_int16_t(angel[0][0][i])); delay(100); } В порт выдаются левые числа, а если явно задаю, то всё нормально: Код (Text): Serial.println(prog_int16_t(angel[0][0][2])); В чём проблема?
pgm_read_... сделать не забыли? Просто так обращаться в память программ нельзя, нужно прочитать оттуда данные при помощи соответствующей (конкретному типу данных) функции. Тогда в памяти программ будет храниться большой массив, а при необходимости его использовать каждый его элемент должен быть сперва прочитан в переменную, находящуюся в памяти данных. И вот ее уже можно использовать. http://arduino.cc/en/Reference/PROGMEM А еще можно рассмотреть вариант подключения SD-карты и хранения данных на ней. Или внешней EEPROM.
Ура! Вроде работает теперь: Код (Text): #define __PROG_TYPES_COMPAT__ #include <avr/pgmspace.h> prog_uchar angel[28][3][80] PROGMEM = {/*Куча цифр*/}; void setup() { Serial.begin(9600); } void loop() { for(int i=0; i< 80; i++) { Serial.println(pgm_read_byte(&angel[0][0][i])); //Кидаем числа из массива в цикле delay(500); } }