Easy IoT General

Firebeetle ESP32 I2S Audio DAC setups

userHead kington 2017-09-28 06:43:58 6743 Views2 Replies
I am using the Firebeetle ESP32 board by DFROBOT DFR0478 ....to send audio data ti I2S 0 port and using BUILTIN DAC for output.
I have problem with distortion when sending full amplitude data samples .....

Is there anything elase I need to setup when programming or is there any other components distorting the output.

Small data samples work OK.

There is a schematic on the web site and pinouts diag. and it doesnt show anything connected to the DAC pins.
And I don't see anything connected on the board. I have nothing else connected except the USB port.

It uses the DFROBOT ESP-WROOM-32 module on the board and I dont see anything connected on the pins of it on the schematic.

Is the DFROBOT ESP-WROOM-32 an original esp WROOM or a version made by DFROBOT and does it have different setup requirements.
I see the DFROBOT Firebeetle ESP32 is listed on Espressif web as "clone" ... non standard clocks..???
What does that mean and is the performance any different..???

As far as I can see the DAC ports are Pins 3 and 4 on the firebeetle board, called D2 and D3, or GPIO25 and GPIO26,...connected to pins 10 and 11 of the WROOM module which is connected to pins 13 and 14 of the actual ESP32 chip.

And I am using Pin 15 on the firebeetle board as GND.


What I am finding is sine wave with amplitude factor above 80 in the calculation below gives distortion

Code: Select all
#include "driver/i2s.h"
#include "freertos/queue.h"

#define PI 3.14159265

    uint32_t samples[256];
    float sin_float;

//i2s configuration ....... I put this at the top of the sketch before setup.....???

int i2s_num = 0;      // i2s port number DAC BUILT_IN  works on I2S_NUM_0
i2s_config_t i2s_config = {
     .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
     .sample_rate =44100,
     .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = (I2S_COMM_FORMAT_I2S_MSB),
     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,           // high interrupt priority Interrupt level 1
     .dma_buf_count = 2,
     .dma_buf_len = 128   
    };

void setup()
{
  Serial.begin(115200);
  
  Serial.println("config done.");

        //initialize i2s with configurations above .....I put this bit in setup....????
                 
        i2s_set_pin((i2s_port_t)i2s_num, NULL);        // NULL here needed for BUILT_IN DAC
         
        i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);
                    
        Serial.println("I2S installed and started!");
  
    // Create Data below.....
    // Make sure data is between 0 and 1V
    
    for(int i = 0; i < 256; i++) {
      
         sin_float = ((sin(i / 256.0 * 2 * PI)+1) * 88);   //calc. sinewave all above zero, 1 cycle x 256 samples.
         
         //   Above line with amplitude of 80 and below works OK...no distortion
         //   81 and above distortion begins to appear......so the above line  at 88 gives distortion...????
       
         samples[i] =  ((uint32_t) (sin_float) << 8) + ((uint32_t) (sin_float) << 24);   //...output IO25 and output IO26...
                 
              }
    
    // Write data to the buffer. 
    
    i2s_write_bytes((i2s_port_t)i2s_num, (const char *)samples, 1024, portMAX_DELAY);
        
   }
2017-10-10 09:10:58 I am still having problems getting DAC1 and DAC2 port operating over the full voltage range 0 to 255 for 0 to 3.3 volt.
Previous posts were using x10 scope probes and I didnt allow for that so all my reading are our x10 low because of that.
Basically when I measure with a meter the voltage varies from about 3.3 volts to a minimun of about 1.65 volts. The 1.65 volts is when I send 128 to the port using dacWrite and I get 3 volts when 0 or 255 is sent. so the volts go from 3.3 to 1.65 as int val goes from 0 to 128, then volts got up again to 3 volts as int goes form 128 to 255. ????.
I have checked for some of the register setting in the technical manual and read out some of the values as code below.

Is it these registers that need to be setup..????.....would be grateful for some help please....
Code: Select all
     // Reading REG values and voltage out of DAC1 and DAC2 ports
  // DFRobot Firebeetle ESP32 dev board.

  void loop()
    {
  
      int a = 20;
      int b = 120;


      dacWrite(25,a);
      dacWrite(26,b);


     Serial.println(a);
     Serial.println(b);

     Serial.println((READ_PERI_REG(RTC_IO_PAD_DAC1_REG)),HEX);
     Serial.println((READ_PERI_REG(RTC_IO_PAD_DAC1_REG)),BIN);
     Serial.println((READ_PERI_REG(RTC_IO_PAD_DAC2_REG)),HEX); 
     Serial.println((READ_PERI_REG(RTC_IO_PAD_DAC2_REG)),BIN);
      
     Serial.println((READ_PERI_REG(SENS_SAR_DAC_CTRL1_REG)),HEX);
     Serial.println((READ_PERI_REG(SENS_SAR_DAC_CTRL1_REG)),BIN);
     Serial.println((READ_PERI_REG(SENS_SAR_DAC_CTRL2_REG)),HEX);
     Serial.println((READ_PERI_REG(SENS_SAR_DAC_CTRL2_REG)),BIN); 

    }

Results below from running above code.....

20
120
80A60400
10000000101001100000010000000000
83C60400
10000011110001100000010000000000
0
0
0
0


For int 20 volts out is 2.82 volts
For int 120 volts out is 1.63 volts.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


160
240
85060400
10000101000001100000010000000000
87860400
10000111100001100000010000000000
0
0
0
0
For int 160 Volts out is 2.0 volts
For int 240 volts out is 3.0 volts
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx




Now if I put in this config for I2S.......

int i2s_num = 0;      // i2s port number DAC BUILT_IN  works on I2S_NUM_0

i2s_config_t i2s_config = {
     .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
     .sample_rate =44100,
     .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = (I2S_COMM_FORMAT_I2S_MSB),
     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,        // high priority Interrupt level 1
     .dma_buf_count = 2,
     .dma_buf_len = 128   
    };


        i2s_set_pin((i2s_port_t)i2s_num, NULL);  // NULL for BUILT_IN DAC
         
        i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);




Below is with I2S config.....

160
240
85060400
10000101000001100000010000000000
87860400
10000111100001100000010000000000
2400000
10010000000000000000000000
0
0
Now get.....
For int 160 Volts out is 3.0 volts
For int 240 volts out is 3.0 volts
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


20
120
80A60400
10000000101001100000010000000000
83C60400
10000011110001100000010000000000
2400000
10010000000000000000000000
0
0
Now get.....
For int 20 Volts out is 3.0 volts
For int 120 volts out is 3.0 volts
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
userHeadPic kington
2017-09-29 16:11:13 I have checked both DAC1 and DAC2 outputs on a scope and find that all I get out of both DAC pins is a about a 100 millivolt ripple on top of about a 250 millivolt DC voltage, when sending samples corresponding to an audio tone signal to the DAC. If I send a fixed value, any value between 0 to 255 I just get the 250 millivolts +/- the few millivolts depending on the value I send.

It doesn't matter if I send using dacWrite OR set_dac_voltage or using I2S-DAC.

When I send samples as a sinewave calculation of amplitude value of 80 I get about 50 millivolt peak to peak on the scope, good sinewave and sounds OK played on an amplified speaker and looks good sinewave in Audacity. If I change the value to 88 or more I can still see the same wave on the scope but with distortion of the bottom of the peaks appearing and it sounds more "buzzing".

Is there anything else needs to be setup in registers etc. I have tried all the enable and disable I can find in the documents and tried it from Arduino IDE on windows and from ESP_IDF on Linux....and no difference....?????
userHeadPic kington