@Phil, great video and great channel! I believe you have off by one error in your C implementation. You want to subtract X(n-L), but you are subtracting X(n-L+1). The result of this is that you have running sum of the last L-1 elements instead of L elements. Another small potential issue you may have is accumulating floating point precision error over time. I would probably keep the running sum and ring buffer integer and convert to float only the result.
Thank you, Nikolay - you're completely right. I've pinned your comment, so people can see the error in the code. As stated in my previous pinned comment, thankfully, for large L (as is the case in the video), the error is small (due to summing 2047 samples, diving by 2048). Good point also regarding floating points.
So in essence, for anyone reading this in the future, just save the n-L sample in a temporary variable before overwriting it with the square of the current sample: ... float n_minus_L = mrms->in_sq_L[mrms->count]; mrms->in_sq_L[mrms->count] = in_sq; ... mrms->out_sq += mrms->invL * (in_sq - n_minus_L); ...
The lowest useful frequency will be: (ADC sampling rate) / (filter length) = 48kHz / 2048 ~ 23Hz. The highest useful frequency shall depend on the "crest factor" of the signal, that is highest harmonic detected. In case of the pure sine: 48kHz / 2 = 24kHz
Thanks for a great video. I see that the STM32 you are using is capable of keeping up with audio frequency waveforms. How high of an input frequency do you think it is capable of analysing reliably? And a side question: what is the reason you prefer hTerm as opposed to the built-in terminal in cubeIDE?
Thank you! In terms of 'raw sampling', the STM32 has its own ADCs which typically can go up to a few MSPS (according to datasheets) and at a significantly lower bit-depth. The external CODEC I'm using can go up to 192kHz sampling rate. What you can actually process using the H7 strongly depends on the algorithm, so it's hard to generalise. From past experiences, I'm not too much of a fan of the built-in terminals. Also I like having a single program for that, since I typically use quite a few different IDEs/platforms.
The answer depends on the input signal' "crest factor" and needed accuracy of the result. For example, to measure RMS of the sawtooth signal with 8-bit accuracy, one would need about 64 samples per period. So, for example, using 1 MHz ADC will give 1MHz/64=15kHz max! You can reach higher frequencies by reducing the number of samples per period, but at the expense of accuracy, and highest harmonic you want to catch. The sawtooth signal is very rich in harmonics, so a high sampling rate is needed. If you expect only a sine and a 2-nd harmonic, then 8 samples per period should suffice. There are hardware solutions for signals up to GHz frequencies.
There is one catch using this technique - it provides RMS value, which is delayed by the (length of the filter) / 2. So the results are not instantaneous.
Thanks. I wonder is that a part of a digital compressor, sir? I mean is it used in this shape for a coefficient of a signal amplification. or everything can be enveloped into a formula without a preliminary calculation of an RMS value? Unfortunately I don't remember, have you already created a digital compressor for your guitar pedal or not.
@Phil, great video and great channel! I believe you have off by one error in your C implementation. You want to subtract X(n-L), but you are subtracting X(n-L+1). The result of this is that you have running sum of the last L-1 elements instead of L elements. Another small potential issue you may have is accumulating floating point precision error over time. I would probably keep the running sum and ring buffer integer and convert to float only the result.
Thank you, Nikolay - you're completely right. I've pinned your comment, so people can see the error in the code. As stated in my previous pinned comment, thankfully, for large L (as is the case in the video), the error is small (due to summing 2047 samples, diving by 2048).
Good point also regarding floating points.
So in essence, for anyone reading this in the future, just save the n-L sample in a temporary variable before overwriting it with the square of the current sample:
...
float n_minus_L = mrms->in_sq_L[mrms->count];
mrms->in_sq_L[mrms->count] = in_sq;
...
mrms->out_sq += mrms->invL * (in_sq - n_minus_L);
...
Exactly @@EduardoBehr
Another very interesting video. I need someone like you to teach me more on physics.
Thank you, Alexandre!
fun fact the RMS of a sine wave is equal to its amplitude multiplied by sin(45) or cos(45)
Yeah but for arbitrary waveforms this wont help unfortunately
The lowest useful frequency will be: (ADC sampling rate) / (filter length) = 48kHz / 2048 ~ 23Hz.
The highest useful frequency shall depend on the "crest factor" of the signal, that is highest harmonic detected. In case of the pure sine: 48kHz / 2 = 24kHz
Stunning and neat video! I would like some internship with you to learn more about this topics 😢
Thank you, Teddy! I'm afraid I'm not offering internships, due to limited time available... :(
Thanks for a great video. I see that the STM32 you are using is capable of keeping up with audio frequency waveforms. How high of an input frequency do you think it is capable of analysing reliably? And a side question: what is the reason you prefer hTerm as opposed to the built-in terminal in cubeIDE?
Thank you! In terms of 'raw sampling', the STM32 has its own ADCs which typically can go up to a few MSPS (according to datasheets) and at a significantly lower bit-depth. The external CODEC I'm using can go up to 192kHz sampling rate.
What you can actually process using the H7 strongly depends on the algorithm, so it's hard to generalise.
From past experiences, I'm not too much of a fan of the built-in terminals. Also I like having a single program for that, since I typically use quite a few different IDEs/platforms.
@@PhilsLab 👍
The answer depends on the input signal' "crest factor" and needed accuracy of the result.
For example, to measure RMS of the sawtooth signal with 8-bit accuracy, one would need about 64 samples per period. So, for example, using 1 MHz ADC will give 1MHz/64=15kHz max!
You can reach higher frequencies by reducing the number of samples per period, but at the expense of accuracy, and highest harmonic you want to catch. The sawtooth signal is very rich in harmonics, so a high sampling rate is needed. If you expect only a sine and a 2-nd harmonic, then 8 samples per period should suffice.
There are hardware solutions for signals up to GHz frequencies.
Great video and congrats on the 100k subscribers
Thank you very much, Rick!
Great explanation and implementation!
Thank you!
Awesome! Personally, I think it would be cool/useful to add dBu and dBV values next to the voltage.
Hi Phil are you planning on making firmware demostration with the FPGA pcie you made? LOVE your contrnt
Very nice explanation. I need see more :)
There is one catch using this technique - it provides RMS value, which is delayed by the (length of the filter) / 2. So the results are not instantaneous.
Why length of the filter / 2 , you just need to pass that initialisation phase and then you get instant result no?
Another fantastic video!
Thank you!
Excellent
Thank you!
Uhh been waiting for this
Thanks. I wonder is that a part of a digital compressor, sir? I mean is it used in this shape for a coefficient of a signal amplification. or everything can be enveloped into a formula without a preliminary calculation of an RMS value? Unfortunately I don't remember, have you already created a digital compressor for your guitar pedal or not.
JLCPCB now offers flex PCBs! How about a video about them :) ?
Still waiting for a dedicated DSP course
Greetings sir! Big fan of your work. We need some another platforms for ESP32 like ESP_IDF, ESP 32 jama ....!
Is the recursive RMS C code available somewhere?
👍🙏❤
theres an audio glitch at 10:28, just wanted to let u know
Hello Sir, can you share the STM32 project file with us ?
So we can also experimet on our end!
Thanks in advance😊
Couldn't you just use the absolute value of the sin wave instead of squaring it?
no, you need to sum the squares, then only take the square root. The order of operations is not arbitrary here.