I want to generate two signals on the DAC outputs of ESP32, the sine
and cosine
ones, thus shifted by 90 deg. But I have the same signal on both DAC outputs.
From the Espressif documentation I found that The DAC channels can’t be registered to continuous mode separately (link to docs)
Moreover, I found from the documentation (dac cont config) such information for DAC configuration:
cont_cfg = {
.chan_mask = DAC_CHANNEL_MASK_ALL,
.desc_num = 2,
.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_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
*/
Thus, if I understood correctly, for my task I have to use the ALTER mode .chan_mode = DAC_CHANNEL_MODE_ALTER
to put different signals into two DAC channels (channel_mode).
/* Assume the data in buffer is 'A B C D E F'
* DAC_CHANNEL_MODE_ALTER:
* - channel 0: A C E
* - channel 1: B D F
*/
And I have written a function for sine
and cosine
signals generation, where I used the intersection of these two signals in the same buffer:
void generate_waves(void)
{
for (int i = 0; i < EXAMPLE_ARRAY_LEN; i++)
{
if (i % 2)
{
signal_wave[i] = (uint8_t)(amplitude / 2 * (1 + sin(2 * M_PI * i / EXAMPLE_ARRAY_LEN)));
}
else
{
signal_wave[i] = (uint8_t)(amplitude / 2 * (1 + cos(2 * M_PI * i / EXAMPLE_ARRAY_LEN)));
}
}
}
However, no effect. The signals are the same on both DAC outputs!
My example 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()
{
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++)
{
if (i % 2)
{
signal_wave[i] = (uint8_t)(amplitude / 2 * (1 + sin(2 * M_PI * i / EXAMPLE_ARRAY_LEN)));
}
else
{
signal_wave[i] = (uint8_t)(amplitude / 2 * (1 + cos(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
The problem/question summary:
How to output different signals on each DAC channel
, where DAC is in Continuous Wave Output mode (Continuous/DMA Mode)?
Thanks to your comments and help!