Closed detly closed 1 year ago
I think you have a problem with your rate - the real rate is half your desired rate.
It may be just the recent bug around rate calculation but I would double check that first
@davydnorris I was confused by that too. Is it in this issue tracker?
(I'm not sure that accounts for it anyway, because the I2S/ADC interaction doesn't need to know what the desired sample rate is. It just gets the data from the ADC reads as triggered by the WS line, whatever the sample rate is.)
See https://github.com/espressif/esp-idf/pull/3648, but I think maybe you have some other problem as the errors here are not half.
I may be completely off track here as I thought you were reading an external ADC sensor, but you're using the in-built one. However I would chase that rate problem down - it seems very weird
Verified that it's present in master
.
@davydnorris I filed a separate bug for that, #3692 .
Running this on a commit where the sample rate problem is not present still shows the channel ordering issue.
So avoiding the APLL issue, I have verified with an oscilloscope that the WS signal is running at 24kHz as expected. The channel ordering is still doubled up.
@davydnorris Turns out the weird sample rate being reported is simply a side effect of the fact that the clocks work a bit differently in ADC mode (WS is always half the frequency of the BCK). The debug print still calculates everything assuming WS = BCK/(bits*channels). But the WS signal is actually correct as long as the PLL D2 is used and not the APLL.
thanks for digging into this - I have never used the built in ADC on the ESP32 so this is all news to me!
Have you seen #3170 ? If you use apll, you need do also set a fixed mclk:
.use_apll = 1,
.fixed_mclk= 2000000,
@x-ryl669 yep, see #3692. Problem exists regardless of APLL.
@detly I found that the adc channel is normal when using mono.
i2s_set_clk(i2s_num, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
Why is it swapping values in the middle (5 6 5 6 then 6 5 6 5) ?
I found that the adc channel is normal when using mono.
Look closely, there's a doubled-up channel 6 read in the middle of your output.
At any rate, I can't contribute much to this issue any more. I scrapped the project and blacklisted ESP due to multiple not-fit-for-purpose issues such as this one.
@detly I found that the adc channel is normal when using mono.
i2s_set_clk(i2s_num, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
- 2 channel:
- 8 channel:
When the I2S bus works in I2S_CHANNEL_FMT_RIGHT_LEFT mode, each data will be repeated once to cause the data rate to double, but the actual sampling rate is unchanged. However, when using SAR ADC1 to perform multi-channel scanning according to the specified pattern table, as in your test results, there will be random channel sequence changes, or some channels will be repeatedly scanned suddenly. This problem causes non-uniformity in the sampling interval, and it is clear that the chip does not work according to the characteristics given in TRM.
To reproduce this problem, code attched to the link https://www.esp32.com/viewtopic.php?t=8335&start=10 can be used. Here is a part of the output of the example code when the problem occurs: ch 6 0.160000v ch 7 0.160000v ch 0 0.160000v ch 3 0.160000v ch 3 0.160000v ch 7 0.160000v ch 7 0.208308v ch 0 0.197573v ch 3 0.160000v ch 6 0.229011v ch 7 0.202173v ch 0 0.188371v ch 3 0.160000v ch 6 0.208308v ch 7 0.196806v ch 0 0.179170v
I've read in one of the issues (don't remember which) here that the HW sampler needs 2 clocks to restart sampling when it's done a batch (instead of restarting immediately), so it's always missing one sample, that's probably the reason for the repetition, in fact, it has missed one value.
If you had a non constant voltage source, you'd see the effect.
I've read in one of the issues (don't remember which) here that the HW sampler needs 2 clocks to restart sampling when it's done a batch (instead of restarting immediately), so it's always missing one sample, that's probably the reason for the repetition, in fact, it has missed one value.
I read this too, I think it was a PR, not an issue. If this is a case, it absolutely needs to be documented front and centre in the TRM and the API, because it is totally at odds with every other embedded system out there, and means that the ADC-to-I2S functionality — an advertised feature of this system — is more or less useless for a great many applications. On top of that, letting engineers waste this much time and effort trying to debug it, instead of simply being honest about the limitation, is unacceptable.
If you had a non constant voltage source, you'd see the effect.
I actually do, I see it quite clearly with a sine tone generator or audio calibration signal.
@X-Ryl669 was it this comment on PR #1991?
Yes, exactly. Thanks for digging this out again.
Hello, I hope you are doing well. I believe that what is being discussed in here is the underlying issue of what I have posted:
https://github.com/espressif/arduino-esp32/issues/3939
Could you kindly please take a look at this issue and let me know what you think? My knowledge on I2S and firmware are very limited, and so I`m not sure if this is the same issue and if there is a solution for it?
Thank you
@detly About the modifications that you've done to sample multiple channels, does it is still possible to do it on current esp32 firmware?
This actually helped a lot:
I've read in one of the issues (don't remember which) here that the HW sampler needs 2 clocks to restart sampling when it's done a batch (instead of restarting immediately), so it's always missing one sample, that's probably the reason for the repetition, in fact, it has missed one value.
But when I saw it I thought of tossing everything out the (closed) window since it seemed like a HW limitation. and hundreds of hours down the drain. Now it's actually working here.
Thanks for explaining your engineering dissection. I'm eager to see the actual code to make it work flawlessly.
Environment
v3.3-beta2
andmaster
(58df1d93
) but note modifications below1.22.0-80-g6c4433a
Problem Description
I'm trying to use the I2S direct-from-ADC functionality in my firmware, with multiple channels.
Note: I have modified the IDF code with the following changes:
adc_set_i2s_data_len()
fromcomponents/driver/rtc_module.c
viacomponents/driver/include/driver/adc.h
adc_set_i2s_data_pattern()
(same)._i2s_adc_mode_recover()
ini2s_adc_enable()
incomponents/driver/i2s.c
These changes are necessary to allow connecting multiple ADCs to the I2S module (see #2980 , @montaguk's comment).
I have some example code that simply reads the I2S data as it is generated and extracts the channel it originated from. The Technical Manual says:
So this is done with code like:
...applied to every second
char
, offset by one (to get the MSB).But when I actually run my code (below), I do not see alternating channels eg 5, 6, 5, 6. I see channels doubled up and sometimes skipped eg. 5, 6, 6, 5, 5, 6, 6, 5, 6.
Expected Behavior
The Technical Manual says:
So given the setup:
I would expect the I2S-triggered scanning to simply go 6, 5, 6, 5, 6, 5, and the resulting I2S data to have that same pattern.
Actual Behavior
My code prints:
Note the repetition of each channel.
Steps to repropduce
Build and run the code I link to with
idf.py build
andidf.py flash monitor
. Don't forget to make the modifications I mention above.Code to reproduce this issue
I have put the entire example project on Gitlab here. But here is the essential setup code for the peripherals:
I would also like to know what the proper
communication_format
is to use for direct-from-ADC operation, because it does seem to affect the result.Debug Logs
Here's the log of the first set of reads:
Happy to provide more information if it helps.