Question

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.

AD2_derivation_integration.thumb.png.b5ced6b208a509b115042c39377c6edb.png


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

Edited by lab!fyi

Share this post


Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0

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.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.