when you call this
you execute this malloc()
if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
you screen size is
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
so you are asking for 128*((64+7)/8) = 1136 bytes of SRAM
when you compile on a UNO, you need also 819 bytes of SRAM
So that's a total of 1955 bytes when you have 2048 bytes in total... that's not enough for the stack and all the other dynamic needs
if you change all your display.println("xxx");
into display.println(F("xxx"));
and the naked display.println("");
into display.println();
then you'll save about 40 bytes of RAM... that's enough to accommodate your 16 pointers of checkList and the content in SRAM and it should compile, but it will likely be risky as you are still very close of memory saturation.
I would move the items if Flash too to gain a bit more memory and go down to 707 instead of 819
the code would look like this
#include <SPI.h>
#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define APDS9960_INT 2 // Needs to be an interrupt pin
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
struct t_Item {
char label[10];
};
static const t_Item checkList[] PROGMEM = {
{"Item 1"}, {"Item 2"}, {"Item 3"}, {"Item 4"}, {"Item 5"}, {"Item 6"}, {"Item 7"}, {"Item 8"}
};
void setup() {
Serial.begin(9600);
Serial.println(F("In setup()"));
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println(F("ADPS Initialization"));
display.println();
display.setTextSize(2);
display.println(F("Success! "));
display.display();
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println(F("ADPS Initialization"));
display.println();
display.setTextSize(2);
display.println(F("Failed! "));
display.display();
}
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Gesture sensor is now running"));
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println(F("ADPS Initialization"));
display.println();
display.setTextSize(2);
display.println(F("Success! "));
display.display();
} else {
Serial.println(F("Something went wrong during gesture sensor init!"));
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println(F("ADPS Initialization"));
display.println();
display.setTextSize(2);
display.println(F("Failed! "));
display.display();
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
// Draw a single pixel in white
display.drawPixel(10, 10, SSD1306_WHITE);
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
display.display();
delay(2000);
// Invert and restore display, pausing in-between
Serial.println(F("calling invertDisplay(true))"));
display.invertDisplay(true);
delay(1000);
Serial.println(F("calling invertDisplay(false))"));
display.invertDisplay(false);
delay(1000);
}
void loop() {
Serial.println(F("In loop()"));
isr_flag = 1; // Hard-coding it for now. Ideally isr_flag should be set to 1 by the interrupt routine. But it's not happening. TODO: To be fixed.
if ( isr_flag == 1 ) {
Serial.println(F("In loop with isr_flag==1"));
detachInterrupt(0);
// Read the checkList
for (int i = 0; i < 8; i++)
{
Serial.println(F("In FOR LOOP !!!!!!!!!!"));
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println((__FlashStringHelper*) checkList[i].label);
display.display();
delay(1000);
}
// TODO: Combine the below code related to the gestures with the every item displayed on the screen. Firt get the items displayed on the screen working
handleGesture();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
void interruptRoutine() {
Serial.println(F("In interruptRoutine()- setting isr_flag to 1"));
isr_flag = 1;
}
void handleGesture() {
Serial.println(F("In handleGesture()"));
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("UP"));
display.display();
break;
case DIR_DOWN:
Serial.println("DOWN");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("DOWN"));
display.display();
break;
case DIR_LEFT:
Serial.println("LEFT");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("<- LEFT"));
display.display();
break;
case DIR_RIGHT:
Serial.println("RIGHT");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("RIGHT ->"));
display.display();
break;
case DIR_NEAR:
Serial.println("NEAR");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("NEAR"));
display.display();
break;
case DIR_FAR:
Serial.println("FAR");
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("FAR"));
display.display();
break;
default:
Serial.println("NONE");
}
}
}
you are still close to the memory limit (~200 bytes left) but it might be good enough.
in order to print the text, you would use (__FlashStringHelper*) checkList[i].label
instead of just checkList[i]