Skip to main content

Overview

Memory optimization is critical for embedded systems development. Kinematrix’s modular compilation system allows you to control exactly how much memory your application uses by selectively enabling only the modules you need.

Memory Usage Tiers

Kinematrix applications can be configured for different memory footprints:

Minimal Setup

~50KB Flash
Basic sensors only
Ideal for AVR boards with 32KB flash

Standard Setup

~200KB Flash
Sensors + basic modules
Suitable for ESP8266 and ESP32

Full-Featured Setup

~500KB+ Flash
All modules enabled
ESP32 with 4MB+ flash

Platform Memory Specifications

ESP32 (520KB RAM, 4MB Flash)

// You can afford to enable many modules
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_BME680_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_SENSOR_ANALOG_V2
#define ENABLE_MODULE_WIFI_HANDLER_V2
#define ENABLE_MODULE_MQTT_MANAGER
#define ENABLE_MODULE_FIREBASE_RTDB_V3
#define ENABLE_MODULE_PID_CONTROLLER
#define ENABLE_MODULE_FUZZY_MAMDANI
#define ENABLE_MODULE_SD_CARD_MODULE_ESP32
#define ENABLE_MODULE_FREE_RTOS_HANDLER
#include "Kinematrix.h"

// Estimated usage: ~350KB Flash, ~120KB RAM
// Still plenty of room left!

ESP8266 (80KB RAM, 4MB Flash)

// Be selective - RAM is the constraint
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_MODULE_WIFI_HANDLER_V2
#define ENABLE_MODULE_MQTT_MANAGER
#define ENABLE_MODULE_MOVING_AVERAGE_FILTER
#include "Kinematrix.h"

// Estimated usage: ~180KB Flash, ~45KB RAM
// Comfortable fit with room for runtime data
ESP8266 has only 80KB usable RAM. Stay under 50KB for application code to leave room for WiFi stack (~30KB) and runtime data.

AVR Arduino Uno (2KB RAM, 32KB Flash)

// Extreme minimalism required
#define ENABLE_SENSOR_ANALOG_V2
#define ENABLE_MODULE_MOVING_AVERAGE_FILTER
#include "Kinematrix.h"

// Estimated usage: ~8KB Flash, ~400 bytes RAM
// Very tight fit - test thoroughly!
Arduino Uno has only 2KB RAM total. Stay under 1KB for variables to leave room for the stack. Use Arduino Mega (8KB RAM) for more complex projects.

Real-World Memory Examples

Example 1: Minimal Environmental Monitor

Target: Arduino Uno (2KB RAM, 32KB Flash)
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_BME680_V2
#define ENABLE_MODULE_SERIAL_DEBUGGER_LITE
#include "Kinematrix.h"

SensorModuleV2 sensors;
BME680SensV2 environmental;

void setup() {
    Serial.begin(115200);
    environmental.setUpdateInterval(5000);
    sensors.addSensor("env", &environmental);
    sensors.init();
}

void loop() {
    sensors.update();
    Serial.printf("Temp: %.2f°C\n", environmental.getTemperature());
    delay(1000);
}
Memory Analysis:
  • Flash: ~12KB (37% of 32KB)
  • RAM: ~850 bytes (42% of 2KB)
  • ✅ Fits comfortably on Arduino Uno

Example 2: WiFi Sensor Node

Target: ESP8266 (80KB RAM, 4MB Flash)
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_SENSOR_ANALOG_V2
#define ENABLE_MODULE_WIFI_HANDLER_V2
#define ENABLE_MODULE_MQTT_MANAGER
#define ENABLE_MODULE_DATETIME_NTP_V2
#define ENABLE_MODULE_MOVING_AVERAGE_FILTER
#include "Kinematrix.h"

// Multi-sensor WiFi node with MQTT
Memory Analysis:
  • Flash: ~280KB (7% of 4MB)
  • RAM: ~48KB (60% of 80KB)
  • ✅ Reasonable fit with WiFi stack overhead

Example 3: Full IoT Hub

Target: ESP32 (520KB RAM, 4MB Flash)
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_BME680_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_SENSOR_ANALOG_V2
#define ENABLE_MODULE_WIFI_HANDLER_V2
#define ENABLE_MODULE_MQTT_MANAGER
#define ENABLE_MODULE_FIREBASE_RTDB_V3
#define ENABLE_MODULE_FIREBASE_FIRESTORE_V3
#define ENABLE_MODULE_SD_CARD_MODULE_ESP32
#define ENABLE_MODULE_PID_CONTROLLER
#define ENABLE_MODULE_FUZZY_MAMDANI
#define ENABLE_MODULE_FREE_RTOS_HANDLER
#define ENABLE_MODULE_OLED_MENU
#define ENABLE_MODULE_SERIAL_DEBUGGER_V2
#include "Kinematrix.h"

// Full-featured IoT hub with cloud, storage, and HMI
Memory Analysis:
  • Flash: ~580KB (14% of 4MB)
  • RAM: ~185KB (35% of 520KB)
  • ✅ Plenty of room for expansion

Module Size Reference

Lightweight Modules (<5KB each)

#define ENABLE_MODULE_I2C_SCANNER              // ~2KB
#define ENABLE_MODULE_SERIAL_HARD              // ~1KB
#define ENABLE_MODULE_MOVING_AVERAGE_FILTER    // ~2KB
#define ENABLE_MODULE_PID                      // ~4KB
#define ENABLE_SENSOR_ANALOG_V2                // ~3KB

Medium Modules (5-20KB each)

#define ENABLE_MODULE_SERIAL_DEBUGGER_LITE     // ~8KB
#define ENABLE_MODULE_PID_CONTROLLER           // ~12KB
#define ENABLE_MODULE_FUZZY_MAMDANI            // ~15KB
#define ENABLE_MODULE_OLED_MENU                // ~18KB
#define ENABLE_SENSOR_MODULE_V2                // ~10KB
#define ENABLE_SENSOR_BME680_V2                // ~14KB

Heavy Modules (20KB+ each)

#define ENABLE_MODULE_WIFI_HANDLER_V2          // ~35KB
#define ENABLE_MODULE_MQTT_MANAGER             // ~45KB
#define ENABLE_MODULE_FIREBASE_RTDB_V3         // ~85KB
#define ENABLE_MODULE_FIREBASE_FIRESTORE_V3    // ~95KB
#define ENABLE_MODULE_SERIAL_DEBUGGER_V2       // ~25KB
#define ENABLE_ADDONS_AUTOLIGHT_V3             // ~120KB
These are approximate sizes for Flash memory. RAM usage depends on runtime behavior and buffer allocations.

Optimization Strategies

Strategy 1: Choose Lightweight Variants

Many modules have lightweight alternatives:
// Heavy version (25KB)
#define ENABLE_MODULE_SERIAL_DEBUGGER_V2

// Lightweight version (8KB) - prefer this for constrained platforms
#define ENABLE_MODULE_SERIAL_DEBUGGER_LITE
// Heavy version (85KB)
#define ENABLE_MODULE_FIREBASE_RTDB_V3

// Lightweight alternative (45KB)
#define ENABLE_MODULE_MQTT_MANAGER  // Use MQTT instead of Firebase

Strategy 2: Use Conditional Compilation

Enable modules only when needed:
// Development build - enable debugging
#ifdef DEBUG_BUILD
#define ENABLE_MODULE_SERIAL_DEBUGGER_V2
#endif

// Production build - no debugging overhead
#ifdef PRODUCTION_BUILD
#undef ENABLE_MODULE_SERIAL_DEBUGGER_V2
#endif

#include "Kinematrix.h"

Strategy 3: Minimize Sensor Count

// Bad: Enabling all sensors you might use
#define ENABLE_SENSOR_BME680_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_SENSOR_DS18B20
#define ENABLE_SENSOR_ANALOG_V2
#define ENABLE_SENSOR_MAX31865

// Good: Only enable sensors you're actually using
#define ENABLE_SENSOR_BME680_V2  // The one you need
#include "Kinematrix.h"

Strategy 4: Use NoDef Variant for Development

The NoDef (No Definition) variant includes only headers, not implementations:
// During development - explore APIs without compiling everything
#define ENABLE_MODULE_NODEF_PID_CONTROLLER
#define ENABLE_MODULE_NODEF_MQTT_MANAGER
#include "KinematrixModulesNoDef.h"  // Headers only!

// For production - compile only what you use
#define ENABLE_MODULE_PID_CONTROLLER
#include "Kinematrix.h"

Memory Profiling

Arduino IDE Method

After compilation, check the output:
Sketch uses 245760 bytes (58%) of program storage space. Maximum is 419840 bytes.
Global variables use 42384 bytes (51%) of dynamic memory, leaving 39536 bytes for local variables. Maximum is 81920 bytes.
Analysis:
  • Flash: 245KB / 410KB (58%) ✅ OK
  • RAM: 42KB / 80KB (51%) ⚠️ Monitor closely

PlatformIO Method

pio run --target upload
Output:
RAM:   [======    ]  52.1% (used 42780 bytes from 81920 bytes)
Flash: [=====     ]  58.5% (used 245760 bytes from 419840 bytes)

Runtime Monitoring (ESP32/ESP8266)

void setup() {
    Serial.begin(115200);
    
    #ifdef ESP32
    Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
    Serial.printf("Heap size: %d bytes\n", ESP.getHeapSize());
    #endif
    
    #ifdef ESP8266
    Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
    #endif
}

void loop() {
    // Monitor heap over time
    static unsigned long lastCheck = 0;
    if (millis() - lastCheck > 10000) {
        Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
        lastCheck = millis();
    }
}

Advanced Optimization Techniques

Use PROGMEM for Constants (AVR/ESP8266)

// Bad: Wastes precious RAM
const char* errorMessages[] = {
    "Sensor initialization failed",
    "WiFi connection timeout",
    "MQTT broker unreachable"
};

// Good: Stores in Flash, not RAM
const char msg1[] PROGMEM = "Sensor initialization failed";
const char msg2[] PROGMEM = "WiFi connection timeout";
const char msg3[] PROGMEM = "MQTT broker unreachable";

const char* const errorMessages[] PROGMEM = {msg1, msg2, msg3};

Use F() Macro for Serial Strings

// Bad: Copies string to RAM first
Serial.println("Temperature: ");

// Good: Reads directly from Flash
Serial.println(F("Temperature: "));

Reduce Buffer Sizes

// Default - large buffers
MQTTManager mqtt;
mqtt.setBufferSize(2048);  // 2KB buffer

// Optimized - smaller buffers for constrained platforms
#ifdef ESP8266
mqtt.setBufferSize(512);   // 512 bytes - still functional
#endif

Memory Usage Guidelines

1

Start Minimal

Begin with the absolute minimum modules needed. Add more as you verify available memory.
2

Profile Early

Check memory usage after adding each module. Don’t wait until the end.
3

Leave Headroom

Keep at least 30% RAM free for:
  • Stack growth
  • Runtime allocations
  • WiFi/networking buffers
4

Test Under Load

Memory usage can spike during WiFi connections, MQTT publishing, or JSON parsing.

Platform-Specific Guidelines

ESP32 (520KB RAM)

Safe Limits:
  • Flash: Up to 3.5MB (leave room for OTA updates)
  • RAM: Keep under 350KB for application
Recommendations:
  • You can enable 15-20 modules comfortably
  • No need to optimize aggressively
  • Focus on feature richness over size
  • Enable full debugging during development

Troubleshooting Memory Issues

Likely cause: Stack overflow or heap corruptionSolutions:
  • Reduce number of enabled modules
  • Decrease buffer sizes
  • Remove large local variables
  • Monitor free heap during runtime
Likely cause: Too many modules for Flash sizeSolutions:
  • Disable unused modules
  • Use lightweight module variants
  • Check if you’re including modules twice
  • Verify board selection in IDE
Likely cause: Not enough free heap for WiFi stackSolutions:
  • Reduce application RAM usage below 50KB
  • Free memory before WiFi.begin()
  • Avoid allocations during WiFi operations
  • Consider ESP32 if WiFi + features needed

See Also

Build docs developers (and LLMs) love