14:45 hmm, I wouldn't call this "wild", it mostly looks like what I'd expect provided I ignore the frequency axis. An averaging filter is well known to have pretty meh frequency response, with unit gain only at multiples of f_S (the sampling frequency) and nulls at all other multiples of f_S/N for N-sample averaging. The problem here is that with a 100ms sampling period, you'd expect peaks at multiples of 10 Hz which is clearly not where they're at.
That's interesting... although I have to mention, the 'sampling period' in this case is just the ramp time, which is 20ms. Each conversion is three ramps and three reset phases (zero, reference, input), totaling 120ms.
@@NNNILabs Ah, 120ms sampling interval i.e. 8.33 Hz sampling rate indeed looks consistent with the graphs you got when doing averaging. Specifically, the expected difference between no averaging and N-point averaging (in dB) is: 10 log₁₀( (1-cos(N ω)) / (1-cos(ω)) / N² ) where ω = 2 π f / f_S EDIT: or perhaps a nicer expression is: 20 log₁₀| sin(N ω / 2) / sin(ω / 2) / N |
@@MatthijsvanDuin Just tried the second formula, and it got me really close! There's still some kind of offset in the calculated result, and I had to change the formula slightly. I have to mention, I have no idea what I'm doing 😂 I would love to get in touch somewhere else so we can discuss this though, do you have a Discord account? You can find me there (basically online 24/7) under the same tag (@nnnilabs). I've pinned the comment since this basically explains it.
Thanks for the presenting a very interesting project. If the sampling interval is 120ms it will not provide *any* 50Hz suppression, no matter how many averages are taken, as it will be sampling the 50Hz interference at the same phase angle in every 6th cycle. I'm sure you know this but for the benefit of other viewers the ramp time has no relevance to the 50Hz suppression - as you observed, this ADC does *not* integrate the input signal over a single measurement cycle. That can only be achieved by averaging multiple measurements. For best NMRR the measurement sampling instances need to be phase locked to, and be equally spread over an integer number of cycles of the interfering signal -eg. averaging two measurements at 10ms intervals will provide a notch at 50Hz (and multiples) and significant NMRR. To complicate matters, the sampling point within each ramp is proportional to the input signal at the sampling instance so whilst it will be the same for each measurement of a DC input signal, adding an AC interfering signal means the sampling point in each ramp will vary accordingly. I'll let you do the NMRR analysis from here onwards :)
The pinned comment pointed out the same thing actually, and you're right, trying to reject NM noise with a single slope ADC is not very straightforward😅
Cool project! I might try building a crude version for myself because it seems like a good learning opportunity. I really enjoyed how you explained all the steps you went through to get it working. I can't wait to see what you do next!
Glad you enjoyed it! I tried to focus on actually explaining what I'm doing in the last couple of videos, so that seems to have worked at least 😅 If you do end up trying to replicate it, use lots of shielding, that seems to help.
@@NNNILabs I only plan on building it on a breadboard with fairly jellybean parts, just to get my feet wet. Thanks for the advice though, I will keep it in mind! I am really impressed with what you managed to accomplish with such a simple (and discrete!) ADC
Cool! Very good performance overall. Just as a note, didn't see whether you retained it, but the ADuM140x series can itself be rather noisy, and I would suspect that it might introduce timing jitter. Since these devices use transformers to couple the signal across the isolation boundary, they can only transmit signal transitions (not the actual signal state). Basically they send one type of pulse when the signal transitions high, another type when it transitions low, and nothing in between. The output side needs to latch the signal state. The problem with this approach is that if some noise glitch or other event causes the output latch that stores the signal state to inadvertently flip, the output will be wrong until the input changes again. That would of course be very bad. To fix this, the ADuM140x transmits "refresh" pulses even when you're not doing anything with the signal (the datasheet I saw says this is at ~1us period). It does this whenever the input signal goes more than 1us without transitions (is the case with your signals, I believe). But, of course this means that it's generating noise in the ~1MHz region and above all the time. Potentially worse is that I imagine there might be interactions between the refresh pulses and the data edge pulses. Imagine that you're sending a low-to-high transition but the refresh pulse has already started to send the original "low" state. I don't know how the chip would handle this, but I'd worry it might end up delaying your transition until the refresh pulse was done. This would quite possibly introduce timing jitter to the signals. Not sure what the solution here might be... putting an MCU of any sort on the same rails as the circuit without destroying the performance is going to be very, very hard. Traditional optocouplers might be one approach, although they do have pretty bad timing distortion themselves (not sure how sensitive the circuit is to this as I haven't studied it). It might also be possible to allow the MCU and converter to share a ground reference, but split the power rails completely, and then isolate the digital signals by transmitting them through some reasonably large resistors (~1-10k) and re-buffering them in the converter power domain with some logic gates powered by the analog rails, to restore edge slew rate and drive strength, while still interrupting the noise current path from the MCU's GPIOs.
Thanks for the tip, that's something I never thought about! I was aware that the ADuM was transformer coupled, but skipped over how it was actually implemented. Definitely will keep it in mind for the future. I did end up removing it when I moved to TMT.
Very nice, this for sure goes to my list of projects to try! I originally noticed this ADC for the 1980s copium since most stuff i have is 1980s soviet crap, but got scared by programming so didn't get far.
I can understand that feeling 😅 The beginner-friendly stuff is a little too basic, and the good stuff assumes you were born knowing how to deal with computer stuff... thank god someone came up with a Windows installer for the RP2040 C/C++ SDK, and even with that it has it's quirks, but I got used to them
Somehow I think I'm mentally retarded in the sense that I find it very hard to wrap my head around these programmatical tools. I've tried it, and I hope to get a system up and running soon-ish, but Excel is just very comfortable for the amount of data I process, although there are two very good points as to why I should use a 'standard' tool: - Dealing with larger quantities of data (say, from 100 runs) becomes very hard to deal with - Recreating the same plot is difficult because you have to manually fiddle with the plot area, etc.
@@NNNILabs i do get it, everything is neatly organized and premade Excel is always more convenient and stuff Though python does hold size advantages, as it's easier to process large amounts of data
14:45 hmm, I wouldn't call this "wild", it mostly looks like what I'd expect provided I ignore the frequency axis. An averaging filter is well known to have pretty meh frequency response, with unit gain only at multiples of f_S (the sampling frequency) and nulls at all other multiples of f_S/N for N-sample averaging. The problem here is that with a 100ms sampling period, you'd expect peaks at multiples of 10 Hz which is clearly not where they're at.
That's interesting... although I have to mention, the 'sampling period' in this case is just the ramp time, which is 20ms. Each conversion is three ramps and three reset phases (zero, reference, input), totaling 120ms.
@@NNNILabs Ah, 120ms sampling interval i.e. 8.33 Hz sampling rate indeed looks consistent with the graphs you got when doing averaging. Specifically, the expected difference between no averaging and N-point averaging (in dB) is:
10 log₁₀( (1-cos(N ω)) / (1-cos(ω)) / N² )
where ω = 2 π f / f_S
EDIT: or perhaps a nicer expression is:
20 log₁₀| sin(N ω / 2) / sin(ω / 2) / N |
@@MatthijsvanDuin Just tried the second formula, and it got me really close! There's still some kind of offset in the calculated result, and I had to change the formula slightly. I have to mention, I have no idea what I'm doing 😂 I would love to get in touch somewhere else so we can discuss this though, do you have a Discord account? You can find me there (basically online 24/7) under the same tag (@nnnilabs).
I've pinned the comment since this basically explains it.
This was a fascinating journey into an area that I've not yet explored. Thanks for posting this. Subscribed.
Glad you found it interesting!
We really need to ramp up ProPico production 🙏
real
Thanks for the presenting a very interesting project. If the sampling interval is 120ms it will not provide *any* 50Hz suppression, no matter how many averages are taken, as it will be sampling the 50Hz interference at the same phase angle in every 6th cycle.
I'm sure you know this but for the benefit of other viewers the ramp time has no relevance to the 50Hz suppression - as you observed, this ADC does *not* integrate the input signal over a single measurement cycle. That can only be achieved by averaging multiple measurements. For best NMRR the measurement sampling instances need to be phase locked to, and be equally spread over an integer number of cycles of the interfering signal -eg. averaging two measurements at 10ms intervals will provide a notch at 50Hz (and multiples) and significant NMRR.
To complicate matters, the sampling point within each ramp is proportional to the input signal at the sampling instance so whilst it will be the same for each measurement of a DC input signal, adding an AC interfering signal means the sampling point in each ramp will vary accordingly. I'll let you do the NMRR analysis from here onwards :)
The pinned comment pointed out the same thing actually, and you're right, trying to reject NM noise with a single slope ADC is not very straightforward😅
Thanks NNNI!
You're welcome!
Cool project! I might try building a crude version for myself because it seems like a good learning opportunity. I really enjoyed how you explained all the steps you went through to get it working. I can't wait to see what you do next!
Glad you enjoyed it! I tried to focus on actually explaining what I'm doing in the last couple of videos, so that seems to have worked at least 😅
If you do end up trying to replicate it, use lots of shielding, that seems to help.
@@NNNILabs I only plan on building it on a breadboard with fairly jellybean parts, just to get my feet wet. Thanks for the advice though, I will keep it in mind! I am really impressed with what you managed to accomplish with such a simple (and discrete!) ADC
@@justin.campbell You'll have to thank Jim Williams for this one😅
Great video man. Love your thoughtfull setup and practical use of sim and matlab. Really enjoyed it. Cheers
Matlab?!
@@NNNILabs Oh ehm did I say Matlab? I ment matplotlib ofc...😅
Wait, you were using excel all along 😯😯
@@Jajaho2 ding ding ding!
Cool! Very good performance overall.
Just as a note, didn't see whether you retained it, but the ADuM140x series can itself be rather noisy, and I would suspect that it might introduce timing jitter.
Since these devices use transformers to couple the signal across the isolation boundary, they can only transmit signal transitions (not the actual signal state). Basically they send one type of pulse when the signal transitions high, another type when it transitions low, and nothing in between. The output side needs to latch the signal state. The problem with this approach is that if some noise glitch or other event causes the output latch that stores the signal state to inadvertently flip, the output will be wrong until the input changes again. That would of course be very bad.
To fix this, the ADuM140x transmits "refresh" pulses even when you're not doing anything with the signal (the datasheet I saw says this is at ~1us period). It does this whenever the input signal goes more than 1us without transitions (is the case with your signals, I believe). But, of course this means that it's generating noise in the ~1MHz region and above all the time. Potentially worse is that I imagine there might be interactions between the refresh pulses and the data edge pulses. Imagine that you're sending a low-to-high transition but the refresh pulse has already started to send the original "low" state. I don't know how the chip would handle this, but I'd worry it might end up delaying your transition until the refresh pulse was done. This would quite possibly introduce timing jitter to the signals.
Not sure what the solution here might be... putting an MCU of any sort on the same rails as the circuit without destroying the performance is going to be very, very hard. Traditional optocouplers might be one approach, although they do have pretty bad timing distortion themselves (not sure how sensitive the circuit is to this as I haven't studied it). It might also be possible to allow the MCU and converter to share a ground reference, but split the power rails completely, and then isolate the digital signals by transmitting them through some reasonably large resistors (~1-10k) and re-buffering them in the converter power domain with some logic gates powered by the analog rails, to restore edge slew rate and drive strength, while still interrupting the noise current path from the MCU's GPIOs.
Thanks for the tip, that's something I never thought about! I was aware that the ADuM was transformer coupled, but skipped over how it was actually implemented. Definitely will keep it in mind for the future. I did end up removing it when I moved to TMT.
Very nice, this for sure goes to my list of projects to try! I originally noticed this ADC for the 1980s copium since most stuff i have is 1980s soviet crap, but got scared by programming so didn't get far.
I can understand that feeling 😅
The beginner-friendly stuff is a little too basic, and the good stuff assumes you were born knowing how to deal with computer stuff... thank god someone came up with a Windows installer for the RP2040 C/C++ SDK, and even with that it has it's quirks, but I got used to them
Fantastic work as usual!
Thanks!
Outstanding!!!
Wonderful 👏👌
The shitty Pico switcher strikes again!
For the last time, I hope 😅
why not use python or r to analyse the INL?
Though to be fair, excel is way more intuitive to use
Somehow I think I'm mentally retarded in the sense that I find it very hard to wrap my head around these programmatical tools. I've tried it, and I hope to get a system up and running soon-ish, but Excel is just very comfortable for the amount of data I process, although there are two very good points as to why I should use a 'standard' tool:
- Dealing with larger quantities of data (say, from 100 runs) becomes very hard to deal with
- Recreating the same plot is difficult because you have to manually fiddle with the plot area, etc.
@@NNNILabs i do get it, everything is neatly organized and premade
Excel is always more convenient and stuff
Though python does hold size advantages, as it's easier to process large amounts of data
Not good way too fast booh!