0

I have a somewhat large sketch that uses the Adafruit_ssd1306(I2C) library for a 128X64 LCD. The sketch is a designed to be an alarm clock. When I upload the sketch with out initializing serial, it works as designed. However if I do intialize serial:

Serial.begin(9600);

the program fails to run on my UNO. After many hours of troubleshooting I noticed I have several large char arrays that may be the culprit.

const char *menusDisplay[] = {"1. Alarm-is Off", "2. Month", "3. Hour", "4. Minute", "5. Exit", "6. Alarm Set", NULL};
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep" , "Oct", "Nov", "Dec", NULL};
const int days[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

The months array as 12 elements. If I shorted it down to 2 elements and upload the programs with serial initialized, the program runs. At first I thought is was a memory leak in perhaps the Adafruit_ssd1306. But I also have another LCD library Adafruit_ssd1306syp that the issue occurred too. So that ruled out those libraries.

When I compile the sketch without Serial:

Sketch uses 16,846 bytes (52%) of program storage space. Maximum is 32,256 bytes.
Global variables use 737 bytes (35%) of dynamic memory, leaving 1,311 bytes for local variables. Maximum is 2,048 bytes.

With Serial:

Sketch uses 17,862 bytes (55%) of program storage space. Maximum is 32,256 bytes.
Global variables use 910 bytes (44%) of dynamic memory, leaving 1,138 bytes for local variables. Maximum is 2,048 bytes.

Any ideas of what may be going on? I would load the sketch but its very large. If needed, I can try to cut it down and reproduce the issue.

  • 1
    The reported percentage of “dynamic memory” used is actually the percentage of RAM used by static and global variables. A significant amount of RAM can be used by the heap and the stack, which is not reported here as it can only be measured at run time. C.f. this answer and this answer on how to measure the amount of free RAM. – Edgar Bonet Jun 12 '15 at 11:56
  • @EdgarBonet That was it. I ran out ram. Make this answer so you can get the credit. I have 2k of ram (Arduino) to start with. With serial initialized & my code, I have around 100 at the start of the program. I am sure that's the issue. – PhillyNJ Jun 13 '15 at 11:14
0

Since no other code is posted, I am going to guess that you're performing a loop on months[], which has 13 elements (last one is NULL).

You are likely also trying to walk the days[] array (or some other array), which only has 12 elements.

Since days[] or the other (not pasted) array doesn't have 13 elements, you're probably overriding a critical bootloader memory which causes a crash.

0

@EdgarBonet pointed out in a comment, I need to check my dynamic ram, which could be used by the Heap and Stack. The class can be found here to measure ram usage. Since links can die, here is the code:

Here is the header:

/* MemoryFree.h */

// MemoryFree library based on code posted here:
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15
// Extended by Matthew Murdoch to include walking of the free list.

#ifndef MEMORY_FREE_H
#define MEMORY_FREE_H

#ifdef __cplusplus
extern "C" {
#endif

int freeMemory();

#ifdef  __cplusplus
}
#endif

#endif

Here is the .cpp

/* MemoryFree.cpp */

#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

extern unsigned int __heap_start;
extern void *__brkval;

/*
 * The free list structure as maintained by the 
 * avr-libc memory allocation routines.
 */
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};

/* The head of the free list structure */
extern struct __freelist *__flp;

#include "MemoryFree.h"

/* Calculates the size of the free list */
int freeListSize() {
  struct __freelist* current;
  int total = 0;
  for (current = __flp; current; current = current->nx) {
    total += 2; /* Add two bytes for the memory block's header  */
    total += (int) current->sz;
  }
  return total;
}

int freeMemory() {
  int free_memory;
  if ((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__heap_start);
  } else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
    free_memory += freeListSize();
  }
  return free_memory;
}

From this I was able to see how much ram was used. Of the avialable 2k, I had only 100k left. So now I know why my program is crashing, I need a solution. The solution was to store the static content in program memory (PROGMEM):

const char* const months[] PROGMEM = 
    {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };

const uint8_t days_of_month[] PROGMEM = 
    {
        31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.