Closed zekageri closed 4 years ago
Hi ,where is your loop or setup functions ?
There are a few things in my setup and in my loop. i have got a bunch of components attached to my esp. The i2s init function is my first thing to do on the setup.
I had to separate the reading and plotting part of my sampling function. The signals are good now, but the entire thing is slow. Btw my problem solved. Here is the reader and plotter functions, separated on the two cores of the esp.
Reading on core1 on loop:
static const inline void Sampling(){
i2s_read(I2S_NUM_0, (char*)i2s_read_buff,NUM_SAMPLES * sizeof(uint16_t), &bytes_read, portMAX_DELAY);
}
I dont have to do anything else in here.
And my plotting function on core 0:
static const inline void Plotting(uint16_t* Buffer){
String data;
if (Chart_is_ok_to_Send_Data) // if the user investigated the chart page
{
for(int i = 0;i<NUM_SAMPLES;i++)
{
data = String((Buffer[i])/*/(float)40.95*/);
if(olvasunk_e){ // there is a button on the page to stop the plotting but not the reading.
data += "}";
webSocket.broadcastTXT(data.c_str(), data.length());
}
}
}
}
My i2s init is on the first place at the setup():
void configure_i2s(){
i2s_config_t i2s_config =
{
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), // I2S receive mode with ADC
.sample_rate = samplingFrequency, // 144000hz
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // 16 bit I2S
.channel_format = I2S_CHANNEL_FMT_ALL_LEFT, // all the left channel
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), // I2S format
.intr_alloc_flags = 0, // none
.dma_buf_count = 8, // number of DMA buffers ( maybe this is too much? )
.dma_buf_len = 1024, // number of samples
.use_apll = 0, // no Audio PLL
};
adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN_11db);
adc1_config_width(ADC_WIDTH_12Bit);
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_adc_mode(ADC_UNIT_1, ADC_CHANNEL);
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL2_REG, SYSCON_SARADC_SAR1_INV);
i2s_adc_enable(I2S_NUM_0);
vTaskDelay(1000);
}
And thats all. It would be good if i was able to do the queue thing with the i2s but i can't find anything with arduino core. Btw this problem is solved.
Some pictures from the plotting on the web:
Can I get the full code of it. I am facing similar problem but couldn’t understand how to run in seperate core as you mentioned.
Sorry. I don't have the code anymore. I completelly ditched the project because the esp's analog read is a total garbage. I couldn't get even near of the desired accuracy.
@PilnyTomas Just take a look on this closed issue, maybe it can be relevant a bit to your work.
If you want accurate real time analog data visualization on the web, spare your time. It won't work.
Hello forumers!
I want to read a 4Khz analog signal from a signal generator via i2s dma with ESP32 on arduino framework.
My basic idea is this:
-Setup i2s DMA to put the reading to a buffer. -Assign a read function/task to the core0 to read the values from the DMA buffer. -Assign a "plotting" functon/task to a core to plot the readings to the web with ChartJS.
What have i done so far:
I created the i2s setup function and put it to the first place on the setup(). I created the reader task on the core0 for reading and plotting to the web. I created a html file that i store on the SPIFFS file system on the ESP32. -In the HTMl file i created a chart on a canvas using ChartJS javascript library. -In the JavaScript file i created a websocket client that is connected to the websocket server on the esp32. -In the JavaScript file, when the data comes from the esp32 i assign it to the chart and visualize it.
Everything is working fine, except one little problem. My i2s dma buffer is overflowing and i can see it in the visualized data.
What i think is happening: -While i read the entire DMA buffer, the i2s adc is filling up this buffer again and again even if i doesn't end up reading from the entire buffer. This will result on buffer overflow and my readed data does not mach the actual reading.
What i think is the solution: -If there will be an interrupt on the i2s adc dma, if it is filled up the entire buffer i would switch to an other buffer while i read the first, and when i done with the reading i would read from the second while the adc filling up the first and so on...
The thing is i did not find anything from this interrupt on the Arduino core. The one thing that i found is an event solution, that i think is just a flag and does not work as expected.
So my question is, how can i avoid this buffer overflow or how can i assign an interrupt to the dma buffer, or how can it be done correctly.
Here is my i2s init code:
Here is my adc reader function on core 0:
The ADC_Sampling is looks like this on core0:
My HTML and JavaScript code:
Here is a video URL from my plotted data on the WEB when the buffer overflow doesn't hit.:
https://streamable.com/9dngp
I attached some pictures from the readed data on the web.