0

I am trying to get this code working:

#include <Button.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RTC_DS1307 RTC;

// when I remove this part it works...
int mode = 1;
const String periodicSystem[60] = {
    "H", "He", "Li", "Be", "B", "C", "N", "O", 
    "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", 
    "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", 
    "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", 
    "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", 
    "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
    "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd"
};
/////////////////////////////////////////////////////////////////////

Button button1(7);

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

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // This will reflect the time that your sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  display.display();
}

void loop() {
  DateTime now = RTC.now();
  if(button1.pressed()) {
      display.clearDisplay();
      display.setTextSize(1); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(10, 0);
      display.print(now.second());
      display.display();
  }
}

Whenever I try to add the constant periodicSystem, I get the error SSD1306 allocation failed over Serial. The error also goes away when I remove the part with button1.pressed(). Basically I am not able to add the constant periodicSystem and read out a digital pin at the same time. To me it seems to be some sort of memory issue (I am only adding the constant, I am not doing anything else with it), but my IDE tells me I am only using 52% of the available storage. What am I doing wrong?

Here is my wiring (in reality I am using a 128x32 display, I didn't have the correct part for Fritzing; my display is labeled SDA, SCK, VCC, GND instead of SDA, SCK, VDD, GND; the RTC Module I am using is a DS1307 AT24C32 RTC Module):

My wiring

1

Your display needs 624 bytes of RAM for its internal buffer (128 * ((32 + 7) / 8)). The periodicSystem array needs a massive 360 bytes of RAM just for the objects. That doesn't include the memory used to store the actual string data, which by my reckoning is 168 bytes.

So far we're up to 624+360+168 = 1152 bytes of a maximum of 2048. Over half way and we haven't touched on the serial buffers or other objects that you're using.

An array (const or otherwise) of String objects is by far the least efficient way possible of storing constant string data on an Arduino. You're using 528 bytes of RAM to store what could be stored in 121 bytes of flash.

Personally I would store the data thus:

const char periodicSystem[] PROGMEM = "H HeLiBeB C N O F NeNaMgAlSiP S ClArK CaScTiV CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY ZrNbMoTcRuRhPdAgCdInSnSbTeI XeCsBaLaCePrNd";

Each symbol consists of exactly two bytes, and the PROGMEM forces it to stay in flash and never be copied to RAM.

You can get the two bytes of each symbol with:

char b1 = pgm_read_byte(periodicSystem + (i * 2));
char b2 = pgm_read_byte(periodicSystem + (i * 2) + 1);

Then either print them separately, or combine them into a C string:

char symbol[3] = { b1, b2, 0 };

That will include the space character, of course. So you could remove that if you like:

if (symbol[1] == ' ') symbol[1] = 0;

Theoretically you could also change the spaces in the original data to be character 0 if you like - depending on what you do with it, it shouldn't cause any issues:

const char periodicSystem[] PROGMEM = "H\0HeLiBeB\0C\0N\0O\0F\0NeNaMgAlSiP\0S\0ClArK\0CaScTiV\0CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY\0ZrNbMoTcRuRhPdAgCdInSnSbTeI\0XeCsBaLaCePrNd";

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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