Start a new topic

High RAM usage - where to start reducing?

Hi All. I'm a new user of the Nextion 2.4" display, running it on an Arduino Micro.  It's all working just fine. I have run it from the RX/TX pins (0/1) and also from pins 10/11 (by changing the NexConfig.h definition of nexSerial).  In short, all working as expected - at least as much as I've tried.


The problem is, I'm working in an extremely tight memory environment - I am running a MicroSD card from which I am streaming WAV files which encode video and audio for a mechanical television.  The Nextion is controlling the user interface for the TV - brightness, contrast, volume, etc.


A bit of a plug:  here's my project video playlist

https://www.youtube.com/playlist?list=PLBo1eD9x0FwsKHMemeg55uVL2CDSLgNPr


So anyway, on to my question - because I'm doing an awful lot with the little Arduino, memory is very tight - and I have just found out that a MAJOR hog of memory is the Nextion code.  If I have a minimal stand-alone Nextion test program which simply sets up a few sliders and callbacks, the RAM usage shoots to 48% (from 5% for an empty project).  That's basically 43% of all available RAM used just by the Nextion code. And compared to an empty project, the Nextion library is using 30% of the available ROM, too!!! This is really really high and costly.


Oh, the question - what is using all the memory, and where/how best to tackle reducing it?  I thought I'd ask here before starting a hunt trough the code base.


Thanks for any assistance. Hope I havent' broken any forum rules. For the record, I love the hardware - amazing for the price!


 

// Minimal callback test of Nextion UI for Mechanical TV on Arduino Micro
// by Andrew Davie (andrew@taswegian.com)

#include "NexSlider.h"
#include "NexText.h"
#include "NexButton.h"
#include "NexCheckbox.h"
#include "NexText.h"

NexSlider seekerSlider = NexSlider(0, 12, "seek");
NexSlider brightnessSlider = NexSlider(0, 8, "brightness");
NexSlider contrastSlider = NexSlider(0, 10, "contrast");
NexSlider volumeSlider = NexSlider(0, 11, "volume");
NexCheckbox gammaCheckbox = NexCheckbox(0, 3, "gamma");
NexButton stopButton = NexButton(0, 4, "stopButton");
NexText timePos = NexText(0, 9, "timePos");

NexTouch *nex_Listen_List[] = {
    &stopButton,
    &seekerSlider,
    &contrastSlider,
    &brightnessSlider,
    &gammaCheckbox,
    &volumeSlider,
    NULL
};

boolean stopped = false;

void stopButtonCallback(void *ptr) {
  NexButton *stopButton = (NexButton *) ptr;
  stopped = !stopped;
  Serial.print(F("STOP = "));
  Serial.println(stopped);
}

void brightnessCallback(void *ptr) {
  NexSlider *slider = (NexSlider *) ptr;
  long bright;
  slider->getValue(&bright);
  Serial.print(F("BRIGHTNESS = "));
  Serial.println(bright);
}

void contrastCallback(void *ptr) {
  NexSlider *slider = (NexSlider *) ptr;
  long contrast;
  slider->getValue(&contrast);
  Serial.print(F("CONTRAST= "));
  Serial.println(contrast);
}

void volumeCallback(void *ptr) {
  NexSlider *slider = (NexSlider *) ptr;
  long volume;
  slider->getValue(&volume);
  Serial.print(F("VOLUME ="));
  Serial.println(volume);
}

void seekerCallback(void *ptr) {
  NexSlider *slider = (NexSlider *) ptr;
  long seekPosition;
  slider->getValue(&seekPosition);
  Serial.print(F("SEEK ="));
  Serial.println(seekPosition);
}


void gammaCallback(void *ptr) {
  NexCheckbox *checkbox = (NexCheckbox *) ptr;
  long gamma;
  checkbox->getValue(&gamma);
  Serial.print(F("GAMMA ="));
  Serial.println(gamma);
}

void setup(void) {
    nexInit();
    seekerSlider.attachPop(seekerCallback, &seekerSlider);
    brightnessSlider.attachPop(brightnessCallback, &brightnessSlider);
    contrastSlider.attachPop(contrastCallback, &contrastSlider);
    volumeSlider.attachPop(volumeCallback, &volumeSlider);
    gammaCheckbox.attachPop(gammaCallback, &gammaCheckbox);
    stopButton.attachPop(stopButtonCallback, &stopButton);
}
void loop(void) {
    nexLoop(nex_Listen_List);
}

 


@indev2


Using the SoftwareSerial code - you reported 5,322 bytes and 462 bytes sram

I compiled for UNO on 1.8.0 and got 4614 bytes  and 448 sram


Do I have your Hardware Serial version?



@indev2


Just to continue stats on open forum so users see differences

"Hardware Serial version" on 1.8.0 compiles down to 2910 bytes using 333 bytes


What is 1.6.9 reporting?

Still considerable differences, less so on the Globals 

Sketch uses 3,446 bytes (10%) of program storage space. Maximum is 32,256 bytes.
Global variables use 347 bytes (16%) of dynamic memory, leaving 1,701 bytes for local variables. Maximum is 2,048 bytes.

 

Not sure what they could have done between 1.8.0 and 1.8.1/1.8.2 to cause such increases

[core]

* Add Atmel-ICE and JTAGICE3 programmers for AVR chips (thanks @matthijskooijman)

* AVR: Set unused bits of extended fuse to 1, should remove some avrdude warning during burn bootloader (thanks @descampsa)

* AVR: USB: send ZLP when needed (allows full 64 bytes packets)

* AVR: USB: use IAD descriptors instead than Generic (thanks @cuitoldfish)


So perhaps the fasted way towards sram reduction isn't numerically eliminate strings

- it maybe as simple as downloading the 1.8.0 IDE


Thanks Steve

I will test on Windows today instead of OSX and see if there are any differences in my results.


Personally, I would be disappointed if such different results exist.
Same code, for same target should produce the same result.

Seems there are differences within Arduino compiler


Still numerical approach will reduce further

- it may not be needed if Windows 1.8.0 gives yields reasonable results

I want to make a point here


When I compile your "minimal" code provided above for micro

Arduino reports 8606 bytes (30%) of program storage space

Global variables use 631 bytes (24%) of dynamic memory


When I compile basic with two serials open for micro I get

Sketch uses 4414 bytes (15%) of program storage space

Global variables use 321 bytes (12%) of dynamic memory


At this point the difference is what Nextion consumes

  4192 bytes storage, 310 bytes sram (12.1% of 2560)


So what is off here?  Your claim was 43% of used by Nextion


Now I'm really confused. I setup a brand new VirtualBox instance of Windows 7.

I downloaded and installed Arduino IDE 1.8.2

I compiled the serial example (just one serial port) and get the same/correct numbers we agree on. (182 bytes RAM used)


I download the ITEAD library from GitHub Arduino Nextion

Place it in the Arduino libraries subdirectory.

I modify NexConfig.h to disable the serials as before. File attached.

I grab the 2nd version of my minimal Nextion code example (the one using just one slider). File attached.


I compile, and i get...


Sketch uses 7260 bytes (23%) of program storage space. Maximum is 30720 bytes.

Global variables use 857 bytes (41%) of dynamic memory, leaving 1191 bytes for local variables. Maximum is 2048 bytes.


This is what I see on OSX.  Difference in RAM between this and the plain serial test code: 857-182 = 675 bytes.


I can only conclude we are compiling different code. I have now done this test with vanilla installs on both OSX and Windows 7.

I expect you are compiling with your in-house library, not the one downloaded from GitHub?


ino
(129 Bytes)
h
(1.28 KB)

Interesting. Thank you for checking.

I will re-test because I don't exactly understand your numbers or what you did.

When I compiled my minimal example, I got the quoted number (43% of RAM used).

I will come back with a confirmation tomorrow.


You may have a point about the cost of having a serial port; me bad, I didn't consider that.

As I said, I will do some more tests.  310 bytes is very reasonable.


Sounds like my claim is off - I will re-do the tests, as I said.

Thanks again for the reply.


Arduino IDE 1.80 - Board Arduino/Genuino Micro

First test was basic as I suggested to do above.


#include <Arduino.h>


void setup ( void) {

  Serial.begin(9600);

  Serial1.begin(115200);

}

void loop() {

  int i;

  i++;

}


Second test was your code as posted above.

I think I have possibly found the problem and it is probably my fault, sorry. I am using a software serial and have defined this in the NexConfig.h and obviously that is using all the RAM. I was/am having issues downloading when the Nextion is connected to RX/TX so switched it and seemed to be working fine. I had forgotten this reconfiguration and now see that I have modified the file thus...


/** 
 * Define DEBUG_SERIAL_ENABLE to enable debug serial. 
 * Comment it to disable debug serial. 
 */
//#define DEBUG_SERIAL_ENABLE

/**
 * Define dbSerial for the output of debug messages. 
 */
#define dbSerial Serial

/**
 * Define nexSerial for communicate with Nextion touch panel. 
 */

#ifdef NEXTION_SERIAL_REDEFINE
	#include <SoftwareSerial.h>
	extern SoftwareSerial NexSerial;
	#define nexSerial NexSerial
#else
	#define nexSerial Serial1
#endif

 

Clearly this is a user error - I will have to find a way to go back to hardware serial.

I apologise for the error, and thank you for your support.


Addendum: I was compiling for "Nano" target, as before.

To go back to Hardware Serial



 

/**
 * @file NexConfig.h
 *
 * Options for user can be found here. 
 *
 * @author  Wu Pengfei (email:<pengfei.wu@itead.cc>)
 * @date    2015/8/13
 * @copyright 
 * Copyright (C) 2014-2015 ITEAD Intelligent Systems Co., Ltd. \n
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 */
#ifndef __NEXCONFIG_H__
#define __NEXCONFIG_H__

/**
 * @addtogroup Configuration 
 * @{ 
 */

/** 
 * Define DEBUG_SERIAL_ENABLE to enable debug serial. 
 * Comment it to disable debug serial. 
 */
#define DEBUG_SERIAL_ENABLE

/**
 * Define dbSerial for the output of debug messages. 
 */
#define dbSerial Serial

/**
 * Define nexSerial for communicate with Nextion touch panel. 
 */
#define nexSerial Serial1

#ifdef DEBUG_SERIAL_ENABLE
#define dbSerialPrint(a)    dbSerial.print(a)
#define dbSerialPrintln(a)  dbSerial.println(a)
#define dbSerialBegin(a)    dbSerial.begin(a)
#else
#define dbSerialPrint(a)    do{}while(0)
#define dbSerialPrintln(a)  do{}while(0)
#define dbSerialBegin(a)    do{}while(0)
#endif

/**
 * @}
 */

#endif /* #ifndef __NEXCONFIG_H__ *

 

Serial is Debug in Serial Monitor

Serial1 is connected to Nextion

Here is the correct sketch with the minimum Nextion callback example... attached file.

For me, OSX 10.11.1 with Arduino IDE 1.8.1 and Nextion library 0.9.0 from GitHub and compiling for 'Nano' ATMega328 processor, and with the NexConfig.h as per the previous file upload ...


Sketch uses 7260 bytes (23%) of program storage space. Maximum is 30720 bytes.

Global variables use 857 bytes (41%) of dynamic memory, leaving 1191 bytes for local variables. Maximum is 2048 bytes.



ino
(630 Bytes)

I think we are somewhat closer to standardization here.  Baseline 1 serial is consistent


image


And reduced (smaller than previous code) minimumNextionCallbackExample.ino

image


So to me the main difference I am seeing is Arduino IDE version being used

 - I am using 1.8.0 Arduino IDE, you are reporting 1.8.1 and 1.8.2

   on Windows Arduino IDE 1.8.0 - I am getting awesome results

   on other than Windows Arduino IDE 1.8.0 - you are getting really poor results.

 - I know version 1.8.0 for Windows can be downloaded from Arduino site

   https://www.arduino.cc/en/Main/OldSoftwareReleases#previous

Login or Signup to post a comment