040-Third generation software development-new waveform capture algorithm

Header image

Third generation software development-new waveform capture algorithm

Article directory

  • Third generation software development-new waveform capture algorithm
    • Project Introduction
    • New waveform capture algorithm
      • Code explanation


Keywords:
Qt
Qml
Catch the wave,
Interception,
Waveform

Project introduction

Welcome to our QML & C++ project! This project combines the power of QML (Qt Meta-Object Language) and C++ to develop excellent user interfaces and high-performance backend logic.

In the project, we leveraged QML’s declarative syntax and visual design capabilities to create a modern user interface. Through intuitive coding and reusable components, we can quickly develop rich and diverse interface effects and animation effects. At the same time, we use QML’s powerful integration capabilities to easily integrate the underlying logic and data model of C++ into the front-end interface.

On the backend side, we use C++ to write high-performance algorithms, data processing, and computational logic. C++ is a powerful programming language that offers excellent performance and scalability. Our team is committed to optimizing code and reducing resource consumption to ensure that our projects run efficiently on a variety of platforms and devices.

Whether you’re interested in QML and C++ development or need us to build complex user interfaces and backend logic for you, we’re ready to support you. Please feel free to contact us and let’s build a modern, high-performance QML & C++ project together!

Important?

?The price of this column will increase after the third generation soft development update.

New waveform capture algorithm

Hey hey hey, if you happen to have seen my previous wave capture algorithm, you can take a look here. This version is a demonstration version for inspection and is aimed at the pure waveform produced by the signal generator. In actual use, it was found that no matter how the parameters were adjusted, it was not ideal. So a new gambling algorithm was born.

The link is here: https://dreamlife.blog.csdn.net/article/details/128716820

image-20230807183545114

The new blog capture algorithm simply removes the violence and directly determines whether the peak value exceeds the threshold. If it exceeds the threshold, waveform analysis is performed, and the stock capture does not continue. The core algorithm is as follows:

/**
 * @brief XXXX::wavesCatch extracts the wave peak function
 * @param iAisle
 */
bool XXXX::wavesCatch(int iAisle)
{
    // @ld
    m_wavesStartIndex = 0;
    m_wavesEndIndex = 0;


    m_yData.resize(m_windowDataSize - m_stimeNumber);

    m_yData.at(0) = m_windowData[iAisle + 1].at(0 + m_stimeNumber);
    m_yData.at(1) = m_windowData[iAisle + 1].at(1 + m_stimeNumber);
    for(int i=2;i<m_windowDataSize-m_stimeNumber;i + + )
    {
        m_yData.at(i) = (m_windowData[iAisle + 1].at(i + m_stimeNumber) + m_windowData[iAisle + 1].at(i-1 + m_stimeNumber) + m_windowData[iAisle + 1].at(i-2 + m_stimeNumber))/3;
    }

    m_wavesMaxIndex = m_wavesMaxIndex - m_stimeNumber;
    m_wavesMinIndex = m_wavesMinIndex - m_stimeNumber;

    //

    if(m_wavesMaxIndex<m_wavesMinIndex)
    {

        // m_wavesStartIndex
        for(int iStart=m_wavesMaxIndex-2;iStart>=2;iStart--)
        {
            // around the average
            if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg))
            {
                //B. minimum value
                if((m_yData.at(iStart)<=m_yData.at(iStart + 1) & amp; & amp; m_yData.at(iStart) <= m_yData.at(iStart-1))
                    // Find the rapid increase point
                    || (m_yData.at(iStart + 2) > m_yData.at(iStart + 1) > m_yData.at(iStart)
                         & amp; & amp; (m_yData.at(iStart + 2) -m_yData.at(iStart + 1)) > 5*(m_yData.at(iStart + 1) -m_yData.at(iStart))))
                {
                    m_wavesStartIndex = iStart;
                    break;
                }
            }
        }
        for(int iEnd=m_wavesMinIndex + 2;iEnd<int(m_yData.size())-2;iEnd + + )
        {
            // around the average
            if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin))
            {
                //B. maximum
                if((m_yData.at(iEnd)>=m_yData.at(iEnd + 1) & amp; & amp; m_yData.at(iEnd) >= m_yData.at(iEnd-1))
                    // Find the gentle point
                    || (m_yData.at(iEnd-2) < m_yData.at(iEnd-1) < m_yData.at(iEnd)
                         & amp; & amp; (m_yData.at(iEnd-1) -m_yData.at(iEnd-2)) > 5*(m_yData.at(iEnd) -m_yData.at(iEnd-1))))
                {
                    m_wavesEndIndex = iEnd;
                    break;
                }
            }
        }
    }
    else
    {
        for(int iStart=m_wavesMinIndex-2;iStart>=2;iStart--)
        {
            // around the average
            if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin))
            {
                //B. maximum
                if((m_yData.at(iStart)>=m_yData.at(iStart + 1) & amp; & amp; m_yData.at(iStart) >= m_yData.at(iStart-1))
                    // Find the rapid increase point
                    || (m_yData.at(iStart + 2) < m_yData.at(iStart + 1) < m_yData.at(iStart)
                         & amp; & amp; (m_yData.at(iStart + 1) -m_yData.at(iStart + 2)) > 5*(m_yData.at(iStart) -m_yData.at(iStart-1))))
                {
                    m_wavesStartIndex = iStart;
                    break;
                }
            }
        }
        for(int iEnd=m_wavesMaxIndex + 2;iEnd<int(m_yData.size())-1;iEnd + + )
        {
            // around the average
            if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg))
            {
                //B. minimum value
                if((m_yData.at(iEnd)<=m_yData.at(iEnd + 1) & amp; & amp; m_yData.at(iEnd) <= m_yData.at(iEnd-1))
                    // Find the gentle point
                    || (m_yData.at(iEnd-2) > m_yData.at(iEnd-1) > m_yData.at(iEnd)
                         & amp; & amp; (m_yData.at(iEnd-2) -m_yData.at(iEnd-1)) > 5*(m_yData.at(iEnd-1) -m_yData.at(iEnd))))
                {
                    m_wavesEndIndex = iEnd;
                    break;
                }
            }
        }
    }

    if(m_wavesStartIndex == 0 || m_wavesEndIndex == 0)
        return false;

    emit signal_wavesCatched(iAisle,m_wavesStartIndex + m_stimeNumber,m_wavesMaxIndex + m_stimeNumber,m_wavesMinIndex + m_stimeNumber,m_wavesEndIndex + m_stimeNumber);
    return true;
}

The general flow chart is as follows:

image-20230807223052252

Code explanation

  1. First, we reset some parameters to ensure that we start with the same

     m_wavesStartIndex = 0;
        m_wavesEndIndex = 0;
        m_yData.resize(m_windowDataSize - m_stimeNumber);
    
  2. Next, we perform a simple smoothing process on our data

     m_yData.at(0) = m_windowData[iAisle + 1].at(0 + m_stimeNumber);
        m_yData.at(1) = m_windowData[iAisle + 1].at(1 + m_stimeNumber);
            for(int i=2;i<m_windowDataSize-m_stimeNumber;i + + )
        {
            m_yData.at(i) = (m_windowData[iAisle + 1].at(i + m_stimeNumber) + m_windowData[iAisle + 1].at(i-1 + m_stimeNumber) + m_windowData[iAisle + 1].at(i-2 + m_stimeNumber))/3;
        }
    
  3. Next, we need to perform a coordinate transformation on the maximum value and minimum value we calculated before

     m_wavesMaxIndex = m_wavesMaxIndex - m_stimeNumber;
        m_wavesMinIndex = m_wavesMinIndex - m_stimeNumber;
    
  4. Next, we can determine whether the peak or trough comes first by judging the coordinates corresponding to the maximum value and the minimum value.

    if(m_wavesMaxIndex<m_wavesMinIndex)
    
  5. Find the starting point and key points respectively

     for(int iStart=m_wavesMaxIndex-2;iStart>=2;iStart--)
            {
                // around the average
                if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg))
                {
                    //B. minimum value
                    if((m_yData.at(iStart)<=m_yData.at(iStart + 1) & amp; & amp; m_yData.at(iStart) <= m_yData.at(iStart-1))
                        // Find the rapid increase point
                        || (m_yData.at(iStart + 2) > m_yData.at(iStart + 1) > m_yData.at(iStart)
                             & amp; & amp; (m_yData.at(iStart + 2) -m_yData.at(iStart + 1)) > 5*(m_yData.at(iStart + 1) -m_yData.at(iStart))))
                    {
                        m_wavesStartIndex = iStart;
                        break;
                    }
                }
            }
            for(int iEnd=m_wavesMinIndex + 2;iEnd<int(m_yData.size())-2;iEnd + + )
            {
                // around the average
                if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin))
                {
                    //B. maximum
                    if((m_yData.at(iEnd)>=m_yData.at(iEnd + 1) & amp; & amp; m_yData.at(iEnd) >= m_yData.at(iEnd-1))
                        // Find the gentle point
                        || (m_yData.at(iEnd-2) < m_yData.at(iEnd-1) < m_yData.at(iEnd)
                             & amp; & amp; (m_yData.at(iEnd-1) -m_yData.at(iEnd-2)) > 5*(m_yData.at(iEnd) -m_yData.at(iEnd-1))))
                    {
                        m_wavesEndIndex = iEnd;
                        break;
                    }
                }
            }
    
  6. Determine the waveform characteristics. If it meets the waveform characteristics, it will send a signal and return true; if it does not meet the waveform characteristics, it will return False.

     if(m_wavesStartIndex == 0 || m_wavesEndIndex == 0)
            return false;
    
        emit signal_wavesCatched(iAisle,m_wavesStartIndex + m_stimeNumber,m_wavesMaxIndex + m_stimeNumber,m_wavesMinIndex + m_stimeNumber,m_wavesEndIndex + m_stimeNumber);
        return true;
    

Blog Signature 2021