I2S DAC generate tone
Posted: Wed Nov 28, 2018 10:04 am
I am trying to produce sine wave with I2S. There are several strange things I have found I don't know how to overcome.
Here is my code:
First of all I am totally missing why signal is produced more than once. Image shows that pattern is repeated each ~30ms. Why is that so?
Secondly I am not sure how does I2S interpret sent data, should it be signed or unsigned?
However I tried both approaches(you can see two arrays in my code). What for unsinged pattern, it produces the following output: And here is how it should look like:
Clearly sequences of points are not the same.
Could someone clarify what is wrong here?
Here is my code:
- #include <Arduino.h>
- #include <driver/i2s.h>
- #include <driver/dac.h>
- /* I2S DAC */
- #define DAC_CHANNEL DAC_CHANNEL_1 // GPIO25 channel
- #define I2S_DAC I2S_NUM_0
- #define I2S_SAMPLE_RATE 8000
- #define I2S_BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_16BIT
- #define I2S_CHANNELS_NUM I2S_CHANNEL_MONO
- #define I2S_CHANNEL_FORMAT I2S_CHANNEL_FMT_ONLY_RIGHT
- #define I2S_COMM_FORMAT I2S_COMM_FORMAT_I2S_MSB
- #define I2S_DAC_CHANNEL I2S_DAC_CHANNEL_RIGHT_EN // corresponds to DAC 1 channel
- #define SINE_SAMPLES_NUM 256
- #define SINE_800HZ_SAMPLES_NUM 10
- /*
- const uint16_t i2s_sine_wave_800hz[SINE_800HZ_SAMPLES_NUM] = {
- 32768, 53830, 65038, 61145, 43975,
- 21561, 4391, 498, 11706, 32768
- };*/
- const int16_t i2s_sine_wave_800hz[SINE_800HZ_SAMPLES_NUM] = {
- 0, 21062, 32269, 28377, 11206,
- -11206, -28377, -32269, -21062, 0
- };
- static bool prepare_i2s_dac();
- static bool play_sound();
- void setup()
- {
- Serial.begin(921600);
- Serial.println("Hello!");
- if(!prepare_i2s_dac())
- {
- Serial.println("Failed to initialize DAC");
- while(true);
- }
- play_sound();
- }
- void loop()
- {
- //delay(10);
- }
- static bool play_sound()
- {
- static uint8_t sin_samples[SINE_800HZ_SAMPLES_NUM*2];
- for(uint32_t i=0; i<SINE_800HZ_SAMPLES_NUM; i++)
- {
- sin_samples[i*2] = (i2s_sine_wave_800hz[i]) & 0xFF;
- sin_samples[i*2+1] = (i2s_sine_wave_800hz[i] >> 8) & 0xFF;
- }
- if(i2s_write_bytes(I2S_DAC, (const char*)sin_samples,
- SINE_800HZ_SAMPLES_NUM*2, portMAX_DELAY) != SINE_800HZ_SAMPLES_NUM*2)
- {
- return false;
- }
- return true;
- }
- static bool prepare_i2s_dac()
- {
- i2s_config_t i2s_config = {
- mode : (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
- sample_rate : I2S_SAMPLE_RATE,
- bits_per_sample : I2S_BITS_PER_SAMPLE,
- channel_format : I2S_CHANNEL_FORMAT,
- communication_format : I2S_COMM_FORMAT,
- intr_alloc_flags : 0,
- dma_buf_count : 2,
- dma_buf_len : 128,
- use_apll : false,
- fixed_mclk : 0
- };
- if(i2s_driver_install(I2S_DAC, &i2s_config, 0, NULL) != ESP_OK)
- {
- Serial.println("Failed to initialize i2s driver for DAC");
- return false;
- }
- if(i2s_set_dac_mode(I2S_DAC_CHANNEL) != ESP_OK)
- {
- Serial.println("Failed to set i2s DAC channel");
- return false;
- }
- i2s_set_sample_rates(I2S_DAC, I2S_SAMPLE_RATE);
- return true;
- }
Secondly I am not sure how does I2S interpret sent data, should it be signed or unsigned?
However I tried both approaches(you can see two arrays in my code). What for unsinged pattern, it produces the following output: And here is how it should look like:
Clearly sequences of points are not the same.
Could someone clarify what is wrong here?