Arduino UNO: reducing memory by placing array in function?

Thread Starter

Terrypin

Joined Feb 5, 2016
113
(Intended to post this in Arduino forum, but site seems to be down today.)

I'm trying to reduce my UNO program's memory requirement, in order to use a large array. On the page
https://support.arduino.cc/hc/en-us/articles/360013825179
I read this:

"Declare variables as locally as possible to save memory:

* Anything declared at global scope will exist for the entire lifetime of the sketch.
* Variables that are only used inside one function, can be declared within that function."

Have I understood that last point correctly? I moved the array declaration from global to a function 'void shuffleRawArray()' but storage remained at the same level.

Code:
void shuffleRawArray()
{
int rawArray[500] // 500 elements
{
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500
};
 
  for (int i = 0; i < 1651; i++)
  {
    int pos = random(500);
    int t = rawArray[i];
    rawArray[i] = rawArray[pos];
    rawArray[pos] = t;
  }
  // Print for debugging after randomising
  Serial.println();
  Serial.print(F("Printing check of rawArray "));
  for (int i = 0; i < 500; i++)
  {
    Serial.print(F("rawArray["));
    Serial.print(i);
    Serial.print(F("] = "));
    Serial.println(rawArray[i]);
  }
  delay(10);
  i = 0;
}
 

Papabravo

Joined Feb 24, 2006
21,264
You have to understand how storage is allocated for various things. What you have declared is an array of constants. I'm not an expert on the Arduino IDE, but I can see that there are a number of alternatives for how to allocate memory for the purpose of this array. In point of fact there is no viable way of having an array of constants come into being when the function is called and then obliterated when the function returns.

The quote from your original post referred to VARIABLES. Do I really need to point out that there is a huge difference between constants and variables?
 

Papabravo

Joined Feb 24, 2006
21,264
The use of a constant array may have just been an example. If it was going to be variables, they would be allocated on the stack. Whether this would be a good idea or not depends on how they would be used. I'm not aware of any processor where an array of that size on the stack could be a demonstrated advantage for either speed or space optimization. Something of that size would normally come from the heap and be referenced by a base pointer and an offset. Again, I'm no expert on the Arduino IDE so there may be some method to this particular advice.
 

Thread Starter

Terrypin

Joined Feb 5, 2016
113
Thanks both. I did take a brief look at Progmem before posting, but it looks heavy going. I'm an 'Arduino prgrammer' with no C/C++ training or expertience.

Reckon I'll have to approach this part of my JukBox project in a radically diffrent manner. The background in brief: using the DFR Mini MP3 Player module and its DFRobotDFPlayerMini.h library. One of its functions is randomAll(). While that does indeed play my 2,600 tracks randomly, it has a flaw in not preventing repetition. I was trying to code my own version.
 

MrChips

Joined Oct 2, 2009
30,985
The first approach in reducing memory requirement is to use the smallest data size.
Can you use 8-bit data type instead of 16 bits?
 

Papabravo

Joined Feb 24, 2006
21,264
Thanks both. I did take a brief look at Progmem before posting, but it looks heavy going. I'm an 'Arduino prgrammer' with no C/C++ training or expertience.

Reckon I'll have to approach this part of my JukBox project in a radically diffrent manner. The background in brief: using the DFR Mini MP3 Player module and its DFRobotDFPlayerMini.h library. One of its functions is randomAll(). While that does indeed play my 2,600 tracks randomly, it has a flaw in not preventing repetition. I was trying to code my own version.
I did not assume that you had any C/C++ training or experience, that is why I was responding in general terms about how the Arduino IDE might be doing things. These are general principles that are independent of any particular language, and I started doing this in 1962 just shy of a decade before K&R wrote their first C compiler.

BTW are you familiar with hash tables as a way of checking for duplicates? This is a technique used by compiler writers to build a table of symbols to record the value of every symbol encountered in a program and check for duplicates. It might be the magic bullet for this application. the starting point for this algorithm would be to state a requirement like:
I want no repeats for at least 150 successive tracks.​
Now you create a function called the hash function that maps your 2600 tracks into a number in the range [0,...149]. Each time you play a track you compute the hash function for the track and make an entry in that location of the hash table if it is empty. When you pick a song you have played before the hash function will tell you this and you can go onto another track number. At some point the hash table will get pretty full so you have to start over and there may be some overlap between sessions of 100-125 tracks. There are of course more details but that is the basic idea.
 
Last edited:

Thread Starter

Terrypin

Joined Feb 5, 2016
113
Thanks papa bravo, that looks a good alternative. I’ll try it.

Most of my code works on the 26 individual folders, ranging in size from 30 to 252 tracks. I use the array technique successfully on those to play their tracks randomly, fully, and without repetition. Two things that I’d hoped to extend to the entire contents - before hitting the memory issue.
 
Top