1

I want to generate two signals on the DAC outputs of ESP32, the sine and cosine ones. But I have no signal on the DAC outputs.

Please, do not offer answers for the Cosine Wave Output mode (Cosine Mode).

I have to use Continuous Wave Output mode (Continuous/DMA Mode)

Of course, I read the documentation peripherals/dac.html, used the example code, but no positive result.

I am using PlatformIO (if it is matter):

[env]
; Development platform for Espressif 32 series of microcontrollers
platform = https://github.com/Jason2866/platform-espressif32.git #Arduino/IDF5

framework = arduino

My code

The main.cpp file:

#include <Arduino.h>
#include <ArduinoLog.h>

#include "soc/rtc.h"

#include "DAC_Signal_DMA.h"

void setup()
{

  Serial.begin(921600);
  delay(2000);

  // initialize logging
  Log.begin(LOG_LEVEL_VERBOSE, &Serial);

  Log.noticeln(F("%s() is configured"), __func__);

  DAC_Signal_DMA dac_Re_Im = DAC_Signal_DMA();
  delay(2000);

  dac_Re_Im.Start();
  delay(2000);

  Log.noticeln(F("DAC Signal DMA started"));
}

void loop()
{
  // Just for testing
  Serial.printf("Free heap size: %d\n", esp_get_free_heap_size());
  Serial.printf("%s(), core: %d: Running time [s]: %d\n", __func__, xPortGetCoreID(), millis());

  vTaskDelay(pdMS_TO_TICKS(1000 - 0));
}

The DAC_Signal_DMA.h file:

Some code is commented (reserved for the cosine signal on the second DAC channel). For now both channels are configured to the same signal.

#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/dac_channel.h"
#include "driver/dac_continuous.h"

// #include "esp_check.h"
// #include "dac_continuous_example.h"

#define EXAMPLE_DAC_CHAN0_IO DAC_CHAN0_GPIO_NUM // DAC channel 0 io number
#define EXAMPLE_DAC_CHAN1_IO DAC_CHAN1_GPIO_NUM // DAC channel 1 io number

#define EXAMPLE_ARRAY_LEN 500     // Length of wave array
#define EXAMPLE_DAC_AMPLITUDE 255 // Amplitude of DAC voltage. If it's more than 256 will causes

#define CONST_2_PI 6.2832 // 2 * PI

_Static_assert(EXAMPLE_DAC_AMPLITUDE < 256, "The DAC accuracy is 8 bit-width, doesn't support the amplitude beyond 255");

class DAC_Signal_DMA
{
public:
    DAC_Signal_DMA()
    {
        generate_waves();

        cont_cfg_0 = {
            .chan_mask = DAC_CHANNEL_MASK_ALL,
            .desc_num = 8,
            .buf_size = 2048,
            .freq_hz = frequency_convert_Hz,
            .offset = 0,
            .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // If the frequency is out of range, try 'DAC_DIGI_CLK_SRC_APLL'
            .chan_mode = DAC_CHANNEL_MODE_SIMUL,
        };

        // cont_cfg_1 = {
        //     .chan_mask = DAC_CHANNEL_MASK_CH1,
        //     .desc_num = 8,
        //     .buf_size = 2048,
        //     .freq_hz = frequency_convert_Hz,
        //     .offset = 0,
        //     .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // If the frequency is out of range, try 'DAC_DIGI_CLK_SRC_APLL'
        //     .chan_mode = DAC_CHANNEL_MODE_SIMUL,
        // };

        ESP_ERROR_CHECK(dac_continuous_write_cyclically(handle_0, (uint8_t *)squ_wav, buf_len, NULL));
        // ESP_ERROR_CHECK(dac_continuous_write_cyclically(handle_1, (uint8_t *)squ_wav, buf_len, NULL));

        Serial.println("DAC_Signal_DMA() constructed");
    }
    ~DAC_Signal_DMA()
    {
        Stop();
    }

    void Start()
    {
        /* Allocate continuous channel */
        ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg_0, &handle_0));
        delay(1000);
        /* Enable the channels in the group */
        ESP_ERROR_CHECK(dac_continuous_enable(handle_0));
        delay(1000);

        // /* Allocate continuous channel */
        // ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg_1, &handle_1));
        // delay(1000);
        // /* Enable the channels in the group */
        // ESP_ERROR_CHECK(dac_continuous_enable(handle_1));
        // delay(1000);

        Serial.println("DAC_Signal_DMA() started");
    }

    void Stop()
    {
        ESP_ERROR_CHECK(dac_continuous_disable(handle_0));
        ESP_ERROR_CHECK(dac_continuous_del_channels(handle_0));

        // ESP_ERROR_CHECK(dac_continuous_disable(handle_1));
        // ESP_ERROR_CHECK(dac_continuous_del_channels(handle_1));
    }

protected:
    void generate_waves(void)
    {
        uint32_t pnt_num = EXAMPLE_ARRAY_LEN;

        for (int i = 0; i < pnt_num; i++)
        {
            sin_wav[i] = (uint8_t)((sin(i * CONST_2_PI / pnt_num) + 1) * (double)(amplitude) / 2 + 0.5);
            cos_wav[i] = (uint8_t)((cos(i * CONST_2_PI / pnt_num) + 1) * (double)(amplitude) / 2 + 0.5);

            squ_wav[i] = (i < (pnt_num / 2)) ? amplitude : 0;
        }
    }

private:
    uint32_t frequency_Hz = 1000;
    uint32_t frequency_convert_Hz = EXAMPLE_ARRAY_LEN * frequency_Hz;
    size_t buf_len = EXAMPLE_ARRAY_LEN;
    uint8_t amplitude = EXAMPLE_DAC_AMPLITUDE;

    dac_continuous_config_t cont_cfg_0;
    dac_continuous_config_t cont_cfg_1;

    uint8_t sin_wav[EXAMPLE_ARRAY_LEN]; // Used to store sine wave values
    uint8_t cos_wav[EXAMPLE_ARRAY_LEN]; // Used to store cosine wave values
    uint8_t squ_wav[EXAMPLE_ARRAY_LEN]; // Used to store square wave values

    dac_continuous_handle_t handle_0 = NULL;
    dac_continuous_handle_t handle_1 = NULL;
};

The problem/question summary:

I need the help with ESP32 working DAC configuration in Continuous Wave Output mode (Continuous/DMA Mode)

Thanks to your comments and help!

1 Answer 1

0

Finally, after some experiments, I found, that the DAC driver functions cannot work if they are inside class.

And the function dac_continuous_write_cyclically() must be called after the channels activation:

ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg_0, &handle_0));
ESP_ERROR_CHECK(dac_continuous_enable(handle_0));

// After
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg_0, &handle_0));

The fully working code:

The main.cpp file:

#include <Arduino.h>

#include "DAC_Continuous_DMA.h"

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

  dac_continuous_dma_config(1000);
}

void loop()
{
  // Just for testing
  Serial.printf("Free heap size: %d\n", esp_get_free_heap_size());
  Serial.printf("%s(), core: %d: Running time [s]: %d\n", __func__, xPortGetCoreID(), millis());

  vTaskDelay(pdMS_TO_TICKS(1000));
}

The DAC_Continuous_DMA.h file:

#pragma once
#ifndef DAC_Continuous_DMA_h
#define DAC_Continuous_DMA_h

#include "Arduino.h"
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/dac_channel.h"
#include "driver/dac_continuous.h"

#include "soc/sens_reg.h"

#define EXAMPLE_ARRAY_LEN 512     // Length of wave array
#define EXAMPLE_DAC_AMPLITUDE 255 // Amplitude of DAC voltage. If it's more than 256 will causes

#define CONST_2_PI 6.2832 // 2 * PI

_Static_assert(EXAMPLE_DAC_AMPLITUDE < 256, "The DAC accuracy is 8 bit-width, doesn't support the amplitude beyond 255");

dac_continuous_config_t cont_cfg;

uint8_t signal_wave[EXAMPLE_ARRAY_LEN]; // Used to store sine wave values
uint8_t amplitude = EXAMPLE_DAC_AMPLITUDE;

dac_continuous_handle_t cont_handle = NULL;

void generate_waves(void)
{
    for (int i = 0; i < EXAMPLE_ARRAY_LEN; i++)
    {
        signal_wave[i] = (uint8_t)(amplitude / 2 * (1 + sin(2 * M_PI * i / EXAMPLE_ARRAY_LEN)));
    }
}

void dac_continuous_dma_config(uint32_t frequency_Hz = 1000)
{
    generate_waves();

    cont_cfg = {
        .chan_mask = DAC_CHANNEL_MASK_ALL,
        .desc_num = 2,
        .buf_size = 2048,
        .freq_hz = EXAMPLE_ARRAY_LEN * frequency_Hz / 2,
        .offset = 0,
        .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // If the frequency is out of range, try 'DAC_DIGI_CLK_SRC_APLL'
        .chan_mode = DAC_CHANNEL_MODE_ALTER,
    };
    /* Assume the data in buffer is 'A B C D E F'
     * DAC_CHANNEL_MODE_SIMUL:
     *      - channel 0: A B C D E F
     *      - channel 1: A B C D E F
     * DAC_CHANNEL_MODE_ALTER:
     *      - channel 0: A C E
     *      - channel 1: B D F
     */

    ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &cont_handle));
    ESP_ERROR_CHECK(dac_continuous_enable(cont_handle));
    ESP_ERROR_CHECK(dac_continuous_write_cyclically(cont_handle, (uint8_t *)signal_wave, EXAMPLE_ARRAY_LEN, NULL));

}

#endif // DAC_Continuous_DMA_h

Despite the I get signals on the DAC outputs (the current question is answered), the main my goal, to generate two signals on the DAC channels of ESP32, the sine and cosine ones, thus shifted by 90 deg, is not achieved.

But it is another question. And if somebody interested in this and can help me, I created new question here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.