RISC-V ULP ADC readings are off

norwayman22
Posts: 1
Joined: Sun Apr 05, 2026 8:48 pm

RISC-V ULP ADC readings are off

Postby norwayman22 » Sun Apr 05, 2026 9:09 pm

Hi, I'm trying to use the RISC-V ULP ADC example code (https://github.com/espressif/esp-idf/tr ... _riscv/adc) on my ESP32-S3 with my wpm356 water quality sensor and I'm getting strange results.

I've set EXAMPLE_ADC_TRESHOLD to 1 for testing and my ADC readings are stuck at around 1300. Shorting the pins on my sensor doesn't change the value at all. The only change is if I connect my board's 5v usb power to the adc pin, where i get a reading of 4095 as expected. Without the sensor plugged in it's the same thing.

Modifying the example code to prevent going into deepsleep makes me get the values I expect, with the baseline ADC value with the sensor plugged being around 40. Shorting the pins on the sensor gives around 3000 and connecting the 5V pin to the adc pin again gives 4095.

So why is it that the ADC is behaving weird when I allow the board to go into deepsleep?

Below is the code with the modified part commented out.

./ulp_riscv_adc_example_main.c:

Code: Select all

/*
 * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
/* ULP riscv example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ulp/example_config.h"
#include "ulp_adc.h"
#include "ulp_main.h"
#include "ulp_riscv.h"
#include <inttypes.h>
#include <stdio.h>

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");

static void init_ulp_program(void);

void app_main(void) {
  /* If user is using USB-serial-jtag then idf monitor needs some time to
   *  re-connect to the USB port. We wait 1 sec here to allow for it to make the
   * reconnection before we print anything. Otherwise the chip will go back to
   * sleep again before the user has time to monitor any output.
   */
  vTaskDelay(pdMS_TO_TICKS(1000));

  uint32_t causes = esp_sleep_get_wakeup_causes();

  /* not a wakeup from ULP, load the firmware */
  if (!(causes & (BIT(ESP_SLEEP_WAKEUP_ULP) | BIT(ESP_SLEEP_WAKEUP_TIMER)))) {
    printf("Not a ULP-RISC-V wakeup (causes = %lx), initializing it! \n",
           causes);
    init_ulp_program();

    // --- prevent deepsleep
    // while (1) {
    //   printf("ULP-RISC-V woke up the main CPU\n");
    //   printf("Threshold: high = %" PRIu32 "\n", ulp_adc_threshold);
    //   printf("Value = %" PRIu32 " was above threshold\n", ulp_wakeup_result);
    //   vTaskDelay(pdMS_TO_TICKS(1000));
    // }
    // ---
  }

  /* ULP Risc-V read and detected a temperature above the limit */
  if (causes & BIT(ESP_SLEEP_WAKEUP_ULP)) {
    printf("ULP-RISC-V woke up the main CPU\n");
    printf("Threshold: high = %" PRIu32 "\n", ulp_adc_threshold);
    printf("Value = %" PRIu32 " was above threshold\n", ulp_wakeup_result);
    printf("Count = %" PRIu32 "\n", ulp_count);
  }

  /* Go back to sleep, only the ULP Risc-V will run */
  printf("Entering in deep sleep\n\n");

  /* RTC peripheral power domain needs to be kept on to keep SAR ADC related
   * configs during sleep */
  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);

  ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());

  esp_deep_sleep_start();
}

static void init_ulp_program(void) {
  ulp_adc_cfg_t cfg = {
      .adc_n = EXAMPLE_ADC_UNIT,
      .channel = EXAMPLE_ADC_CHANNEL,
      .width = EXAMPLE_ADC_WIDTH,
      .atten = EXAMPLE_ADC_ATTEN,
      .ulp_mode = ADC_ULP_MODE_RISCV,
  };

  ESP_ERROR_CHECK(ulp_adc_init(&cfg));

  esp_err_t err = ulp_riscv_load_binary(
      ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
  ESP_ERROR_CHECK(err);

  /* The first argument is the period index, which is not used by the ULP-RISC-V
   * timer The second argument is the period in microseconds, which gives a
   * wakeup time period of: 20ms
   */
  ulp_set_wakeup_period(0, 20000);

  /* Start the program */
  err = ulp_riscv_run();
  ESP_ERROR_CHECK(err);
}

./ulp/main.c:

Code: Select all

/*
 * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
/* ULP-RISC-V example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.

   This code runs on ULP-RISC-V  coprocessor
*/

#include "ulp_riscv_adc_ulp_core.h"
#include "ulp_riscv_utils.h"
#include <stdint.h>

#include "example_config.h"

uint32_t adc_threshold = EXAMPLE_ADC_TRESHOLD;
int32_t wakeup_result;
int32_t count = 0;

int main(void) {
  count++;
  int32_t last_result =
      ulp_riscv_adc_read_channel(EXAMPLE_ADC_UNIT, EXAMPLE_ADC_CHANNEL);

  if (last_result > adc_threshold) {
    wakeup_result = last_result;
    ulp_riscv_wakeup_main_processor();
  }

  return 0;
}

./ulp/example_config.h:

Code: Select all

/*
 * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
#pragma once

#include "hal/adc_types.h"

#define EXAMPLE_ADC_CHANNEL ADC_CHANNEL_4
#define EXAMPLE_ADC_UNIT ADC_UNIT_1
#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12
#define EXAMPLE_ADC_WIDTH ADC_BITWIDTH_DEFAULT

/* Set high threshold, approx. 1.75V*/
#define EXAMPLE_ADC_TRESHOLD 1


MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: RISC-V ULP ADC readings are off

Postby MicroController » Mon Apr 06, 2026 10:10 am

The only change is if I connect my board's 5v usb power to the adc pin
Don't do that!

Who is online

Users browsing this forum: ChatGPT-User, Google [Bot], PerplexityBot and 3 guests