Apparent memory/serial ouput issues with large-ish const arrays

Hi,

I am somewhat familiar with C/C++ but I am brand new to arduino. I am having a problem where serial output is breaking when I use arrays with length 184 (but not length 18).

When I upload the code below to my arduino uno I get the message “Binary sketch size: 7,304 bytes (of a 32,256 byte maximum)”, but the serial monitor outputs garbage: “SMéS*kEMáSºÊEMÑS¸*יÑS”, etc.

I can “fix” the problem by commenting out the 2 adafruit header files and the next few lines that create the motor shield and motor objects. It compiles successfully ("Binary sketch size: 6,926 bytes (of a 32,256 byte maximum)"), and the serial monitor output is exactly what I expect:

<snip> ...
Step 182	A 1	B 1	S 0.00	Done
Step 183	A 1	B 0	S 0.10	Done
Step 184	A 1	B 0	S 0.20	Done

So this maybe suggests that the adafruit libraries are to blame, EXCEPT that I can also “fix” the problem by commenting out the line (toward the end) Serial.print(penShading[stepNum]);, OR by reducing the length of the arrays (I tried 18 instead of 185 and got the expected output.)

So I am confused because it seems to depend on the length of the arrays, but judging from the binary sketch size reported I am safely under the maximum?

This is the minimal code to recreate the issue which just echoes back via Serial the numbers from some const arrays. I removed all of the code actually dealing with moving the motors because I still get the “error” without it.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_StepperMotor *myMotorLeft = AFMS.getStepper(200, 1);
Adafruit_StepperMotor *myMotorRight = AFMS.getStepper(200, 2);

const int stepsA[] = { -1, -1, 1, 1, 1, 0, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1 };
const int stepsB[] = { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 };
const int maxSteps = 185 ;
const float penShading[] = { 0.00, 0.00, 0.10, 0.20, 0.30, 0.00, 0.40, 0.50, 0.60, 0.70, 0.00, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.00, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 0.00, 1.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.00, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.00, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.00, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.00, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.00, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.10, 0.20, 0.00, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 0.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.00, 0.80, 0.90, 1.00, 0.00, 0.00, 0.10, 0.20 };

const int resolution = 25;

int stepNum = 0;

void setup() {
  Serial.begin(9600);
}


void loop() {
  if ( stepNum >= maxSteps ) return;
  
  Serial.print(F("Step "));
  Serial.print(stepNum);
  
  Serial.print(F("\tA "));
  Serial.print(stepsA[stepNum]);
  
  Serial.print(F("\tB "));
  Serial.print(stepsB[stepNum]);
  
  Serial.print(F("\tS "));
  Serial.print(penShading[stepNum]);
  
  // code to move motors goes here.

  Serial.println(F("\tDone"));
  
  
  stepNum++;  
}

Thanks for your help/feedback! If there is a better way to store the array data (hopefully besides using an SD card or anything else that would require buying additional components) I would be interested to hear. Also if there is an easier way to troubleshoot stuff that breaks the serial output?

Sorry this post is so long but at this stage I’m not really sure what is and isn’t relevant.

You can save half the space for each of your 'int' arrays by making them 'char' instead.

You can save 3/4 of your 'float' array by multiplying them by 10 and saving the integer part in a 'char'. Divide by 10.0 when you want to re-constitute the float value.

You don't mention what model of Arduino you are dealing with, but the UNO and friends have an incredibly small amount of RAM to work with -- 2KB. And constants like the arrays you declare for stepsA, etc, reside in RAM at runtime unless you use the PROGMEM mechanism. Generally the symptoms of running out of memory in this sort of case is that the first K or so of data looks right, and the rest is garbage. If you're using an UNO or MEGA, this is likely what is happening.

It is an Uno so I'm sure that must be the problem. I didn't realize the space for variables was so much smaller than the total available memory. I will look into the progmem thing. Thanks!