跳到主要内容

Firmware FAQ

信息

If you have any questions about firmware development, please contact esp-rainmaker-support@espressif.com with a Firmware tag.

Provisioning, Wi‑Fi, Claiming & Factory Reset

How do I reset my board to factory defaults?

You can reset your board to factory defaults using any of these methods:

  1. Physical button (BOOT button) – If you are using the standard RainMaker examples, press and hold the BOOT button for more than 10 seconds to reset the board to factory defaults.

  2. System service (phone app) – If your firmware has System Service enabled with the Factory-Reset parameter, you can trigger a factory reset from the ESP RainMaker phone app. Open the device settings and use the Factory Reset option. The System Service exposes Reboot, Factory-Reset, and Wi-Fi-Reset parameters that can be triggered remotely from the app when the device is online.

For details on implementing factory reset support in your firmware, see How do I reset my board to factory defaults? and System Service Usage.

  1. Serial console – If your firmware has the Serial Console enabled, connect via UART (e.g., idf.py monitor) and run reset-to-factory. The device will reset to factory defaults and reboot.

    If the console is not enabled and your board has no boot button, connect via USB/serial and run the following from your host terminal:

    esptool.py --port $ESPPORT erase_region 0x10000 0x6000

    Ensure $ESPPORT is set to the correct serial port (e.g., /dev/ttyUSB0 on Linux or COM3 on Windows). Note: The partition layout may vary by project; verify the NVS partition address and size in your project's partition table if this command does not work.

$ esptool.py --port $ESPPORT erase_region 0x10000 0x6000

Ensure that you have set the correct value of $ESPPORT, which is the serial port to which your board is connected.


How can I change Wi-Fi credentials on my device?

Reset the device to provisioning mode, then provision again from the phone app. You can use any of these methods:

  1. Physical button (BOOT button) – If you are using the standard RainMaker examples, press and hold the BOOT button for more than 3 seconds and release. The device enters provisioning mode (Wi-Fi credentials are cleared; RainMaker association is retained).

  2. System service (phone app) – If your firmware has System Service enabled with the Wi-Fi-Reset parameter, open the device in the ESP RainMaker phone app, go to Settings, and use the Wi-Fi Reset option. The device will clear Wi-Fi credentials and reboot into provisioning mode.

  3. RainMaker CLI – If the device is online and System Service is enabled, trigger Wi-Fi reset remotely:

    esp-rainmaker-cli setparams <node_id> --data '{"System":{"Wi-Fi-Reset":true}}'

    See RainMaker CLI User Guide and Parameter Management.

Optional (testing only): If the Serial Console is enabled, connect via UART (e.g., idf.py monitor) and run wifi-prov <ssid> [<passphrase>] to provision new Wi-Fi credentials directly. This is convenient for development but not suitable for end users.


Why does user-node association from ESP RainMaker keep failing?

If you see failures for "Confirming Node Association" or "Configuring Node Association" on the phone app and no errors on the device serial terminal, it most likely means the app and node are connected to different backends (e.g., different regions or public vs private RainMaker). The device MQTT credentials in the fctry partition determine which cloud endpoint the node connects to.

Ensure backend alignment:

  • Private deployments: Use the RainMaker Admin CLI to generate credentials and flash the fctry partition binary. Claiming is not available in private RainMaker. See Admin CLI User Guide and Firmware Custom Documentation.

  • Public Global or China deployments: If the fctry partition contains stale or incorrect credentials, erase it and claim again:

    • Option 1 – Serial console: If the Serial Console is enabled, run clear-claim-data to erase the fctry NVS partition and reboot, then claim via esp-rainmaker-cli: esp-rainmaker-cli claim $ESPPORT --addr <fctry_partition_address>
    • Option 2 – esptool: If the console is not enabled, erase the fctry partition from the host:
      esptool.py --port $ESPPORT erase_region <fctry_address> <fctry_size>
      Verify the fctry partition address and size in your project's partition table (e.g., 0x3FA000 and 0x6000 in common layouts).

Ensure the RainMaker phone app is using the correct region (Global vs China) and that you are logged into the same account used for claiming. See Claiming for the claiming workflow.


Challenge-response is a user-node mapping method that uses cryptographic challenge-response instead of shared secrets. During provisioning, the cloud sends a challenge to the phone app, which relays it to the device over BLE. The device signs the challenge with its credentials and returns the response; the app forwards it to the cloud for verification. Mapping completes before Wi-Fi credentials are sent—so the node is added to the user's account even before it connects to the network.

Why it is recommended:

  • More secure — No shared secret is exchanged; the device proves ownership cryptographically.
  • More reliable — Mapping does not depend on MQTT; the node does not need network connectivity.
  • Early mapping — The user sees the device in their account as soon as provisioning starts.
  • Simpler flow — No node-to-cloud MQTT step during mapping.

Enable via CONFIG_ESP_RMAKER_ENABLE_CHALLENGE_RESPONSE=y in menuconfig (enabled by default on most platforms). Requires ESP RainMaker iOS app v3.4.0+ or Android app v3.7.0+. The node must be claimed first. For details, see User-Node Mapping.


Can I use ESP RainMaker without Wi-Fi provisioning?

While Wi-Fi provisioning (BLE or SoftAP) is the recommended method, you can hardcode Wi-Fi credentials for testing:

wifi_config_t wifi_config = {
.sta = {
.ssid = "YOUR_SSID",
.password = "YOUR_PASSWORD",
},
};
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);

Warning: Hardcoding credentials is only suitable for development/testing. For production, always use provisioning.


My provisioning is failing. What could be the issue?

Common provisioning issues and solutions:

  1. BLE Provisioning:

    • Ensure Bluetooth is enabled on the phone
    • Check if BLE is properly initialized in firmware
    • Verify device name appears in the app's scan list
  2. SoftAP Provisioning:

    • Confirm the device creates a Wi-Fi AP with the expected name
    • Check if the phone can connect to the device's AP
    • Verify security settings (WPA2 is recommended)
  3. QR Code:

    • Ensure the QR code includes correct provisioning data
    • Verify the proof-of-possession (PoP) matches
  4. Firmware Logs: Enable provisioning logs:

    esp_log_level_set("wifi_prov_mgr", ESP_LOG_DEBUG);

How do I reset my device to factory settings?

Implement a factory reset handler in your firmware:

esp_err_t factory_reset_handler(void)
{
ESP_LOGI(TAG, "Factory reset triggered");

// Reset RainMaker
esp_rmaker_factory_reset();

// Reset Wi-Fi
esp_wifi_restore();

// Restart device
esp_restart();

return ESP_OK;
}

// Register the handler
esp_rmaker_system_service_enable(reset_reboot_config);

Users can trigger factory reset through:

  • Physical button press (if implemented)
  • System service in the phone app
  • CLI commands

For more details, see System Service Usage.


Account & Authentication

Is the login email address case sensitive?

Yes, the login email address is case sensitive. RainMaker does not make assumptions about how the email address should be formatted. For example, xyz@abc.com, Xyz@abc.com, and xyz@Abc.com are all treated as different accounts.


Connectivity, MQTT & Cloud Parameter Sync

Why does it take a long time for a device to appear offline?

ESP RainMaker devices connect to the cloud over MQTT, which uses keep-alive messages to detect if the connection is active. As per MQTT Specs v3.1.1, if the Keep Alive value is non-zero and the Server does not receive a Control Packet from the Client within one and a half times the Keep Alive time period, it must disconnect the Network Connection to the Client as if the network had failed.

In ESP RainMaker, the keep-alive time is 120 seconds. Therefore, it can take up to 180 seconds (3 minutes) for the server to detect that a device has disconnected. A smaller keep-alive value would enable faster detection, but is undesirable as it can result in unnecessary network traffic and cause frequent disconnect events when network strength is poor.

备注

Changing the keep-alive value is not recommended, but you can do so via CONFIG_ESP_RMAKER_MQTT_KEEP_ALIVE_INTERVAL in menuconfig if needed.


I got success message for set params, but it did not reflect on my device. What may have happened?

The device may have disconnected from the network. Due to the MQTT keep-alive behaviour, the backend can take up to 180 seconds to detect that a device has gone offline. During this window, the backend still considers the device online and reports success when you set parameters—even if the message never reached the device. Once the device reconnects, it will sync with the cloud and reflect the last known state. If the parameter change was lost, set it again when the device is back online.


How can I ensure that my device always gets a param update even if it is offline when I trigger it?

If your use case requires updating parameters even when the device is offline, you have two options:

1. Enable CONFIG_ESP_RMAKER_MQTT_PERSISTENT_SESSION – The node will receive any messages it missed if it reconnects within 1 hour. This 1-hour window is defined by AWS IoT and cannot be changed. Note that only messages sent before the device was marked offline (as per the keep-alive logic) will be delivered—messages sent after that are discarded by the backend. This can have unexpected consequences: the device may receive on/off or other operations at odd times if it had disconnected when those operations were triggered.

2. Use param updates via Command-Response – Added in v1.7.3 of the esp_rainmaker component. This lets you use regular set-params for day-to-day operations and Command-Response for scenes and schedules. Command-Response supports a timeout of up to 30 days, or -1 so that commands never time out. For details, see Command-Response Usage.


What is the command-response framework? How is it different from get/set params?

The Command-Response framework is an alternative to the set-params workflow for sending data from clients (phone app, CLI) to devices. With get/set params, commands are delivered in real time over MQTT—the device must be online, and there is no built-in way to get the status of a request or to queue commands for when the device comes back online.

Key differences:

FeatureGet/Set ParamsCommand-Response
DeliveryReal-time; device must be onlineCloud queues; device fetches when online
Offline supportMessage lost if device offlineRequest stored; executed when device connects
Request statusFire-and-forget; no explicit statusQuery status (requested, in_progress, success, timed_out, failure)
ValiditySent once, delivered or droppedConfigurable timeout (e.g. up to 30 days or never expire)
Access controlParameter-levelUser-role aware (super admin, primary, secondary)

Typical use cases: Scenes and schedules (so they run even if the device was offline when triggered), device state recovery after power loss (device queries last command from cloud), and any flow where you need reliable delivery or request status. Enable via CONFIG_ESP_RMAKER_CMD_RESP_ENABLE=y. For details, see Command-Response and Command-Response Usage.


Parameters, Attributes, Time-Series & Phone App

Why am I unable to fetch time-series values for a given parameter?

If you are publishing time-series data but the query returns no results, check the following:

  1. Parameter created with PROP_FLAG_SIMPLE_TIME_SERIES — Confirm that the parameter was initialized with PROP_FLAG_SIMPLE_TIME_SERIES when creating it. Without this flag, the parameter will not be treated as a time-series parameter and data will not be stored for historical queries.

  2. Parameter name format for querying — When fetching time-series data via the API, use the full parameter name in the format <DeviceName>.<ParamName>. For example, use Sensor.Temperature, not just Temperature. The device and parameter names must match your node configuration exactly.

  3. Time service enabled — Confirm that the time service is enabled in your firmware. Time-series values are reported only if the device has obtained network time from SNTP. Without valid timestamps, the data may not be stored or returned correctly.

  4. Time window in the API — Ensure you are passing the correct time window (start and end timestamps) in your query. Data is returned only for the specified range; if the window is wrong or in the future, the result will be empty.

  5. SNTP sync — Time-series data depends on network time. If the device has not synced with SNTP (e.g., shortly after boot or with no internet), reported values may lack valid timestamps. Wait for time sync before expecting data to appear in queries.


Can I use custom device types instead of standard types?

Yes. Standard types (e.g., Switch, LightBulb, Fan) are helpers that provide better default integration with phone apps and voice assistants. You can create fully custom device types and parameters for any use case (e.g., soil moisture, water level, air cooler).

Create a custom device:

esp_rmaker_device_t *device = esp_rmaker_device_create("Air Cooler", "my.device.air-cooler", NULL);
esp_rmaker_device_add_cb(device, write_cb, NULL);

/* Add parameters with esp_rmaker_param_create(), bounds, UI types */
esp_rmaker_param_t *power_param = esp_rmaker_power_param_create("Power", true);
esp_rmaker_device_add_param(device, power_param);
esp_rmaker_device_assign_primary_param(device, power_param);

/* Add custom params: toggle, slider, dropdown */
esp_rmaker_param_t *speed = esp_rmaker_param_create("Speed", "esp.param.range",
esp_rmaker_int(3), PROP_FLAG_READ | PROP_FLAG_WRITE);
esp_rmaker_param_add_ui_type(speed, ESP_RMAKER_UI_SLIDER);
esp_rmaker_param_add_bounds(speed, esp_rmaker_int(0), esp_rmaker_int(5), esp_rmaker_int(1));
esp_rmaker_device_add_param(device, speed);

esp_rmaker_node_add_device(node, device);

For details, see Custom Types & Standard Types.


What is the difference between parameters and attributes?

FeatureParametersAttributes
PurposeControl and monitor device stateStatic metadata
MutabilityRead and/or writeRead-only
ExamplesPower, Brightness, TemperatureSerial number, Firmware version
Synced via MQTTYes, updated dynamicallyNo, reported once at boot
Has UI type / boundsYesNo

Parameters are the live, controllable state (power on/off, brightness, sensor readings). They sync between device and cloud over MQTT and can be changed remotely.

Attributes are fixed metadata (e.g., serial number, firmware version) reported once as part of the node configuration. They describe the device or node and do not change during operation.


My parameter updates are not reflecting in the phone app. Why?

Common causes:

  1. Not reporting updates — After changing a parameter locally, you must call esp_rmaker_param_update_and_report(param, &val) (or Arduino param.updateAndReport(val)). If you only update an internal variable, the cloud and app won't see the change.

  2. Wrong use of write callback — Write callbacks run when the app/user writes a value. For sensor params (e.g., temperature), update from your loop using esp_rmaker_param_update_and_report(), not from the write callback.

  3. Wrong parameter name — The name passed to updateAndReportParam() must exactly match the parameter on the device. Check standard name macros (e.g., ESP_RMAKER_DEF_TEMPERATURE_NAME) for standard devices.

  4. Node config changed but not reported — If you add/remove params or change options at runtime, call esp_rmaker_report_node_details() so the app sees the new layout.

  5. Update rate too high — Avoid exceeding ~1 message per 5 seconds; MQTT budgeting can drop updates. For time-series params (2 messages each), stay under ~20 seconds between updates.

  6. Invalid device name — Avoid dots (.) in device names; they can cause backend parsing issues.

  7. App caching — Refresh the device list or restart the app; some bugs were fixed in newer app versions.


How do I implement time-series data logging?

Use Simple Time-Series to log and visualize historical parameter values (e.g., temperature, energy consumption). Add PROP_FLAG_SIMPLE_TIME_SERIES when creating the parameter:

esp_rmaker_param_t *temp_param = esp_rmaker_param_create(
"Temperature", ESP_RMAKER_PARAM_TEMPERATURE,
esp_rmaker_float(15.5),
PROP_FLAG_READ | PROP_FLAG_SIMPLE_TIME_SERIES);

Report data using esp_rmaker_param_update_and_report()—this updates both the live parameter value and the time-series record. For TS-only logging (no param update, no automations), use esp_rmaker_param_report_simple_ts_data(). The cloud stores the data; it can be viewed in the phone app or queried via APIs. For more information, see Time-Series Data Usage.


OTA (Over-the-Air Updates)

How do I perform OTA updates for my devices?

Enable OTA with a single call (recommended):

esp_rmaker_ota_enable_default();

This uses OTA over topics, the default server certificate, and the default callback. For custom config:

esp_rmaker_ota_config_t ota_config = {
.server_cert = ESP_RMAKER_OTA_DEFAULT_SERVER_CERT,
};
esp_rmaker_ota_enable(&ota_config, OTA_USING_TOPICS);

Key APIs (only for advanced use cases): esp_rmaker_ota_fetch() to query for pending OTA, esp_rmaker_ota_report_status() for progress, esp_rmaker_ota_mark_valid() / esp_rmaker_ota_mark_invalid() for rollback support. Ensure project name and firmware version are correctly set—the cloud matches by project name and version. OTA can be triggered from the Dashboard. For details, see OTA Firmware Upgrades.


What could cause an OTA failure with reason "ESP HTTPS OTA Begin failed"?

The most likely cause is memory allocation failure. HTTPS-based OTA requires an additional TLS connection and buffers, which consume significant heap. If free heap is too low at OTA start, the HTTPS OTA begin can fail.

1. Optimize memory usage — See My device is running out of memory. How can I optimize? for ways to reduce your project's heap consumption (log verbosity, PSRAM, disabling unused features, etc.).

2. Use MQTT OTA instead — MQTT OTA uses the same MQTT channel as RainMaker instead of opening a separate HTTPS connection, which saves RAM. Available in esp_rainmaker component v1.6.4 and later. Enable via CONFIG_ESP_RMAKER_OTA_USE_MQTT=y in menuconfig (ESP RainMaker ConfigESP RainMaker OTA ConfigOTA Update Protocol TypeMQTT). MQTT OTA may be slightly slower but avoids the extra heap pressure from HTTPS. See the esp_rainmaker changelog for details.


How to improve reliability of OTA Firmware Upgrades?

Keep esp_rainmaker up to date and use these options, added across releases:

  • v1.6.0OTA retry on failure: If OTA fails, the component retries multiple times (CONFIG_ESP_RMAKER_OTA_MAX_RETRIES, default 3) and schedules another OTA fetch after all retries fail (CONFIG_ESP_RMAKER_OTA_RETRY_DELAY_MINUTES). OTA fetch also monitors publish acknowledgement and retries if the otafetch message fails.

  • v1.6.4MQTT OTA: Use CONFIG_ESP_RMAKER_OTA_USE_MQTT=y to fetch the OTA image over MQTT instead of HTTPS, saving RAM and avoiding extra TLS connections. May be slightly slower but improves reliability on memory-constrained devices.

  • v1.7.2OTA resumption: Resume download from the last position instead of restarting. Requires backend v3.0.0+ and ESP-IDF v5.5+. The device checks MD5 of consecutive chunks; if the same, download continues; if different, it restarts.

  • v1.9.0Rollback status reporting: Enable CONFIG_ESP_RMAKER_OTA_ROLLBACK_REPORT_FAILED so that when a rollback occurs due to MQTT timeout, the rolled-back firmware reports failed instead of rejected, giving the cloud accurate status. Use with caution—see the changelog for caveats.

For full details, see the esp_rainmaker changelog.


Local Control & Offline Operation

How can I implement local control for my devices?

ESP RainMaker uses mDNS-based discovery and HTTP-based control so devices can be controlled on the local network without going through the cloud. This is faster and works offline (after initial provisioning).

Enable in sdkconfig:

  • CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE=y
  • CONFIG_ESP_RMAKER_LOCAL_CTRL_SECURITY_1=y (recommended)

Once enabled, a Local Control service is automatically added to the node. Devices appear as "Reachable on WLAN" in the phone app when on the same network. No extra firmware code is needed beyond enabling the options. You can also use the CLI with --local --pop <pop_value> for local get/set. For details, see Local Control Usage and Local Control Service.


Can a RainMaker device work without internet?

Yes, to a limited extent. Local Control lets you control devices on the same Wi‑Fi network without internet access—the phone app discovers devices via mDNS and sends commands over HTTP on the local network. This works after initial provisioning, even when the cloud is unreachable. See How can I implement local control for my devices? for setup.

Schedules also continue to work offline. Once the device has obtained time from SNTP (which requires internet at least once after boot or after a long offline period), scheduled commands run locally on the device. The device uses its internal RTC to fire schedules at the correct times, so schedules keep working even when the device is disconnected from the cloud. For scheduling setup, see How do I implement scheduling in my firmware?.


Time, Timezone & Scheduling

Can RainMaker firmware handle timezones and daylight savings offset?

Yes. ESP RainMaker handles timezones and Daylight Saving Time (DST) via the Time Service. UTC is obtained via SNTP; RainMaker then converts to local time using the configured timezone and applies DST rules automatically. Schedules use this local time, so they remain correct across DST changes.

Configure timezone in firmware:

  • Location string (recommended—includes DST rules):
    esp_rmaker_time_set_timezone("America/Los_Angeles");
  • POSIX TZ string:
    esp_rmaker_time_set_timezone_posix("PST8PDT,M3.2.0,M11.1.0");
  • Build-time default: CONFIG_ESP_RMAKER_DEF_TIMEZONE="Asia/Shanghai" in menuconfig

Runtime changes from apps: Enable esp_rmaker_timezone_service_enable() so the node exposes TZ and TZ-POSIX parameters. The phone app can set timezone based on user account settings; values are stored in NVS and survive reboot.

To use timezone and DST correctly: (1) enable time sync, (2) set timezone, (3) optionally enable the timezone service for app-driven updates, (4) enable scheduling if needed. For more details, see Time Service Usage.

信息

Time service and timezone handling are enabled by default in all RainMaker examples. The phone apps set the node's timezone internally to match the user's timezone immediately after provisioning. You can view the configured timezone on the node details page in the app.


How do I implement scheduling in my firmware?

ESP RainMaker has built-in scheduling support. To enable it:

  1. Enable time service (required for scheduling):

    esp_rmaker_time_service_enable();
  2. Enable scheduling:

    esp_rmaker_schedule_enable();

Users can then create schedules through the phone app without additional firmware code. The firmware will automatically receive and execute scheduled commands.

For advanced usage, see Scheduling Usage.


How do I handle timezone for my devices?

ESP RainMaker provides automatic timezone management:

  1. Enable time service:

    esp_rmaker_time_service_enable();
  2. Get current time:

    time_t now;
    time(&now);
    struct tm timeinfo;
    localtime_r(&now, &timeinfo);

The timezone is automatically set based on the user's account settings in the phone app.

For more details, see Time Service Usage.


Security, Signing & Deployment

How do I migrate from public to private deployment?

Firmware logic stays largely the same. Main changes:

  1. Contact Espressif — Private RainMaker is not self-service. Reach out to esp-rainmaker-support@espressif.com or sales@espressif.com.

  2. Replace credentials — Claiming is not available in private deployments. Use the RainMaker Admin CLI to generate and register credentials. You can use pre-provisioned modules from Espressif or generate unique binaries per device.

  3. Disable claiming in sdkconfig:

    CONFIG_ESP_RMAKER_ASSISTED_CLAIM=n
    CONFIG_ESP_RMAKER_SELF_CLAIM=n
  4. Point CLI/Apps to private — Configure RainMaker CLI and phone apps to use your private deployment's API base URL.

For details, see Public vs Private RainMaker and Firmware Custom Documentation.


How do I implement secure signing for production devices?

Secure signing ensures that only authenticated firmware can be deployed to your devices.

Key steps:

  1. Enable secure boot in your ESP-IDF project
  2. Configure signing keys in the RainMaker Dashboard
  3. Sign firmware images before OTA deployment

For a complete implementation guide, see:


How do I implement secure signing for production devices?

Secure signing ensures that only authenticated firmware can be deployed to your devices.

Key steps:

  1. Enable secure boot in your ESP-IDF project
  2. Configure signing keys in the RainMaker Dashboard
  3. Sign firmware images before OTA deployment

For a complete implementation guide, see:


Memory, Logging & Debugging

How do I enable debug logging for my firmware?

ESP RainMaker uses the standard ESP-IDF logging system. You can control log verbosity at compile time or runtime:

Compile-time (menuconfig):

  • Component configLog outputDefault log verbosity — set to Debug or Verbose
  • Component configLog outputMaximum log verbosity — set higher if you want to enable verbose logs at runtime without rebuilding

Runtime (in code or via serial):

/* Set a specific RainMaker component to verbose */
esp_log_level_set("esp_rmaker_core", ESP_LOG_VERBOSE);
esp_log_level_set("esp_rmaker_mqtt", ESP_LOG_DEBUG);
esp_log_level_set("esp_rmaker_param", ESP_LOG_DEBUG);
esp_log_level_set("wifi_prov_mgr", ESP_LOG_DEBUG);

/* Or set all components globally */
esp_log_level_set("*", ESP_LOG_DEBUG);

Common RainMaker log tags: esp_rmaker_core, esp_rmaker_mqtt, esp_rmaker_param, esp_rmaker_schedule, esp_rmaker_scenes, esp_rmaker_local, esp_rmaker_connectivity, wifi_prov_mgr, app_wifi, app_network.


My device is running out of memory. How can I optimize?

If you encounter memory issues:

  1. Reduce log verbosity in production builds:

    CONFIG_LOG_DEFAULT_LEVEL_WARN=y
  2. Enable PSRAM if your chip supports it:

    CONFIG_SPIRAM_SUPPORT=y
  3. Disable unused features: Turn off unnecessary RainMaker features:

    /* Don't enable features you don't need */
    /* esp_rmaker_schedule_enable();
    * esp_rmaker_scenes_enable(); */
  4. Monitor memory usage:

    ESP_LOGI(TAG, "Free heap: %d", esp_get_free_heap_size());

    Or use the mem-dump serial console command when the console is enabled:

    >> mem-dump

    Description Internal SPIRAM
    Current Free Memory 136572 0
    Largest Free Block 114688 0
    Min. Ever Free Size 110896 0

For comprehensive memory optimization (static RAM, heap, lwIP, Wi-Fi buffers, Mbed TLS, PSRAM, IRAM), see the ESP-IDF Minimizing RAM Usage guide. Use idf.py size and idf.py size-components to analyze memory, and esp_get_free_heap_size() / esp_get_minimum_free_heap_size() for runtime heap monitoring.


Scenes, Cloud Access & Node Limits

How do I implement scenes in my firmware?

Scenes allow users to control multiple device parameters with a single action. To enable scenes:

esp_rmaker_scenes_enable();

No additional firmware code is required. Users can create and manage scenes through the phone app, and the firmware will automatically execute scene commands.

For advanced scene implementation, see Scenes Usage.


Can I access cloud data from my firmware?

ESP RainMaker is primarily designed for cloud-to-device communication. However, you can:

  1. Use Command-Response: Send requests to the cloud and receive responses:

    esp_rmaker_cmd_resp_enable();

    See Command-Response Usage.

  2. Subscribe to MQTT topics: For advanced use cases, subscribe to specific MQTT topics for custom data exchange.

  3. Use REST APIs: Your device can make HTTP requests to RainMaker's REST APIs (requires authentication).


What is the maximum number of devices a node can have?

A single ESP RainMaker node (physical device) can contain multiple devices (logical entities). The practical limit depends on:

  • Available memory on your chip
  • Number of parameters per device
  • Total MQTT payload size (must be under 128KB)

Typically, a node can support 5-10 devices comfortably. For complex product designs, consider memory and cloud communication implications.


Thread, Matter & Wi‑Fi Ecosystems

Can I use ESP RainMaker with Thread or Matter?

ESP RainMaker supports Wi-Fi, Thread, and Matter:

  • Matter: ESP RainMaker can integrate with Matter through ESP-Matter, allowing devices to work in both ecosystems.

  • Thread: ESP RainMaker supports Thread devices (e.g., ESP32-H2, ESP32-C6) via the RainMaker over Thread solution. Thread end devices connect to the RainMaker cloud through a Thread Border Router with NAT64 (e.g., Apple HomePod or Espressif ESP-Thread-BR). The RainMaker phone apps support provisioning Thread Border Routers and Thread end devices over BLE. See the thread_br and Matter+RainMaker Thread examples.

For Matter integration details, refer to the ESP-Matter documentation and RainMaker's Matter integration guides.


Can I use ESP RainMaker with Thread or Matter?

ESP RainMaker primarily uses Wi-Fi for connectivity. For Thread or Matter support:

  • Matter: ESP RainMaker can integrate with Matter through ESP-Matter, allowing devices to work in both ecosystems.
  • Thread: Not directly supported by RainMaker, which focuses on Wi-Fi-based IoT solutions.

For Matter integration details, refer to the ESP-Matter documentation and RainMaker's Matter integration guides.


Storage & Board-Specific Hardware

How can I save custom data to persistent storage?

Use ESP-IDF's NVS (Non-Volatile Storage) for saving custom data:

#include "nvs_flash.h"
#include "nvs.h"

// Write data
nvs_handle_t handle;
nvs_open("storage", NVS_READWRITE, &handle);
nvs_set_i32(handle, "key", value);
nvs_commit(handle);
nvs_close(handle);

// Read data
int32_t value;
nvs_open("storage", NVS_READONLY, &handle);
nvs_get_i32(handle, "key", &value);
nvs_close(handle);

ESP RainMaker also provides convenient wrappers for storing node information automatically.


Why is the RGB LED on my ESP32-S2-Saola-1 not working?

The ESP32-S2-Saola-1 board has the RGB LED connected to GPIO 18. However, a few earlier boards may have it on GPIO 17. Use CONFIG_APP_LED_GPIO to set the appropriate GPIO:

$ idf.py menuconfig
Example Configuration -> RGB LED GPIO -> 17

On this page