Parameters in my functions are taking up my memory

im at about 1000 lines of code but my static memory is already at 67%. Im wondering if i change all of my char arrays into global variables instead of sending them through the functions will save more memory. ill try to remove any code that isn't relevant.

#include <Stepper.h>
#include "rotateFace.h"
#include "rotateOutside.h"
// initialize the stepper library on pins 8 through 11:
//the 100 is the steps per revoltuion change it to get the best speed possible
Stepper whiteStepper(100, 8, 9, 10, 11);
void setup() {
  Serial.begin(9600);
}
void loop() {
  //Setting up the white face
  Serial.println(F("With the white side towards you and the red end facing up enter the colors of each square by typing\nfor example 'wrbgwybog'."));
  char white[10];
  String temp = "";
  while (Serial.available() == 0) {}
  temp = Serial.readString();
  temp.toCharArray(white, 10); //changes from a string to a char array
  temp.remove(0, 10);
  //Setting up the Blue face
  Serial.println(F("With the Blue side towards you and the white end facing up enter the colors of each square by typing"));
  while (Serial.available() == 0) {}
  temp = Serial.readString();
  char blue[10];
  temp.toCharArray(blue, 10);
  temp.remove(0, 10);

// this is repeated for orange[],green[], red[], and yellow[]

  //for the rotate() function add the direction as cw or cc, color for ex 'white' then all the arrays in order
  while (solved == false) {
    if (white[1] != 'w' || red[1] != 'r') { // if the white red piece is not in the white red spot
      if (white[3] == 'w' && blue[1] == 'r') { // if the white red piece is in the white 3 spot
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (white[5] == 'w' && green[1] == 'r') { // if white red piece is in the white 5 spot
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (white[7] == 'w' && orange[1] == 'r') { //if white red piece is in the white 7 spot
        rotate("cw", "orange", white, blue, orange, green, red, yellow);
        rotate("cw", "orange", white, blue, orange, green, red, yellow);
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (white[1] == 'r' && red[1] == 'w') { // if white red piece is in red 1 spot
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (green[5] == 'r' && red[3] == 'w') { // if white red piece is in red 3 spot
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (blue[3] == 'r' && red[5] == 'w') { // if white red piece is in red 5 spot
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (yellow[1] == 'r' && red[7] == 'w') { // if white red piece is in red 7 spot
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (white[3] == 'r' && blue[1] == 'w') { //if the white red piece is in the blue 1 spot
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
      }
      else if (red[5] == 'r' && blue[3] == 'w') { //if the white red piece is in the blue 3 spot
        rotate("cc", "red", white, blue, orange, green, red, yellow);
      }
      else if (orange[3] == 'r' && blue[5] == 'w') { //if the white red piece is in the blue 5 spot
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
      }
      else if (yellow[5] == 'r' && blue[7] == 'w') { //if the white red piece is in the blue 7 spot
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
      }
      else if (white[7] == 'r' && orange[1] == 'w') { //if the white red piece is in the orange 1 spot
        rotate("cw", "orange", white, blue, orange, green, red, yellow);
        rotate("cw", "orange", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
      }
      else if (blue[5] == 'r' && orange[3] == 'w') { //if the white red piece is in the orange 3 spot
        rotate("cc", "orange", white, blue, orange, green, red, yellow);
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "orange", white, blue, orange, green, red, yellow);
        rotate("cw", "blue", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "blue", white, blue, orange, green, red, yellow);
      }
      else if (green[3] == 'r' && orange[5] == 'w') { //if the white red piece is in the orange 5 spot
        rotate("cc", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cc", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
      }
      else if (yellow[7] == 'r' && orange[5] == 'w') { //if the white red piece is in the orange 7 spot
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cc", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
      }
      else if (white[5] == 'r' && green[1] == 'w') { //if the white red piece is in the green 1 spot
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (orange[5] == 'r' && green[3] == 'w') { //if the white red piece is in the green 3 spot
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
      }
      else if (red[3] == 'r' && green[5] == 'w') { //if the white red piece is in the green 5 spot
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (yellow[3] == 'r' && green[7] == 'w') { //if the white red piece is in the green 7 spot
        rotate("cc", "green", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "green", white, blue, orange, green, red, yellow);
      }
      else if (red[7] == 'r' && yellow[1] == 'w') { //if the white red piece is in the yellow 1 spot
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (green[7] == 'r' && yellow[3] == 'w') { //if the white red piece is in the yellow 3 spot
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (blue[7] == 'r' && yellow[3] == 'w') { //if the white red piece is in the yellow 5 spot
        rotate("cc", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
      else if (orange[7] == 'r' && yellow[3] == 'w') { //if the white red piece is in the yellow 7 spot
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "yellow", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
        rotate("cw", "red", white, blue, orange, green, red, yellow);
      }
    }// end red piece loop
}//ends solved loop though i haven't added a method for checking to see if the arrays are  solved yet
}

here is the function i made that i use #include "rotateFace.h" to initalize

void rotate(char direct[3], String color, char white[10], char blue[10], char orange[10], char green[10], char red[10], char yellow[10]) {
  char arr[16] = "";
  String results = "";
  if (color == "white") {
    rotateFace(direct,white);
    for (int i = 0; i < 3; i++) {
      results = results + red[2 - i]; //red[2,1,0]
    }
    for (int i = 0; i < 3; i++) {
      results = results + green[2 - i]; //green[2,1,0]
    }
    for (int i = 0; i < 3; i++) {
      results = results + orange[2 - i]; //orange[2,1,0]
    }
    for (int i = 0; i < 3; i++) {
      results = results + blue[2 - i]; //blue[2,1,0]
    }
  }
  if (color == "blue") {
    rotateFace(direct,blue);
    for (int i = 0; i < 3; i++) {
      results = results + white[i * 3]; //white[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + orange[i * 3]; //orange[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + yellow[8 - (i * 3)]; //yellow[8,5,2]
    }
    for (int i = 0; i < 3; i++) {
      results = results + red[8 - (i * 3)]; //red[8,5,2]
    }
  }
  if (color == "orange") {
    rotateFace(direct,orange);
    for (int i = 0; i < 3; i++) {
      results = results + white[i + 6]; //white[6,7,8]
    }
    for (int i = 0; i < 3; i++) {
      results = results + green[i * 3]; //green[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + yellow[(i + 6)]; //yellow[6,7,8]
    }
    for (int i = 0; i < 3; i++) {
      results = results + blue[8 - (i * 3)]; //blue[8,5,2]
    }
  }
  if (color == "green") {
    rotateFace(direct,green);
    for (int i = 0; i < 3; i++) {
      results = results + white[8 - (i * 3)]; //white[8,5,2]
    }
    for (int i = 0; i < 3; i++) {
      results = results + red[i * 3]; //red[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + yellow[i * 3]; //yellow[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + orange[8 - (i * 3)]; //orange[8,5,2]
    }
  }
  if (color == "red") {
    rotateFace(direct,red);
    for (int i = 0; i < 3; i++) {
      results = results + white[2 - i]; //white[2,1,0]
    }
    for (int i = 0; i < 3; i++) {
      results = results + blue[i * 3]; //blue[0,3,6]
    }
    for (int i = 0; i < 3; i++) {
      results = results + yellow[(2 - i)]; //yellow[2,1,0]
    }
    for (int i = 0; i < 3; i++) {
      results = results + green[8 - (i * 3)]; //green[8,5,2]
    }
  }
}//ends void function

that is a very shortened version of it but the function changes all arrays without me needing to return a value which is exactly what i want but im wondering how i would change this function to not need the char arrays to be put in as parameters assuming it would save space after calling this function 600+ times. also here is the 2nd and last function i made which is much simpler in case anyone wants context of what it does

void rotateFace(char direct[3], char face[10]) {
  if (direct == "cw") {
    char temp = face[0];
    face[0] = face[6];
    face[6] = face[8];
    face[8] = face[2];
    face[2] = temp;
    temp = face[1];
    face[1] = face[3];
    face[3] = face[7];
    face[7] = face[5];
    face[5] = temp;
  }
  else if (direct == "cc") {
    char temp = face[1];
    face[1] = face[5];
    face[5] = face[7];
    face[7] = face[3];
    face[3] = temp;
    temp = face[0];
    face[0] = face[2];
    face[2] = face[8];
    face[8] = face[6];
    face[6] = temp;
  }
}

let me know if there is anything i can clarify. like i said i just need to do this in order to clear up memory.

are they tabs in project folder? then you can put them together and post here

Blockquote
the two tabs are posted below the main script. i seperated them out between texts.

ok. i make it self.

You could cut-down on your use of Strings.

Why use a String when a simp!e enum would work just as well?

Are the same six global arrays passed in the same order to rotate() every time? Since they are global, they don't have to be passed as arguments.

Also, as pointed out above, it is MUCH more efficient to pass and compare numbers than it is to pass and compare strings. An 'enum' is a good way to assigned numbers to names when you don't need to pick specific numbers. (The enum defaults to assigning consecutive integers starting at zero.)

enum Direction {CW, CC};
enum FaceID {fWhite, fBlue, fOrange, fGreen, fRed, fYellow};

{
  else if (red[7] == 'r' && yellow[1] == 'w') 
    { //if the white red piece is in the yellow 1 spot
      rotate(CW, fRed);
      rotate(CW, fRed);
    }
    else if (green[7] == 'r' && yellow[3] == 'w') 
    { //if the white red piece is in the yellow 3 spot
      rotate(CW, fYellow);
      rotate(CW, fYellow);
      rotate(CW, fRed);
    }

void rotate(Direction dir, FaceID color) {
  char arr[16] = "";
  if (color == fWhite) {
    rotateFace(dir, White);

Why do you want to use strings for the colors and directions? (Maybe you have python/javascript experience?)

(oops. Johnwasser got here first and said everything I wanted to say.)

lol yeah i originally started to teach myself python for fun and when my family got me an arduino kit i started to try and learn c++. This project has taught me a lot, i didn't know enums were a think before this post but just to try it out and to save space ill try it.

I wanted to use strings to keep the code recognizable whenever asking for help but enums would allow me to keep that while saving memory

everyone else has covered the obvious string vs char thing. so I'll offer a different piece of advise: get accustom to the uintN_t system of variables, its built in so you can use them straight away: uint8_t is an 8 bit unsigned integer. uint16_t is a 16bit unsigned int...
One major advantage is cross platform compatibility. For example, you've use "int" a few times, I am assuming your running some derivation of a 328 (uno, nano, mega, ect) which means when you define "int" you are allocating 16 bits of memory to that variable. Want to move to a better board? say the arduino zero or esp32...now an "int" is 32bits. whereas a uint16_t is 16 bits on both systems.

this system also makes you more conscience of how much space you actually need. Not going to make a huge difference in the code you posted, but allocating 16bits to count to 3 is rather silly when 8bits is more than enough. These things can really add up when you build complex programs that have to run on limited resources.

Passing parameters around as strings is a luxury that you can get away with on the near-supercomputer systems that execute billions of operations per second and have gigabytes of memory. Like a cellphone, laptop, or desktop PC.

An Arduino is a MUCH smaller system, and a bit more care is needed.

Having had a career full of "performance-critical" smaller computers, it drives me a bit crazy every time I see one of the new high-level languages passing around options as strings. But it's hard to argue with the results (like: "runs acceptably fast in the target environment, and is readable...")

1 Like

After getting some guidance from you guys I've moved away from strings in almost every place I think I only use one which I do as a way to avoid using a loop to enter chars to an array (not that there isn't another way) but I've really liked learning about the challenges that come with memory control. After moving some char arrays and strings to enums I've been able to cut the memory usage in half and have more than enough space to finish out my program. I saw another post that I can use to save maybe a couple hundred bytes and I might used it just for experience, though not necessary.

remember that in the future when your pulling your hair out trying to get a few more bits on there! :grinning:

sounds likes you made major progress, thats something to feel good about. Good luck with the rest of the project! I do hope you'll share it with us when you're done(if you're able to).

I'm determined to spend this summer working on this project until it works I'd be happy to share what it comes out to. I'm still trying to figure out what kind of motor to use tho. I keep finding people using servo motors but I need a limitless rotation motor and the stepper one that comes with the kit is quite slow.

You are sending pointers to arrays not arrays themselves

while you probably find projects that use a limited angular range, servos can spin 360 just like any other motor. Perhaps people will fight me on this, but a servo, in its broadest sense, is a motor with positional feedback (ie an encoder).

I've watched a few videos explainin the difference between pointers and arrays but I haven't really understood. For my goal thinking of them as arrays as they are passed has worked out though I'm probably not understanding everything there is to what goes on with it. Ill try to study pointers a little more but atm the program works.

Arrays are chucked around as pointers or references if you take extra steps, never they are copied unless you memcpy them or something so your assumption that it takes some memory passing them to the function is wrong

rather than holding a value, a pointer holds the memory address of that value. Think of it a little like a shortcut (or alias) on the computer.

In C++ varibles can be passed by : value, reference by pointer. For all variable EXCEPT arrays, the default is to pass by value. This means making a new value (different memory location) & coping the value you passed in, to that variable.

by default, arrays are passed by reference, no additional syntax is required. Anything you do to that variable, will modify the original array. Note that arrays decay to a pointer to the first element.

To do this with other variable types, you can feed in a reference:

void myfunction(int myvar, int &myVarRef){  }

myvar gets copied, so you have the valuein the function, but you cannot modify it. myVarRef is declared as a reference (& means "address of"). So now the original variable is feed into the function & you can modify it as you wish.

pointers are declared with the use of "*" next to the variable type:

int* myVarPtr;

this holds the memory address of an int variable, its is NOT an int itself. as I declared it, it holds nothing, but we could say:

int myVar =5;
int* myVarPtr = &myVar;     //note the use of & to get the address of myVar.

now we can access myVar, as normal, but we can also use "*" to de reference myVarPrt:

Serial.println(*myVarPtr);
Serial.println(myVar);

both these lines will print out "5"

Thats an overview, lots of good you tube tutorials on the subject, I really recommend getting this down, its fundamental to coding in c++.

Unless otherwise designated, their passed by reference, not by pointer.

well is does take -some- memory, the memory required to store the address. Granted, thats very little, prob 2 bytes / array. I dont know what system he is usuing, but you can find out with

sizeof(int*)
1 Like

I'm a bit late but after doing all of the things recommended (except using a different method for initializing integers to only use 8 bytes instead of 16 ) my project dropped down to 34% usage in my static memory and as I've been adding to it its gone up to 44%. I'm pretty sure this is better than I need it to be but I thank you guys for all of your suggestions.

Post your code - maybe there are further savings to be made.