Memory Leak on CPX

Play with it! Please tell us which board you're using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Post Reply
User avatar
Circuitmage
 
Posts: 13
Joined: Fri Nov 09, 2018 5:36 pm

Memory Leak on CPX

Post by Circuitmage »

I am playing with different TFT displays and I have a CPX that I have been able to get a ST7735 TFT display working on. I also wanted to use the mini Neopixels on the board at the same time. I quickly discovered I was unable to initiate both at the same time, so I placed my tft.initR and .begin statements within my loop to alternate activation.

That seemed to work...but I quickly discovered that after an hour, my CPX locks up. Research found I probably have a memory leak, so I added that check to my sketch and sure enough, it shows after about an hour I lose memory. Further research seems to indicate that a .begin statement may be the culprit in consuming memory.

So, it looks like I have 2 issues;
1) Is there a better way to use both the TFT and the Neopixels at the same time, without embedding the tft.initR and .begin statements repeatedly.
2) How can I avoid this memory leak (presumably from the .begin statement)...I am guessing solving issue 1 may be the fix (??).

Code and memory leak shown below. Thanks in advance for any pointers.

Code: Select all

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <Adafruit_CircuitPlayground.h> 

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI A5 // Data out
#define TFT_SCLK A4 // Clock out
#define TFT_CS    0
#define TFT_RST  A1 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC   A7

// For ST7735-based displays, we will use this call
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// OR for the ST7789-based displays, we will use this call
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

#define BLACK   0x0000
#define GRAY    0x8410
#define WHITE   0xFFFF
#define RED     0xF800
#define ORANGE  0xFA60
#define YELLOW  0xFFE0  
#define LIME    0x07FF
#define GREEN   0x07E0
#define CYAN    0x07FF
#define AQUA    0x04FF
#define BLUE    0x001F
#define MAGENTA 0xF81F
#define PINK    0xF8FF

#define BRIGHTNESS 20  // Brightness of the neopixels, set to 255 for max or lower for less bright.

#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else  // __ARM__
extern char *__brkval;
#endif  // __arm__


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

  tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

  // SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
  // Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
  // may end up with a black screen some times, or all the time.
  //tft.setSPISpeed(40000000);
  
  tft.fillScreen(ST77XX_BLACK);
    
  Serial.println("done");
  delay(1000);
}

void loop() {
  //Re-init tft display
  tft.initR(INITR_MINI160x80);  // Init ST7735S mini display
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);

  tft.fillScreen(WHITE);
  tft.setTextColor(YELLOW, WHITE);
  tft.setTextSize(2);
  tft.setCursor(10, 05);
  tft.print("NAME");
  tft.setCursor(20, 32);
  tft.print("TITLE");
  tft.setCursor(30, 55);
  tft.print("TITLE2");

  CircuitPlayground.begin(BRIGHTNESS);

  // Turn ON the NeoPixels
  for (int p=0; p<5; p++) {
    CircuitPlayground.setPixelColor(p, 255, 0, 0);
    CircuitPlayground.setPixelColor(9-p, 255, 0, 0);
    delay(1000);
  }
  // Turn OFF all the NeoPixels
  CircuitPlayground.clearPixels();

  //Re-init tft display
  tft.initR(INITR_MINI160x80);  // Init ST7735S mini display
  tft.setRotation(3);
  
  tft.fillScreen(WHITE);
  tft.setTextSize(3);
  tft.setCursor(10, 30);
  tft.setTextColor(BLUE, WHITE);
  tft.print("COMPANY");
  CircuitPlayground.begin(BRIGHTNESS);

  // Turn ON the NeoPixels
  for (int p=0; p<5; p++) {
    CircuitPlayground.setPixelColor(p, 0, 255, 255);
    CircuitPlayground.setPixelColor(9-p, 0, 0, 255);
    delay(500);
  }
  // Turn OFF all the NeoPixels
  CircuitPlayground.clearPixels();
  Serial.println(freeMemory(), DEC);
}

int freeMemory() {
  char top;
#ifdef __arm__
  return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
  return &top - __brkval;
#else  // __arm__
  return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif  // __arm__
}

Code: Select all

17:25:38.936 -> 25931
17:25:49.374 -> 25931
17:25:59.857 -> 25931
17:26:10.379 -> 25931
17:26:20.863 -> 25931
17:26:31.344 -> 25891
17:26:41.804 -> 25811
17:26:52.262 -> 25731
17:27:02.790 -> 25651
17:27:13.224 -> 25571
17:27:23.736 -> 25491
17:27:34.186 -> 25411
17:27:44.669 -> 25331
17:27:55.181 -> 25251
.
.
.
18:19:37.618 -> 1547
18:19:48.130 -> 1467
18:19:58.566 -> 1387
18:20:09.066 -> 1307
18:20:19.529 -> 1227
18:20:30.046 -> 1147
18:20:40.506 -> 1067
18:20:50.987 -> 987
18:21:01.484 -> 907
18:21:11.934 -> 827
18:21:22.432 -> 747
18:21:32.915 -> 667
18:21:43.379 -> 587
18:21:53.886 -> 507
18:22:04.354 -> 427
18:22:14.840 -> 347
18:22:25.326 -> 267
18:22:35.787 -> 187

User avatar
Circuitmage
 
Posts: 13
Joined: Fri Nov 09, 2018 5:36 pm

Re: Memory Leak on CPX

Post by Circuitmage »

Ok, so after a bit more looking....I added the Adafruit_Sleepydog library and used the Watchdog.enable to reset my device (after x loops).

It would still be good to know if there is a better way to use both the TFT and NeoPixles, but for now...this works! :)

Post Reply
Please be positive and constructive with your questions and comments.

Return to “Circuit Playground Classic, Circuit Playground Express, Circuit Playground Bluefruit”