lab!fyi

Members
  • Content Count

    7
  • Joined

  • Last visited

  1. @attila, thanks for averaging workarounds. Is it planned in some future release that script can access GUI-averaged trace also (and have still access to raw if wish)? There is also related problem. When perform any manual operation on traces eg just enable-disable Ref trace averaging process always resets. Eg if wanted to create snapshot of long exp averaging process you lose accumulated data on source channel. Second little issue is with trace interpolation. There is automation that in some cases switches from linear interpolation to discrete when in log scale mode, probably due to performance considerations. However when linear averaging it makes wrong decision for most cases because graphing performance becomes irrelevant. It would be much helpful to have manual control on this eg dropdown with [Auto|Linear|Discrete] option. Also, it would be interesting to have phase trace option like on some high-end scopes + script access from script to real and imaginary components.
  2. Forgot to mention little problem. It seems to be no counterpart for Oversampling setting in Scope1.Time object. Had to use some workaround to get the setting value.
  3. Hi, since forum search did not yield much on subject and there seem to be no built in functions did write little something and decided to share below: Script is quite automatic. It will account for sampling rate, memory depth, oversampling changes in real time - just run it to auto create and configure Ref* channels that will display functions. Possible need fiddle Range a little for integration. If wish reset to auto values just disable/delete Ref* and it will instantly re-enable in default configuration. Attached script is provided in demo mode, does integral(derivative(x)) functional check and integral(x). Unneeded doMath*() stuff can be commented out in main() function. If wish for derivative to start from 0 (currently it will remember DC offset for later signal reconstruction) set bDerivativeRetainsDCOffset = false; Code that accounts for Time changes is quite generic so script can be easily expanded with other doMath*() routines. Code tested on: WaveForms version 3.8.10 beta 64-bit Qt5.6.3 Windows 7 // Derivation/Integration for WaveForms, v0.1 // By lab!fyi <info@lab.fyi> // http://lab.fyi/oscilloscope_scripts/derivation_integration/index.html // This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. // Uncheck or delete Ref[1|2] in Run mode to reset units to automatic values // Config bDerivativeRetainsDCOffset = true; oChannel = Scope1.Channel1; // Used for Ref config detection // Derivative >>> function _derivative(aIn, aOut) { aOut[0] = 0; if (bDerivativeRetainsDCOffset) { aOut[0] = aIn[0] * iSTRate; } for (var i = 1; i < aIn.length; i++) { aOut[i] = (aIn[i] - aIn[i - 1]) * iSTRate; } } function derivative(oIn, oOut) { var aO = oOut.data; _derivative(oIn.data, aO); oOut.data = aO; } // <<< Derivative // Integral >>> function _integral(aIn, aOut) { var f = 0; for (var i = 0; i < aIn.length; i++) { f += aIn[i] / iSTRate; aOut[i] = f; } } function integral(oIn, oOut) { var aO = oOut.data; _integral(oIn.data, aO); oOut.data = aO; } // <<< Integral // Config >>> function getSTRate() { return Scope1.Time.Rate.value * (oChannel.data.length / Scope1.Time.Samples.value); } function config(oIn, oOut, fScale) { if (!oOut.enable || !oOut.checked || bInit) { oOut.setEnable(true); oOut.checked = true; oOut.Clone(oIn); oOut.Range.value *= fScale; print ( "(Re)Enabled/Checked & Cloned " + "'" + oIn.name + "'" + " -> " + "'" + oOut.name + "'" ); } if ( (oOut.data.length != oIn.data.length) || (iSTRate != getSTRate()) ) { var iRange = oOut.Range.value; var iOffset = oOut.Offset.value; oOut.Clone(oIn); oOut.Range.value = iRange; oOut.Offset.value = iOffset; } } // <<< Config // ------------------------------------------------ function doMath1(oIn, oOut) { config(oIn, oOut, iSTRate); derivative(oIn, oOut); } function doMath2(oIn, oOut) { config(oIn, oOut, (1 / iSTRate)); integral(oIn, oOut); } function main() { if (!('Scope1' in this)) throw("Please open a Scope instrument"); Scope1.run(); iSTRate = getSTRate(); while (Scope1.State.value == 6) { while (Scope1.wait()) { // integral(derivative(x)) doMath1(Scope1.Channel1, Scope1.Ref1); doMath2(Scope1.Ref1, Scope1.Ref2); // integral(x) doMath2(Scope1.Channel1, Scope1.Ref3); bInit = false; iSTRate = getSTRate(); } } } // ------------------------------------------------ bInit = true; main(); Scope1.stop(); derivation_integration.dwf3script
  4. Hi, thanks for info. Seems then currently only way to get normalized FFT trace is in SA then, got it working: As improvements would look for cursors in script plot window and possibility to write trace back into SA window like with Scope. Currently writing little "math engine" for derivation/integration and suffered some due to lack of documentation. Is this + built in best there is? https://reference.digilentinc.com/reference/software/waveforms/waveforms-3/reference-manual#script1 There is no section for SA at all for example.
  5. That would be fun to play with And thanks for code snippet! However I started messing with SA and instantly hit brick wall due to 20MS/s / 10MHz limit (I understand why it is good for generic user), but maybe little "Extended" option could fix it for enthusiastic ones making full sampling rate available, after all it is available in Scope anyway? Or is there already way to "unlock"? Another handy improvement would be adding dBm + ohm ref to unit choices like on some other scopes. Edit: Did try NA on little different filter with external gen. Overall works but cannot fully normalize vs ref due to no math. More interesting experiment was with TDR. It also certainly works but again cannot fully normalize and also seemningly no way to switch off unneeded traces on FFT plot. Edit 2: Did not find built-in derivative or integral functions or even someone missing them on the Internet. Do I have to write own scripts for these or there is something around and I just did not find it? function doScope() { print("Running Scope script"); Scope1.single(); if (!Scope1.wait()) return; Scope1.Ref1.Clone(Scope1.Channel1); Scope1.Ref2.Clone(Scope1.Channel2); var aR1 = Scope1.Ref1.data; var aR2 = Scope1.Ref2.data; var aC1 = Scope1.Channel1.data; var aC2 = Scope1.Channel2.data; for (var i = 0; i < (aC1.length - 1); i++) { aR1[i + 1] = aC1[i + 1] - aC1[i]; aR2[i + 1] = aC2[i + 1] - aC2[i]; } aR1[0] = 0; aR2[0] = 0; aR1[aC1.length - 1] = 0; aR2[aC2.length - 1] = 0; Scope1.Ref1.data = aR1; Scope1.Ref2.data = aR2; } if(!('Scope1' in this)) throw("Please open a Scope instrument"); //for (var i = 0; i < 10; i++) doScope();
  6. Hi, thanks for info, any plans for math on FFT? This would be very useful in some cases.
  7. Hi, I'm having some little trouble with WF. It's complex software so maybe missing something, but may be actual problems, two of them: 1) Wfm math in FFT window is acting little different than expected. I'm doing 0-50MHz sine sweep with ext gen on some filter and would like to see normalized response graph. For that I first create Ref 1 trace using Peak Hold Continuous. Then create filter response trace. Now try to get final plot using Math 1. No desired result since it calculates on current values, not the PHC plots! 2) Persistence window is not taking into account interpolation setting. It should be doing sin(x)/x but instead is doing linear. Also it would be helpful if interpolation setting is not deep in the menu but more easily accessible and perhaps could be individually steered for both Scope and Persistence window. Min/Max is also acting bit weird with low sample counts.