Common issues and solutions to help you debug your Akira applications.


πŸ“‘ Table of Contents


πŸ–₯️ Display Issues

Problem: Display Shows Nothing

Symptoms: Screen stays black after drawing

Possible Causes:

  1. Forgot to call akira_display_flush()
  2. Drawing outside screen bounds
  3. Using color 0x0000 on black background

Solutions:

// βœ… Always flush after drawing
akira_display_clear(0x0000);
akira_display_text(10, 10, "Hello", 0xFFFF);
akira_display_flush();  // DON'T FORGET THIS!

// βœ… Check your coordinates
int w, h;
akira_display_get_size(&w, &h);
printf("Display size: %dx%d\n", w, h);

// βœ… Use visible colors
akira_display_text(10, 10, "Text", 0xFFFF);  // White on black

Problem: Text is Garbled or Missing

Symptoms: Text appears corrupted or doesn’t show

Possible Causes:

  1. NULL or invalid string pointer
  2. String not null-terminated
  3. Text drawn outside visible area

Solutions:

// βœ… Ensure strings are null-terminated
char text[32];
strncpy(text, source, sizeof(text) - 1);
text[sizeof(text) - 1] = '\0';

// βœ… Validate string before drawing
if (text && text[0] != '\0') {
    akira_display_text(10, 10, text, 0xFFFF);
}

// βœ… Check coordinates are within bounds
if (x >= 0 && y >= 0 && x < width && y < height) {
    akira_display_text(x, y, text, color);
}

Problem: Display Flickers

Symptoms: Screen flashes or flickers rapidly

Possible Causes:

  1. Flushing too frequently
  2. Clearing entire screen every frame
  3. No frame rate limiting

Solutions:

// βœ… Limit frame rate
void render_loop() {
    while(1) {
        update_graphics();
        akira_system_sleep(16);  // ~60 FPS
        akira_process_events();
    }
}

// βœ… Only update changed regions
static int last_value = -1;
if (value != last_value) {
    akira_display_rect(x, y, w, h, 0x0000);
    draw_new_value(value);
    akira_display_flush();
    last_value = value;
}

Problem: Colors Look Wrong

Symptoms: Colors don’t match what you expected

Solutions:

// βœ… Use RGB565 format correctly
// Format: RRRR RGGG GGGB BBBB
// Red (5 bits): 0xF800
// Green (6 bits): 0x07E0
// Blue (5 bits): 0x001F

uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) {
    return ((r & 0xF8) << 8) |  // Red: 5 bits
           ((g & 0xFC) << 3) |  // Green: 6 bits
           (b >> 3);            // Blue: 5 bits
}

// Test your colors
akira_display_rect(0, 0, 10, 10, 0xF800);   // Red square
akira_display_rect(10, 0, 10, 10, 0x07E0);  // Green square
akira_display_rect(20, 0, 10, 10, 0x001F);  // Blue square
akira_display_flush();

⚑ Event Handling Problems

Problem: Callbacks Never Fire

Symptoms: Registered callbacks don’t get called

Possible Causes:

  1. Forgot to call akira_process_events()
  2. Callback not properly registered
  3. Wrong timer/GPIO/topic ID

Solutions:

// βœ… MUST call this in your main loop
while(1) {
    akira_process_events();  // This dispatches callbacks!
}

// βœ… Check registration return value
int result = akira_register_timer_callback(0, my_callback);
if (result != 0) {
    akira_log(0, "Failed to register callback!");
}

// βœ… Verify IDs are in valid range
if (timer_id >= 0 && timer_id < AKIRA_MAX_TIMERS) {
    akira_register_timer_callback(timer_id, callback);
}

Problem: Callback Gets Called Multiple Times

Symptoms: Same callback fires repeatedly for one event

Solutions:

// βœ… Unregister before re-registering
akira_unregister_timer_callback(0);
akira_register_timer_callback(0, new_callback);

// βœ… Check if already registered
static bool is_registered = false;
if (!is_registered) {
    akira_register_timer_callback(0, callback);
    is_registered = true;
}

Problem: Events Are Delayed or Slow

Symptoms: Callbacks fire later than expected

Solutions:

// ❌ BAD - blocks for 5 seconds
void on_button(uint32_t buttons) {
    akira_system_sleep(5000);  // DON'T DO THIS!
}

// βœ… GOOD - returns immediately
static bool action_pending = false;
void on_button(uint32_t buttons) {
    action_pending = true;  // Set flag, process later
}

void on_timer() {
    if (action_pending) {
        perform_long_operation();
        action_pending = false;
    }
}

πŸ“Š Sensor Reading Errors

Problem: Sensor Read Returns Error

Symptoms: akira_sensor_read() returns non-zero

Possible Causes:

  1. Sensor not connected
  2. Wrong sensor type
  3. Sensor needs initialization time
  4. Missing capability in manifest

Solutions:

// βœ… Add retry logic with delays
int read_sensor_with_retry(float *value) {
    for (int i = 0; i < 3; i++) {
        if (akira_sensor_read(SENSOR_TYPE_TEMP, value) == 0) {
            return 0;
        }
        akira_log(1, "Retry sensor read...");
        akira_system_sleep(100);
    }
    akira_log(0, "Sensor read failed after retries");
    return -1;
}

// βœ… Check sensor availability at startup
void test_sensors() {
    float dummy;
    if (akira_sensor_read(SENSOR_TYPE_TEMP, &dummy) == 0) {
        akira_log(2, "Temperature sensor OK");
    } else {
        akira_log(0, "Temperature sensor not available");
    }
}

Problem: Sensor Values Seem Wrong

Symptoms: Readings are unrealistic or constant

Solutions:

// βœ… Always initialize and check
float temp = 0.0;
if (akira_sensor_read(SENSOR_TYPE_TEMP, &temp) == 0) {
    if (temp >= -40.0 && temp <= 85.0) {  // Sanity check
        process_temperature(temp);
    } else {
        akira_log(1, "Temperature out of range");
    }
} else {
    akira_log(0, "Failed to read temperature");
}

// βœ… Don't read too frequently
#define MIN_SENSOR_INTERVAL_MS 1000
static uint64_t last_read = 0;

void read_if_ready() {
    uint64_t now = akira_system_uptime_ms();
    if (now - last_read >= MIN_SENSOR_INTERVAL_MS) {
        read_sensor();
        last_read = now;
    }
}

πŸ“‘ RF Communication Issues

Problem: RF Init Fails

Symptoms: akira_rf_init() returns error

Solutions:

// βœ… Check all possible chips
int init_any_rf() {
    const akira_rf_chip_t chips[] = {
        AKIRA_RF_CHIP_NRF24L01,
        AKIRA_RF_CHIP_CC1101,
        AKIRA_RF_CHIP_SX1276
    };

    for (int i = 0; i < sizeof(chips)/sizeof(chips[0]); i++) {
        if (akira_rf_init(chips[i]) == 0) {
            akira_log(2, "RF initialized!");
            return 0;
        }
    }

    akira_log(0, "No RF chip found");
    return -1;
}

// βœ… Deinit before reinit
akira_rf_deinit();
if (akira_rf_init(AKIRA_RF_CHIP_NRF24L01) == 0) {
    akira_log(2, "RF reinitialized");
}

Problem: Can’t Send/Receive RF Data

Symptoms: akira_rf_send() or akira_rf_receive() fails

Solutions:

// βœ… Configure RF properly
void setup_rf() {
    akira_rf_init(AKIRA_RF_CHIP_NRF24L01);
    akira_rf_set_frequency(2450000000);  // 2.45 GHz
    akira_rf_set_power(0);               // 0 dBm
    akira_log(2, "RF configured");
}

// βœ… Check packet size
#define MAX_RF_PACKET_SIZE 32

void send_packet(const uint8_t *data, size_t len) {
    if (len > MAX_RF_PACKET_SIZE) {
        akira_log(1, "Packet too large");
        return;
    }
    if (akira_rf_send(data, len) == 0) {
        akira_log(2, "Packet sent");
    } else {
        akira_log(0, "Send failed");
    }
}

// βœ… Use appropriate timeout
uint8_t buffer[64];
int len = akira_rf_receive(buffer, sizeof(buffer), 5000);
if (len > 0) {
    akira_log(2, "Packet received!");
} else if (len == 0) {
    akira_log(3, "Timeout - no packet");
} else {
    akira_log(0, "Receive error");
}

Problem: Poor RF Range

Symptoms: Communication only works at close range

Solutions:

// βœ… Increase transmit power
akira_rf_set_power(20);  // Maximum power (check chip specs)

// βœ… Check signal quality
int16_t rssi;
if (akira_rf_get_rssi(&rssi) == 0) {
    akira_log(2, "RSSI: %d dBm");
    if (rssi < -90) {
        akira_log(1, "Weak signal!");
    }
}

// βœ… Try different frequencies
void scan_frequencies() {
    uint32_t freqs[] = {2400000000, 2450000000, 2480000000};
    for (int i = 0; i < 3; i++) {
        akira_rf_set_frequency(freqs[i]);
        // Test communication...
    }
}

πŸ’Ύ Storage Problems

Problem: File Read/Write Fails

Symptoms: Storage operations return negative values

Solutions:

// βœ… Check if file exists before reading
int size = akira_storage_size("config.txt");
if (size >= 0) {
    char buffer[256];
    int bytes = akira_storage_read("config.txt", buffer, sizeof(buffer));
    if (bytes > 0) {
        akira_log(2, "Read successful");
    }
} else {
    akira_log(1, "File not found");
}

// βœ… Check write result
int bytes_written = akira_storage_write("data.txt", data, len);
if (bytes_written == len) {
    akira_log(2, "Write successful");
} else if (bytes_written < 0) {
    akira_log(0, "Write failed");
} else {
    akira_log(1, "Partial write");
}

Problem: Storage Full

Symptoms: Writes fail with -ENOMEM or similar

Solutions:

// βœ… Implement log rotation
void rotate_log() {
    int size = akira_storage_size("app.log");
    if (size > 10000) {  // 10KB limit
        akira_storage_delete("app.log.old");
        akira_storage_delete("app.log");
        akira_log(2, "Log rotated");
    }
}

// βœ… Clean up old files
void cleanup_old_files() {
    akira_storage_delete("temp.dat");
    akira_storage_delete("cache.bin");
    akira_log(2, "Cleanup complete");
}

🌐 Network Errors

Problem: HTTP Request Fails

Symptoms: akira_http_get() returns negative value

Solutions:

// βœ… Validate URL format
bool is_valid_url(const char *url) {
    return (strncmp(url, "http://", 7) == 0 ||
            strncmp(url, "https://", 8) == 0);
}

// βœ… Add retry logic
int http_get_with_retry(const char *url, uint8_t *buffer, size_t len) {
    for (int i = 0; i < 3; i++) {
        int result = akira_http_get(url, buffer, len);
        if (result > 0) {
            return result;
        }
        akira_log(1, "HTTP retry...");
        akira_system_sleep(1000);
    }
    return -1;
}

Problem: MQTT Messages Not Received

Symptoms: Callback never fires for subscribed topic

Solutions:

// βœ… Test subscription
int result = akira_mqtt_subscribe("test/topic", on_mqtt);
if (result == 0) {
    akira_log(2, "Subscribed successfully");
    const char *msg = "test";
    akira_mqtt_publish("test/topic", msg, strlen(msg));
} else {
    akira_log(0, "Subscribe failed");
}

// βœ… Use wildcard patterns correctly
akira_mqtt_subscribe("sensors/+/temp", on_mqtt);  // Any sensor
akira_mqtt_subscribe("sensors/#", on_mqtt);        // All sensor topics

πŸ’Ύ Memory Issues

Problem: Out of Memory Errors

Symptoms: Operations fail with -ENOMEM

Solutions:

// βœ… Use static allocation
static char buffer[1024];  // Instead of malloc

// βœ… Monitor memory usage
void check_memory() {
    size_t free = akira_system_free_memory();
    akira_log(2, "Free memory check");
    if (free < 1000) {
        akira_log(1, "Low memory!");
    }
}

// βœ… Limit buffer sizes
#define MAX_READINGS 100
static float readings[MAX_READINGS];

Problem: Stack Overflow

Symptoms: App crashes or behaves erratically

Solutions:

// ❌ BAD - large stack allocation
void process() {
    char huge[10000];  // Don't do this!
}

// βœ… GOOD - use static
void process() {
    static char buffer[10000];  // OK
}

// ❌ BAD - recursion
void recursive(int n) {
    recursive(n + 1);  // Stack overflow!
}

// βœ… GOOD - iteration
void iterative(int n) {
    for (int i = 0; i < n; i++) {
        // Process...
    }
}

πŸ”¨ Compilation Errors

Problem: Undefined Reference to akira_*

Symptoms: Linker errors for Akira functions

Solutions:

# βœ… Include akira_api.c in compilation
build.sh -o app.wasm main.c

Problem: Wrong WASM Output

Symptoms: Generated WASM doesn’t work

Solutions:

# βœ… Use correct flags for standalone WASM
build.sh -o app.wasm main.c

# βœ… Check WASM with wasm-objdump
wasm-objdump -x app.wasm

🐌 Performance Problems

Problem: App Runs Slow

Symptoms: Laggy UI, slow response

Solutions:

// βœ… Limit display updates
static uint64_t last_update = 0;
#define UPDATE_INTERVAL_MS 100

void maybe_update_display() {
    uint64_t now = akira_system_uptime_ms();
    if (now - last_update >= UPDATE_INTERVAL_MS) {
        update_display();
        last_update = now;
    }
}

// βœ… Move heavy work to timers
void on_button(uint32_t buttons) {
    flag_work_needed = true;  // Just set flag
}

void on_timer() {
    if (flag_work_needed) {
        do_heavy_calculation();
        flag_work_needed = false;
    }
}

// βœ… Profile your code
uint64_t start = akira_system_uptime_ms();
expensive_operation();
uint64_t elapsed = akira_system_uptime_ms() - start;
akira_log(3, "Operation timing logged");

πŸ” General Debugging Tips

Enable Verbose Logging

// Add at start of main()
akira_log(2, "App started");
akira_log(2, "Version: 1.0.0");

// Log important events
akira_log(2, "Sensor read complete");
akira_log(2, "Button pressed");

Add Debug Display

#ifdef DEBUG
void show_debug_overlay() {
    char dbg[64];

    snprintf(dbg, sizeof(dbg), "Mem:%zu",
             akira_system_free_memory());
    akira_display_text(200, 5, dbg, 0xF800);

    snprintf(dbg, sizeof(dbg), "Up:%llu",
             akira_system_uptime_ms() / 1000);
    akira_display_text(200, 20, dbg, 0xF800);
}
#endif

Test in Isolation

void test_display() {
    akira_display_clear(0xF800);  // Red screen
    akira_display_flush();
    akira_system_sleep(1000);
}

void test_sensors() {
    float temp;
    if (akira_sensor_read(SENSOR_TYPE_TEMP, &temp) == 0) {
        akira_log(2, "Sensor OK");
    }
}

int main(void) {
    test_display();
    test_sensors();
    // ...
}

Use Assertions

#define ASSERT(cond) \
    if (!(cond)) { \
        akira_log(0, "Assert failed: " #cond); \
        while(1); \
    }

void process_data(const char *data) {
    ASSERT(data != NULL);
    ASSERT(data[0] != '\0');
    // Process...
}

🎯 Debugging Checklist

Before asking for help, verify:

  • Logs enabled and checked
  • Return values checked
  • Memory usage reasonable
  • Callbacks registered correctly
  • akira_process_events() called in loop
  • Display flushed after drawing
  • Pointers validated
  • Bounds checked
  • Error handling present
  • Tested each component separately

πŸ“ž Getting Help

If you’re still stuck:

  1. Check the logs - Look for error messages
  2. Review the SDK API Reference - Verify correct usage
  3. Read Best Practices - Avoid common pitfalls
  4. Check System Troubleshooting - Build/flash issues
  5. Ask the community - Post on forums with error details


⬆ Back to Top


Copyright © 2025-2026 AkiraOS Project. Distributed under the Apache 2.0 License.