Создание большого массива. Вопрос.

Тема в разделе "Arduino & Shields", создана пользователем owe, 24 окт 2015.

  1. owe

    owe Нуб

    Всех приветствую! Столкнулся с проблемой создания массива, собственно необходимо 512 переменных массива ( myInts[512] ). Заливаю скетч, ардуинка подвисает. Делаем немножко по другому. Если разбить myInts по 100, myInts1[100]..myInts5[100], скетч заливается ардуинка НЕ подвисает, но! Если начать вписывать в массив данные, myInts1[100] и myInts2[100] - полёт нормальный, они туда вписываются. Когда добавляешь myInts3[100] - ардуинка виснет.
    Вопрос: Аруинка не тянет по RAM больше 200 переменных? Как решить проблему?
    arduino uno 328P-PU
    Код (C++):
    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #define OLED_RESET 4
    Adafruit_SSD1306 display(OLED_RESET);

    //int sensorPin1 = A2;
    int sensorPin1 = A1;
    //int sensorPin2 = A1;
    int sensorPin2 = A2;
    //int sensorPin3 = A0;
    int sensorPin0 = A0;

    int ii=0;

    int myInts1[100];
    int myInts2[100];
    int myInts3[100];
    int myInts4[100];
    int myInts5[100];
    int myInts6[12];



    void setup()   {            

      Serial.begin(9600);
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
      display.display();
      delay(2000);
      display.clearDisplay();
              for ( ii=1; ii <= 300; ii++){
              if (ii < 100) {
                myInts1[ii] = 1;
             Serial.print("myInts1 ");
             Serial.print(ii);
             Serial.print(", ");
          //  continue;
              }  if (ii < 200) {
                int zz = ii - 100;
                myInts2[zz] = 2;
             Serial.print("myInts2 ");
             Serial.print(zz);
             Serial.print(", ");
         //   continue;
              }/* if (ii < 300) {
                int zz = ii - 199;
                myInts3[zz] = 3;
                                Serial.print("myInts3");
             Serial.print(zz);
            Serial.print(", ");
             continue;
              }/* else if (ii < 401) {
                myInts4[ii-300] = ii;
                                Serial.print("myInts");
             Serial.print(ii);
            Serial.print(", ");
              } else if (ii < 501) {
                myInts5[ii-400] = ii;
                                Serial.print("myInts");
             Serial.print(ii);
            Serial.print(", ");
              } else if (ii < 513) {
                myInts5[ii] = ii;
                                Serial.print("myInts");
             Serial.print(ii);
            Serial.print(", ");
              }
           
           
           
              /* else if (ii < 201) {
                Serial.print("lll");
             // break;
              }*/





        //  myInts0[ii] = ii;
            }
      //myInts

    /*
    for ( ii=0; ii < 200; ii++){
      if (ii <=100) {
      display.clearDisplay();
      display.setTextSize(0);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.print(myInts0[ii]);
      display.setCursor(20,0);
      display.print(myInts0[ii+1]);
      display.setCursor(40,0);
      display.print(myInts0[ii+2]);
      display.setCursor(60,0);
      display.print(myInts0[ii+3]);
      display.setCursor(80,0);
      display.print(myInts0[ii+4]);
      display.setCursor(100,0);
      display.print(myInts0[ii+5]);
    //  display.display();
            }
    }
    */

    }

    void loop() {
    // delay(100000);
    }
     
     
    Последнее редактирование: 24 окт 2015
  2. AlexVS

    AlexVS Гик

    Ардуинка тянет столько переменных, сколько влезет в ОЗУ, с учетом растущего вниз стека. Поэтому, если например взять под ваш скетч Мегу, то вполне возможно виснуть не будет, а вот Уно или Про Мини - маловат размер ОЗУ.
    Не вдаваясь в подробности вашей программки можно посоветовать хранить переменные во флеш-памяти, используя для этого макрос PROGMEM, если массивы статичны и инициализируются в коде программы, если же они заполняются по мере работы - сходу не знаю что посоветовать, может EPROM.
     
  3. geher

    geher Гуру

    EPROM тоже маловат.
    Можно использовать внешний носитель (SD карту, какую нибудь другую память, управляемую по SPI).
    Но лучше, наверное использовать МК (или ардуину с соответствующим МК), возможности которого более соответствуют требованиям программы, ибо внешний носитель в любом случае будет медленнее ОЗУ.
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    А что именно вы хотите хранить в этих переменных?
     
  5. Onkel

    Onkel Гуру

    с большими массивами надо аккуратно. У меня даже в суровых компиляторах бывало, что когда размер массива выбираешь под завязку мк начинает глючить.
     
  6. owe

    owe Нуб

    Числа, значения снятые с потенциометров ( map(sensorValue0, 0 , 1024, 0, 128); )
     
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Вы никогда с аналогового входа не получите значение 1024, там разрядность 10 бит, от 0 до 1023. Соответственно, имеет смысл переводить показания в диапазон 0..127, а не 0..128. Это проще всего сделать так: value / 8.
    И нет никакого смысла использовать для массива int (2 байта), используйте byte (1 байт) - после деления у вас остается 7 бит, которые в байт замечательно помещаются. А используя int, вы выделяете вдвое больше памяти, чем нужно, и никак ее не используете.
     
  8. geher

    geher Гуру

    value >> 3

    И переход на байты не решит данную проблему.
    Вместо 200 элементов получится хранить 400, а надо 512.
    Так что придется или кардинально перерабатывать алгоритм, чтобы избавиться от необходимости одновременного хранения всех данных, если возможно, или переходить на внешнее устройство хранения.
    Можно и EPROM, его даже с int хватало впритык (1 кбайт, 512 целых).
    Но есть две проблемы.
    1. С целочисленными данными теряется возможность расширения. Т.е. если потребуется хранить не 512, а хотя бы на одну больше, то уже не влезет
    2. Небольшой ресурс чтения/записи. Быстро умрет, даже если перейти на байты.
     
    Последнее редактирование: 25 окт 2015
  9. Megakoteyka

    Megakoteyka Оракул Модератор

    Значит нужно нарыть еще 112 байт. Наверняка библиотеки все сожрали. При желании можно переписать код и наверняка все влезет.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    А вам действительно нужно хранить 512 значений с потенциометров? Может, можно их сразу обрабатывать и тогда массив не понадобится? Расскажите о своей задаче, в чем там суть?
     
  11. Onkel

    Onkel Гуру

    у меня в одном проекте на 328 атмеге массив 256 целых, на atmega8 массив 256 char не проблема. 512 не пробовал, но ацп дает 10 бит - это почти 8 бит.
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Библиотеки тоже вносят свой вклад в расход оперативки и иногда очень весомый.
    Вот тут совсем не понял, что вы имели в виду.
     
  13. Onkel

    Onkel Гуру

    нужно ли тс именно 10 бит? Может сделать массив 8 битных данных, забив на мл. 2 бита АЦП?.
    С библиотеками возможно - я обычно на 8-битной мелочи (да что там обычно, всегда) пишу только своим кодом, без сторонних библиотек. Мой код весомого вклада не вносит.
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

     
  15. Onkel

    Onkel Гуру

    а зачем 7 бит, когда можно 8 бит unsigned char?
     
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Ну значит нужно человеку 7 бит, а не 8. Например, график рисовать на дисплее, у которого 128 точек по вертикали. Храниться это все равно будет в чарах.
     
  17. DrProg

    DrProg Вечный нерд

    А разбить на несколько массивов никак?
     
    ИгорьК нравится это.
  18. Onkel

    Onkel Гуру

    так без толку будет, ясен пень.
     
  19. DrProg

    DrProg Вечный нерд

    Поясните, мне пень не ясен,
     
    ИгорьК нравится это.
  20. Onkel

    Onkel Гуру

    массив из 500 целых занимает ровно столько же места, сколько 5 массивов по 100 целых. Разве нет?
    к тому же тс в самом первом посте отмечал, что он уже проверял таким образом аддитивность операции сложения.
     
    Tomasina нравится это.