PWM in deep sleep

aliasthefourth
Posts: 5
Joined: Sun Feb 28, 2021 8:22 pm

PWM in deep sleep

Postby aliasthefourth » Sun Feb 28, 2021 8:36 pm

Does anybody know if it is possible to have RTC pins perform pulse width modulation in deep sleep?

felmue
Posts: 70
Joined: Mon Nov 16, 2020 2:55 pm

Re: PWM in deep sleep

Postby felmue » Mon Mar 01, 2021 12:44 pm

Hello @aliasthefourth

yes, I did something like that using ULP to toggle a pin on and off. Even though the example is for an M5Stack device I think it should be transferable to any ESP32 board.

https://community.m5stack.com/topic/596 ... p-sleep/16

Thanks
Felix

boarchuz
Posts: 612
Joined: Tue Aug 21, 2018 5:28 am

Re: PWM in deep sleep

Postby boarchuz » Mon Mar 01, 2021 1:28 pm

In a similar vein, I used the RTC I2C peripheral clock here to pulse an LED:
https://github.com/boarchuz/HULP/blob/p ... o/main.cpp
Using a dodgy configuration, the clock signal never ends. It's not 100% clean (there are very occasional hiccups when the peripheral thinks it should be doing a start/stop) but only your scope will ever know.
It also has the ULP writing to timing registers in deep sleep, but I had some issues with this and there are some confused comments to that effect.

aliasthefourth
Posts: 5
Joined: Sun Feb 28, 2021 8:22 pm

Re: PWM in deep sleep

Postby aliasthefourth » Wed Mar 03, 2021 3:27 am

felmue wrote:
Mon Mar 01, 2021 12:44 pm
Hello @aliasthefourth

yes, I did something like that using ULP to toggle a pin on and off. Even though the example is for an M5Stack device I think it should be transferable to any ESP32 board.

https://community.m5stack.com/topic/596 ... p-sleep/16

Thanks
Felix
Thanks Felix,
With only slight modifications that works like a charm dimming the build in LED on my dev Board. Now I can go on to implementing the spike and hold for my solenoid valve. What a time saver.
Best,
Gero

Here is the code:

#include <Arduino.h>
#include "esp32/ulp.h"
#include "driver/rtc_io.h"

const int lcdBrightness = 100; // (0-255)

void ulp_start(void) {
// Slow memory initialization
memset(RTC_SLOW_MEM, 0, 8192);
// if LED is connected to GPIO2 (specify by +14)
const gpio_num_t ledPWMPin = GPIO_NUM_2;
const int ledPWMBit = RTCIO_GPIO2_CHANNEL + 14;
// GPIOx initialization (set to output and initial value is 0)
rtc_gpio_init(ledPWMPin);
rtc_gpio_set_direction(ledPWMPin, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(ledPWMPin, 0);
// Define ULP program
const ulp_insn_t ulp_prog[] = {
M_LABEL(1),
I_WR_REG(RTC_GPIO_OUT_REG, ledPWMBit, ledPWMBit, 1), // on
I_DELAY(lcdBrightness * 100),
I_WR_REG(RTC_GPIO_OUT_REG, ledPWMBit, ledPWMBit, 0), // off
I_DELAY(25500 - lcdBrightness * 100),
M_BX(1),
};
// Run ULP program
size_t size = sizeof(ulp_prog) / sizeof(ulp_insn_t);
ulp_process_macros_and_load(0, ulp_prog, &size);
ulp_run(0);
}

void setup() {
Serial.begin(115200);
ulp_start();
Serial.println("Going to deep sleep");
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_deep_sleep_start();
}

void loop() {
}

Who is online

Users browsing this forum: Google [Bot] and 59 guests