espressif / esp-zigbee-sdk

Espressif Zigbee SDK
Apache License 2.0
164 stars 28 forks source link

Read ADC data during light-sleep (TZ-611) #236

Open vedatbotuk opened 9 months ago

vedatbotuk commented 9 months ago

Answers checklist.

IDF version.

v5.3-dev-582-gab03c2ea13

esp-zigbee-lib version.

1.0.9

esp-zboss-lib version.

1.0.9

Espressif SoC revision.

ESP32-H2

What is the expected behavior?

Read ADC data during light-sleep

What is the actual behavior?

I would like to measure the battery voltage via ADC input. If I do not use sleep mode, it works. But if I use light sleep it does not work. grafik

Steps to reproduce.

  1. Step
  2. Step
  3. Step ...

More Information.

No response

chshu commented 9 months ago

I think the ADC operation during light sleep is not supported yet. You can acquire a sleep lock for the ADC operation, please try out the follow code:

esp_pm_lock_handle_t s_adc_lock;
esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "adc", &s_adc_lock);
esp_pm_lock_acquire(s_adc_lock);
// do the ADC operation here
esp_pm_lock_release(s_adc_lock);
vedatbotuk commented 9 months ago

No change. Unfortunately, this extension does not help either.

vedatbotuk commented 9 months ago

I am using two parallel tasks, could this be the reason?

diazmanuel commented 9 months ago

hello @chshu, I have the same problem as @vedatbotuk, I can't read the adc correctly, the only time the adc read is correct is when the read is done at the same time as the zigbee keepalive signal, then the problem is that the code you posted above does not work, it does not keep the chip awake to read

kelin6 commented 9 months ago

@vedatbotuk @diazmanuel In the esp-idf, the ADC light sleep retention feature for the esp32h2 has not been supported yet. As a result, ADC register backup and restoration are not supported. Therefore, after waking up, the ADC registers are not restored.

If you really need to use the ADC during light sleep, you can try the following approach: after waking up, reinitialize the ADC, read ADC data, deinitialize the ADC, and then go back to sleep.

vedatbotuk commented 9 months ago

@kelin6 , Do you know when this feature will be implemented? Is there a plan?

diazmanuel commented 9 months ago

hello @kelin6

If you really need to use the ADC during light sleep, you can try the following approach: after waking up, reinitialize the ADC, read ADC data, deinitialize the ADC, and then go back to sleep.

i already try that but sometimes works and sometimes not, will you add this feature ? in my case i dont need to read on the sleep state but i wish i could only initialize 1 time and the read locking the chip in the awake state.

kelin6 commented 9 months ago

@diazmanuel @vedatbotuk The ADC light sleep feature may take several months to be supported in ESP-IDF.

Based on the solution I previously provided, after waking up from sleep, reinitialize the ADC, read ADC data, and then deinitialize.

The following code is added to the Zigbee sleep section, and then esp_zb_sleep_now() is called:

......
      case ESP_ZB_COMMON_SIGNAL_CAN_SLEEP:
        ESP_LOGI(TAG, "Zigbee can sleep");
        esp_zb_sleep_now();

        adc_init_test();
        adc_read_test();
        adc_deinit_test();

        break;
......

The attachment includes the ADC's init, deinit, and read interfaces, with GPIO3 set as the default. sleep_adc.txt

agustinebrecht commented 9 months ago

Hello, @kelin6 I have the same problem as @diazmanuel @vedatbotuk. The solution you propose to measure after sleep in the zigbee handler is a problem and it still gives me the same result of 4081. I clarify that I am using the esp32H2 for a low energy product.

kelin6 commented 8 months ago

@agustinebrecht @diazmanuel @vedatbotuk For your convenience in testing, I am uploading my test code light_sleep.zip. Based on the esp-zigbee-sdk light sleep example, I have added ADC-related interfaces. The testing environment is as follows:

esp-idf: ab03c2ea1 esp-zigbee-sdk: 1.1.1 CHIP: ESP32H2 When GPIO3 is connected to 3.3V, the ADC read data is 3360. When GPIO3 is connected to GND, the ADC read data is 0.

image

Please use the test code I provided above for testing. If there are any other issues during testing, feel free to provide your test code for further analysis.

vedatbotuk commented 8 months ago

Thanks for your code @kelin6 . That works fine. I have another questions. If I want to read the GPIO pin during light sleep, it doesn't work properly either.

I use following code in void app_main(void)

gpio_set_direction(INPUT_PIN, GPIO_MODE_INPUT);
gpio_set_pull_mode(INPUT_PIN, GPIO_PULLUP_ONLY);

And I try to check the GPIO Input, if is up or down with a while loop.

gpio_get_level(INPUT_PIN)

I get wrong input while running light sleep. It trigers without any reason. I tried also after esp_zb_sleep_now();, but it did not work. Do you have any solution for that.

kelin6 commented 8 months ago

@vedatbotuk I am uploading my test code light_sleep.zip. Based on the esp-zigbee-sdk light sleep example, I have added GPIO get level related interfaces. The testing environment is as follows:

esp-idf: 0c47128 esp-zigbee-sdk: 1.2.0

CHIP: ESP32H2 When GPIO3 is connected to 3.3V, the gpio_get_level is 1. When GPIO3 is connected to GND, the gpio_get_level is 0.

image

vedatbotuk commented 7 months ago

In my case I need some sleep time, otherwise gpio_get_level(INPUT_PIN) does not work correct. In following out put you can see that.

I (12710) WATERLEAK_CHECK: Water detected
I (12760) WATERLEAK_CHECK: Water alarm released
I (18746) SIGNAL: Zigbee can sleep
I (26755) SIGNAL: Zigbee can sleep
I (26756) WATERLEAK_CHECK: Water detected
I (26806) WATERLEAK_CHECK: Water alarm released
I (34755) SIGNAL: Zigbee can sleep
I (34756) WATERLEAK_CHECK: Water detected
I (34806) WATERLEAK_CHECK: Water alarm released
I (42769) SIGNAL: Zigbee can sleep
I (42769) WATERLEAK_CHECK: Water detected
I (42820) WATERLEAK_CHECK: Water alarm released
I (50768) SIGNAL: Zigbee can sleep
I (50768) WATERLEAK_CHECK: Water detected
I (50818) WATERLEAK_CHECK: Water alarm released
I (65864) SIGNAL: Zigbee can sleep
I (68374) SIGNAL: Zigbee can sleep
I (71392) SIGNAL: Zigbee can sleep
I (71393) WATERLEAK_CHECK: Water detected
I (71443) WATERLEAK_CHECK: Water alarm released
I (77420) SIGNAL: Zigbee can sleep
I (85429) SIGNAL: Zigbee can sleep
I (85430) WATERLEAK_CHECK: Water detected
I (85480) WATERLEAK_CHECK: Water alarm released
I (93428) SIGNAL: Zigbee can sleep
I (93429) WATERLEAK_CHECK: Water detected

I just add some sleep time befor or after esp_zb_sleep_now() and then works fine.

    case ESP_ZB_COMMON_SIGNAL_CAN_SLEEP:
        ESP_LOGI(TAG_SIGNAL_HANDLER, "Zigbee can sleep");
         vTaskDelay(pdMS_TO_TICKS(100)); /*This sleep is necessary for the get_button()*/
         get_gpio_level();
        esp_zb_sleep_now();
        break;
kelin6 commented 7 months ago

@vedatbotuk Based on my code, it seems to be working fine. I'm not quite sure why you need to call vTaskDelay again.

Could you provide the simplest possible code based on our esp-zigbee-light sleep example that can reproduce the issue on your end? This will help us investigate further.

Drippin101 commented 7 months ago

how do you get the gpio level to show up in home assistant?

kelin6 commented 6 months ago

@Drippin101 You can try this: After waking up the device, read the GPIO level and send a custom cluster containing the GPIO level data to Home Assistant.

chshu commented 1 month ago

@vedatbotuk There were some fixes in the ADC retention after sleep, could you test again using IDF v5.3.1, let us know if you still see any issues.

vedatbotuk commented 1 month ago

Ok @chshu, I will check it.

vedatbotuk commented 2 weeks ago

Hi @chshu I could test it today. For me works with IDF v5.2.3 fine.