Как генерировать PWM-выход, представляющий синусоиду, на ESP32 (Arduino/PlatformIO)

Следующая функция вычислит значение синусоиды, используя micros() в качестве временной базы, с регулируемой частотой. Она жёстко запрограммирована на ожидание PWM с 12-битным разрешением

sine_pwm_esp32.cpp
/**
 * @brief Calculate the PWM duty cycle (assuming 12 bits resolution) of a sine wave of
 * given frequency. micros() is used as a timebase
 *
 * @param frequency The frequency in Hz
 * @return int the corresponding 12-bit PWM value
 */
int sinePWMValue(float frequency) {
  unsigned long currentMicros = micros(); // get the current time in microseconds

  // calculate the sine wave value for the current time
  int sineValue = 2048 + 2047 * sin(2 * PI * currentMicros / (1000000 / frequency));
  return sineValue;
}

Основываясь на этом, мы можем использовать базовый код из нашего предыдущего поста ESP32 минимальный пример Arduino PWM-выхода (PlatformIO) для генерации синусоиды 1 Гц (представленной 10 кГц PWM):

#include <Arduino.h> #include <driver/ledc.h>

sine_pwm_example.cpp
#include <Arduino.h>
#include <driver/ledc.h>

void setup() {
    Serial.begin(115200);

    ledcSetup(LEDC_CHANNEL_0, 10000 /* Hz */, 12);

    ledcAttachPin(GPIO_NUM_14, LEDC_CHANNEL_0);
    ledcWrite(LEDC_CHANNEL_0, 2048); // 50%
}

/**
 * @brief Calculate the PWM duty cycle (assuming 12 bits resolution) of a sine wave of
 * given frequency. micros() is used as a timebase
 *
 * @param frequency The frequency in Hz
 * @return int the corresponding 12-bit PWM value
 */
int sinePWMValue(float frequency) {
  unsigned long currentMicros = micros(); // get the current time in microseconds

  // calculate the sine wave value for the current time
  int sineValue = 2048 + 2047 * sin(2 * PI * currentMicros / (1000000 / frequency));
  return sineValue;
}

void loop() {
    // Example of how to change the duty cycle to 25%
    ledcWrite(LEDC_CHANNEL_0, sinePWMValue(1.0));
}

Check out similar posts by category: Arduino ESP8266/ESP32 PlatformIO