maximkulkin / esp-homekit-demo

Demo of Apple HomeKit accessory server library
MIT License
808 stars 233 forks source link

Window curtain Core Panic #232

Closed konifer44 closed 5 years ago

konifer44 commented 5 years ago

Hey, Im running Window Curtain program on ESP32. Everything seems to work until I push open/close/choose position on slider on my iPhone. Then:

HomeKit: [Client 56] Update Characteristics Update target position to: 100 Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception) Debug exception reason: BREAK instr Core 1 register dump: PC : 0x40081e24 PS : 0x00000016 A0 : 0x40080306 A1 : 0x3ffc6140
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x4008c40b A5 : 0x3ffbc9c0
A6 : 0x00050023 A7 : 0x3ffb40d4 A8 : 0x00000000 A9 : 0x3ffb0c60
A10 : 0x00000001 A11 : 0x00060f23 A12 : 0x8008aa94 A13 : 0x3ffbc9b0
A14 : 0x00000003 A15 : 0x00060023 SAR : 0x0000001f EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000

ELF file SHA256: 37e5580a31a43eb64f3edd1b7adbc38d27ac18c051101f530d599770fe9b7e80

Backtrace: 0x40081e21:0x3ffc6140 0x40080303:0x03649c50 |<-CORRUPTED

Rebooting...

Any ideas ?

maximkulkin commented 5 years ago

Feels like either memory corruption or hardware problem. Can you post your code?

konifer44 commented 5 years ago

I suppose there is some error with "vTaskResume(updateStateTask);" Now I Have this error:

>>> HomeKit: [Client 59] Update Characteristics
Update target position to: 100
Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x3ffc6130  PS      : 0x00050033  A0      : 0x3ffc6130  A1      : 0x3ffc6120  
A2      : 0x40137630  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000  
A6      : 0x400d296c  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x00000000  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000000  EXCCAUSE: 0x00000014  
EXCVADDR: 0x3ffc6130  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

ELF file SHA256: 89d1c312e8ee672d5c9c8a63a9eb0575921262ad963946d2649cb39aa461e9ef

Backtrace: 0x3ffc612d:0x3ffc6120 |<-CORRUPTED

Rebooting...
ets Jun  8 2016 00:22:57'

Code:

#include "string.h"
#include <esp_event_loop.h>
#include <esp_log.h>
#include <esp_wifi.h>
#include <nvs_flash.h>
#include <stdio.h>
#include <stdlib.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "wifi.h"
#include <homekit/characteristics.h>
#include <homekit/homekit.h>
#include "driver/mcpwm.h"
#include "driver/pcnt.h"
#include "esp_attr.h"
#include "freertos/queue.h"
#include "soc/mcpwm_periph.h"
#include "soc/rtc.h"

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define POSITION_OPEN 100
#define POSITION_CLOSED 0
#define POSITION_STATE_CLOSING 0
#define POSITION_STATE_OPENING 1
#define POSITION_STATE_STOPPED 2
#define ESP_INTR_FLAG_DEFAULT 0
TaskHandle_t updateStateTask;
homekit_characteristic_t current_position;
homekit_characteristic_t target_position;
homekit_characteristic_t position_state;
homekit_accessory_t *accessories[];

void update_state()
{
    while (true)
    {
        uint8_t position = current_position.value.int_value;
        int8_t direction = position_state.value.int_value == POSITION_STATE_OPENING ? 1 : -1;
        int16_t newPosition = position + direction;

        printf("position %u, target %u\n", newPosition, target_position.value.int_value);

        current_position.value.int_value = newPosition;
        homekit_characteristic_notify(&current_position, current_position.value);

        if (newPosition == target_position.value.int_value)
        {
            printf("reached destination %u\n", newPosition);
            position_state.value.int_value = POSITION_STATE_STOPPED;
            homekit_characteristic_notify(&position_state, position_state.value);
            vTaskSuspend(updateStateTask);
            //return;
        }

        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

void on_wifi_ready();
esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch (event->event_id)
    {
    case SYSTEM_EVENT_STA_START:
        printf("STA start\n");
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        printf("WiFI ready\n");
        on_wifi_ready();
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        printf("STA disconnected\n");
        esp_wifi_connect();
        break;
    default:
        break;
    }
    return ESP_OK;
}
static void wifi_init()
{
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PASSWORD,
        },
    };

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

void update_state_init()
{
    xTaskCreate(update_state, "UpdateState", 256, NULL, tskIDLE_PRIORITY, &updateStateTask);
    vTaskSuspend(updateStateTask);
}

void window_covering_identify(homekit_value_t _value)
{
    printf("Curtain identify\n");
}

void on_update_target_position(homekit_characteristic_t *ch, homekit_value_t value, void *context);

homekit_characteristic_t current_position = {
    HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_POSITION(POSITION_CLOSED)};

homekit_characteristic_t target_position = {
    HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_POSITION(POSITION_CLOSED, .callback = HOMEKIT_CHARACTERISTIC_CALLBACK(on_update_target_position))};

homekit_characteristic_t position_state = {
    HOMEKIT_DECLARE_CHARACTERISTIC_POSITION_STATE(POSITION_STATE_STOPPED)};

homekit_accessory_t *accessories[] = {
    HOMEKIT_ACCESSORY(.id = 1, .category = homekit_accessory_category_window_covering, .services = (homekit_service_t *[]){HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics = (homekit_characteristic_t *[]){HOMEKIT_CHARACTERISTIC(NAME, "Window blind"), HOMEKIT_CHARACTERISTIC(MANUFACTURER, "MNK"), HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "001"), HOMEKIT_CHARACTERISTIC(MODEL, "MyCurtain"), HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"), HOMEKIT_CHARACTERISTIC(IDENTIFY, window_covering_identify), NULL}), HOMEKIT_SERVICE(WINDOW_COVERING, .primary = true, .characteristics = (homekit_characteristic_t *[]){HOMEKIT_CHARACTERISTIC(NAME, "Window blind"), &current_position, &target_position, &position_state, NULL}), NULL}),
    NULL};

void on_update_target_position(homekit_characteristic_t *ch, homekit_value_t value, void *context)
{
    printf("Update target position to: %u\n", target_position.value.int_value);
    if (target_position.value.int_value == current_position.value.int_value)
    {
        printf("Current position equal to target. Stopping.\n");
        position_state.value.int_value = POSITION_STATE_STOPPED;
        homekit_characteristic_notify(&position_state, position_state.value);
        vTaskSuspend(updateStateTask);
    }
    else
    {
        position_state.value.int_value = target_position.value.int_value > current_position.value.int_value
                                             ? POSITION_STATE_OPENING
                                             : POSITION_STATE_CLOSING;

        homekit_characteristic_notify(&position_state, position_state.value);
        update_state();
        vTaskResume(updateStateTask);
    }
}

homekit_server_config_t config = {
    .accessories = accessories,
    .password = "111-11-111"};
void on_wifi_ready() { homekit_server_init(&config); }

void app_main(void)
{
    // Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    wifi_init();
    update_state_init();
}
skanico commented 5 years ago

Maybe have a look at this

skanico commented 5 years ago

If you want, I made something for my 5 blinds with ESP32 (code is not nice, because I made that a few days before going on vacation... it needs some tuning).

It also works with physical buttons.

Archive.zip

skanico commented 5 years ago

If you want to keep your code, you should replace 256 by a higher value (2048?) in xTaskCreate. This is a difference between ESP32 and ESP8266

konifer44 commented 5 years ago

If you want to keep your code, you should replace 256 by a higher value (2048?) in xTaskCreate. This is a difference between ESP32 and ESP8266

YOU ARE GENIUS :D it's working

konifer44 commented 5 years ago

Thanks a lot! Closing.