Skip to main content
Version: 0.0.x

Logging and Debugging - IoT SDK

When a call does not work on a device, the serial monitor is all you have. The SDK ships two log levels, and getting the noisy one requires two separate things: the debug logs must be compiled into the image, and they must be turned on.

Log levels

videosdk_set_log_mode() selects how much the SDK prints. Call it once, before init(), so it covers the join.

typedef enum {
VIDEOSDK_LOG_NORMAL = 0, // lifecycle, warnings and errors
VIDEOSDK_LOG_DEBUG, // adds periodic heartbeats and diagnostics
} videosdk_log_mode_t;

It only moves the SDK's own log tags. ESP-IDF and other components keep whatever level they were built with, which is CONFIG_LOG_DEFAULT_LEVEL.

Turning debug logs on

Pick the level in menuconfig and read it back in code, so you can flip verbosity without editing source:

d. VideoSDK Logging
|-> Log verbosity
|-> Normal (default)
|-> Debug
#if CONFIG_VIDEOSDK_LOG_MODE_DEBUG
videosdk_set_log_mode(VIDEOSDK_LOG_DEBUG);
#else
videosdk_set_log_mode(VIDEOSDK_LOG_NORMAL);
#endif
warning

Debug logs are only present in the image if the build allows that level. Keep this line in sdkconfig.defaults:

CONFIG_LOG_MAXIMUM_LEVEL_DEBUG=y

It costs a few KB of flash and turns nothing on by itself. Without it, selecting Debug prints nothing extra and it looks like the setting is broken.

Remember that sdkconfig.defaults is read only when no sdkconfig exists yet. If you add the line to a project you have already built, delete the generated sdkconfig and build again.

Reading the monitor

idf.py -p <PORT> monitor          # attach to a board that is already flashed
idf.py -p <PORT> flash monitor # flash, then attach

Exit the monitor with Ctrl+]. See Quick Start for how to find <PORT> on your machine.

A healthy audio join looks roughly like this, with 0 meaning RESULT_OK:

I (1180) IOT-SDK: [APP] Startup..
I (1190) IOT-SDK: [APP] IDF version: v5.4.2
I (4210) IOT-SDK: Device ID: esp32-a0b1c2d3e4f5
I (7480) IOT-SDK: init: 0
I (7910) IOT-SDK: startPublishAudio: 0
I (8020) IOT-SDK: startSubscribeAudio: 0

Any non-zero number is a result code. Look it up there before guessing: several of them describe a configuration problem rather than a network one.

note

startSubscribeAudio: 3004 or startSubscribeVideo: 3004 on a send-only board is DEVICE_NOT_SUPPORTED, which is expected, not a failure. See Supported Microcontrollers.

Checking memory

Several result codes mean an allocation failed rather than a network problem: MEMORY_ALLOC_FAILED (3003), PUBLISH_MEMORY_ALLOC_FAILED (3012), SUBSCRIBE_MEMORY_ALLOC_FAILED (3016), and the mutex and task-creation failures. When you see one, print what is actually left:

#include "esp_heap_caps.h"
#include "esp_system.h"

ESP_LOGI("IOT-SDK", "free heap: %u", (unsigned)esp_get_free_heap_size());
ESP_LOGI("IOT-SDK", "free internal: %u",
(unsigned)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
ESP_LOGI("IOT-SDK", "free PSRAM: %u",
(unsigned)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

If free PSRAM reads as 0, PSRAM is not actually enabled and every media buffer is competing for internal RAM. Check that CONFIG_SPIRAM, CONFIG_SPIRAM_MODE_OCT and CONFIG_SPIRAM_SPEED_80M survived into your sdkconfig, and that the board really has octal PSRAM. See Quick Start, Step 5.

API Reference

Got a Question? Ask us on discord