External 24bit I2S ADC nor working

tester
Posts: 3
Joined: Sat Mar 07, 2020 10:22 pm

External 24bit I2S ADC nor working

Postby tester » Sat Mar 07, 2020 10:45 pm

Hello,

I have connected an external 24bit I2S ADC (CS5341) and I only get random data from the device.

I tried both master and slave mode and different samplerates but I always get random data.

I have checked both the LRCLK and BCLK in master and slave mode and they are present.

This is my initialization code:

Code: Select all


     #define SAMPLE_RATE 192000
     #define PIN_I2S_BCLK 27
     #define PIN_I2S_LRC  26
     #define PIN_I2S_DIN  14
     #define PIN_I2S_DOUT -1

     i2s_config_t i2s_config =
     {
        .mode = i2s_mode_t(I2S_MODE_SLAVE | I2S_MODE_RX),
        .sample_rate = SAMPLE_RATE,                        
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 4,                          
        .dma_buf_len = 512,
        .use_apll = 0,                            
     };
  
     i2s_pin_config_t pin_config;
   
     pin_config.bck_io_num = PIN_I2S_BCLK;
     pin_config.ws_io_num = PIN_I2S_LRC;
     pin_config.data_out_num = -1;//I2S_PIN_NO_CHANGE;
     pin_config.data_in_num = 14;//PIN_I2S_DIN;

     i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
     i2s_set_pin(I2S_NUM_0, &pin_config);
And the read code:

Code: Select all

uint32_t bytes_read;
uint32_t samples[1024];

void loop()
{
    i2s_read(I2S_NUM_0, (char*)samples, 1024 * sizeof(uint32_t), &bytes_read, portMAX_DELAY);
        
    for (int i = 0; i < 1024; i++)
    {
        uint32_t dat = (samples[i] & 0xFFFFFF);

        Serial.printf("%d : %d\n",i, dat);
    }  
    
    delay(1000);
}
This is what I get as output:

Code: Select all

0 : 81408
1 : 16757248
2 : 2048
3 : 16351104
4 : 75520
5 : 462848
6 : 209408
7 : 16660480
8 : 16750848
9 : 405504
10 : 258816
11 : 16639488
12 : 16770304
13 : 208896
14 : 49152
15 : 16713472
16 : 3840
17 : 16676608
18 : 16712960
19 : 16441088
20 : 112640
21 : 16754176
22 : 16765952
23 : 16289536
24 : 131584
25 : 63616
26 : 16672256
27 : 16277248
28 : 101376
29 : 16415488
30 : 131200
31 : 397184
32 : 16660864
33 : 1102976
34 : 34048
35 : 37120
36 : 9216
37 : 16161152
38 : 128512
39 : 16695296
40 : 16766208
41 : 307968
42 : 29440
I have tried different settings but always get random data at the output. It makes no difference if I set the ADC in master or slave mode. Clock lines matches the samplerate settings. What could be wrong? I`m sure the ADC board works correctly. if I hook the ADC board up to a Raspberry it works fine. I double checked the data and clock lines and they are connected correctly to the ESP32.

If I disconnect the data line from the ADC and connect it to ground the output is 0 and if I connect the data pin to VCC the output is 0xFFFFFF so the data pin is reading its input correctly.

What could be wrong?

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: External 24bit I2S ADC nor working

Postby ESP_Sprite » Mon Mar 09, 2020 10:27 am

Why do you think these samples are 'random'? As far as I can see, you're interpreting signed data as unsigned; if you correct for that, the extremely high positive numbers become a small negative numbers. That makes the entire sample look like some low-amplitude noise around zero.

tester
Posts: 3
Joined: Sat Mar 07, 2020 10:22 pm

Re: External 24bit I2S ADC nor working

Postby tester » Mon Mar 09, 2020 1:51 pm

The ADC is not getting an input signal. Since the ADC has a S/N of about 100dB I would expect a low noise output.
I already tried to convert from unsigned to signed:

Code: Select all

int32_t sample = (int32_t)Adcsample;
But then I also get strange output values.

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: External 24bit I2S ADC nor working

Postby ESP_Sprite » Mon Mar 09, 2020 2:25 pm

That's not going to make the value 32-bit signed, as your original is 24-bit signed. You need to sign-extend it. Try something like this:

Code: Select all

uint32_t dat = (samples[i] & 0x7FFFFF);
if (samples[i]&0x800000) dat|=0xff800000; //sign extend 24-bit value to 32-bit
int32_t signed_sample=(int32_t)dat;
printf("%d\n", signed_sample);
Hard to say if the noise is to be expected or not without seeing the schematic the ADC is hooked up in. Can you graph what you receive somewhere? Can you input a sine wave into the ADC and graph it again?

Also, if you expect some interfacing mistake, it helps to print the values in hex (printf("%06X", sample)) instead of binary, as per-bit problems are more visible that way.

mjanika
Posts: 1
Joined: Wed May 08, 2024 9:08 am

Re: External 24bit I2S ADC nor working

Postby mjanika » Wed May 08, 2024 12:07 pm

tester wrote:
Sat Mar 07, 2020 10:45 pm
Hello,

I have connected an external 24bit I2S ADC (CS5341) and I only get random data from the device.

I tried both master and slave mode and different samplerates but I always get random data.

I have checked both the LRCLK and BCLK in master and slave mode and they are present.

This is my initialization code:

Code: Select all


     #define SAMPLE_RATE 192000
     #define PIN_I2S_BCLK 27
     #define PIN_I2S_LRC  26
     #define PIN_I2S_DIN  14
     #define PIN_I2S_DOUT -1

     i2s_config_t i2s_config =
     {
        .mode = i2s_mode_t(I2S_MODE_SLAVE | I2S_MODE_RX),
        .sample_rate = SAMPLE_RATE,                        
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 4,                          
        .dma_buf_len = 512,
        .use_apll = 0,                            
     };
  
     i2s_pin_config_t pin_config;
   
     pin_config.bck_io_num = PIN_I2S_BCLK;
     pin_config.ws_io_num = PIN_I2S_LRC;
     pin_config.data_out_num = -1;//I2S_PIN_NO_CHANGE;
     pin_config.data_in_num = 14;//PIN_I2S_DIN;

     i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
     i2s_set_pin(I2S_NUM_0, &pin_config);
And the read code:

Code: Select all

uint32_t bytes_read;
uint32_t samples[1024];

void loop()
{
    i2s_read(I2S_NUM_0, (char*)samples, 1024 * sizeof(uint32_t), &bytes_read, portMAX_DELAY);
        
    for (int i = 0; i < 1024; i++)
    {
        uint32_t dat = (samples[i] & 0xFFFFFF);

        Serial.printf("%d : %d\n",i, dat);
    }  
    
    delay(1000);
}
This is what I get as output:

Code: Select all

0 : 81408
1 : 16757248
2 : 2048
3 : 16351104
4 : 75520
5 : 462848
6 : 209408
7 : 16660480
8 : 16750848
9 : 405504
10 : 258816
11 : 16639488
12 : 16770304
13 : 208896
14 : 49152
15 : 16713472
16 : 3840
17 : 16676608
18 : 16712960
19 : 16441088
20 : 112640
21 : 16754176
22 : 16765952
23 : 16289536
24 : 131584
25 : 63616
26 : 16672256
27 : 16277248
28 : 101376
29 : 16415488
30 : 131200
31 : 397184
32 : 16660864
33 : 1102976
34 : 34048
35 : 37120
36 : 9216
37 : 16161152
38 : 128512
39 : 16695296
40 : 16766208
41 : 307968
42 : 29440
I have tried different settings but always get random data at the output. It makes no difference if I set the ADC in master or slave mode. Clock lines matches the samplerate settings. What could be wrong? I`m sure the ADC board works correctly. if I hook the ADC board up to a Raspberry it works fine. I double checked the data and clock lines and they are connected correctly to the ESP32.

If I disconnect the data line from the ADC and connect it to ground the output is 0 and if I connect the data pin to VCC the output is 0xFFFFFF so the data pin is reading its input correctly.

What could be wrong?
Hello
I have the same problem with a cheap Chinese version of the PCM1808 ADC. Is there a solution to why it gives random numbers?

Who is online

Users browsing this forum: Basalt and 41 guests