Manuel Caballero / LEM-HAIS

LEM_HAIS.cpp

Committer:
mcm
Date:
2017-10-10
Revision:
3:6bc9b8543f13
Parent:
2:c865023c4b20
Child:
4:5002bb8e907b

File content as of revision 3:6bc9b8543f13:

/**
 * @brief       LEM_HAIS.h
 * @details     Current transducer. For the electronic measurement of currents: 
 *              DC, AC, pulsed..., with galvanic separation between the primary
 *              circuit and the secondary circuit.
 *              Function file.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        19/September/2017
 * @version     19/September/2017    The ORIGIN
 * @pre         NaN.
 * @warning     NaN
 * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
 */

#include "LEM_HAIS.h"


LEM_HAIS::LEM_HAIS ( PinName OUTPUT, float myVoltageDivider, float myADC_Vref, float myIPM )
    : _OUTPUT               ( OUTPUT )
{
    _LEM_HAIS_V_OFFSET   =   0.0;
    _VOLTAGE_DIVIDER     =   myVoltageDivider;
    _ADC_VREF            =   myADC_Vref;
    _LEM_HAIS_IPM        =   myIPM;
}


LEM_HAIS::~LEM_HAIS()
{
}



/**
 * @brief       LEM_HAIS_GetVoltage   ( void )
 *
 * @details     It performs a new voltage measurement.
 *
 * @param[in]    NaN.
 *
 * @param[out]   myAuxVoltage:   All the samples.
 *
 *
 * @return       The actual voltage.
 *
 *
 * @author      Manuel Caballero
 * @date        19/September/2017
 * @version     27/September/2017   RMS calculations included.
 *              19/September/2017   The ORIGIN
 * @pre         NaN.
 * @warning     NaN.
 */
LEM_HAIS::Vector_LEM_HAIS_voltage_t  LEM_HAIS::LEM_HAIS_GetVoltage ( void )
{
    uint32_t     i   =   0;
    
    Vector_LEM_HAIS_voltage_t myAuxVoltage;
    

    for ( i = 0; i < SAMPLE_DATA; i++ )
    {       
        myAuxVoltage.OUTPUT_Voltage[i]     =   _OUTPUT.read();
        
        wait_ms ( 1 );                                                        
    }
    

    return   myAuxVoltage;
}



/**
 * @brief       LEM_HAIS_CalculateCurrent   ( Vector_LEM_HAIS_voltage_t , float , LEM_HAIS_filter_status_t )
 *
 * @details     It calculates the actual current.
 *
 * @param[in]    myVoltages:    Both voltages, OUTPUT and Vref voltages.
 * @param[in]    Device_Vref:   Device voltage reference.
 * @param[in]    myFilter:      If a low pass filter is enabled/disabled.
 *
 * @param[out]   NaN.
 *
 *
 * @return       The calculated current.
 *
 *
 * @author      Manuel Caballero
 * @date        19/September/2017
 * @version     19/September/2017   The ORIGIN
 * @pre         LEM_HAIS_GetVoltage function MUST be called first.
 * @warning     NaN.
 */
LEM_HAIS::Vector_LEM_HAIS_current_t  LEM_HAIS::LEM_HAIS_CalculateCurrent ( Vector_LEM_HAIS_voltage_t myVoltages, float Device_Vref, LEM_HAIS_filter_status_t myFilter )
{
    Vector_LEM_HAIS_current_t myAuxCurrent;
    
    float    myAuxSQI               =  0;
    float    myAuxVol               =  0;
    float    myI_filtered           =  0;
    float    myI_Previousfiltered   =  0;
    uint32_t i                      =  0;

    
    
    // Check if we want to use a low pass filter
    if ( myFilter    ==  FILTER_ENABLED )
    {
        myI_Previousfiltered =   _VOLTAGE_DIVIDER * _ADC_VREF * myVoltages.OUTPUT_Voltage[0];  
        i                    =   1;
    }
    else
        i                    =   0;
        
    
    // Calculate the RMS current 
    for ( ; i < SAMPLE_DATA; i++ )
    {        
        myAuxVol     =   _VOLTAGE_DIVIDER * _ADC_VREF * myVoltages.OUTPUT_Voltage[i];                       
        
        if ( myFilter    ==  FILTER_ENABLED )
        {
            myI_filtered    =   ( ( 1 - 0.5 ) * myAuxVol ) + ( 0.5 * myI_Previousfiltered );
            
            myI_Previousfiltered = myI_filtered;
            
            myAuxSQI     =   ( 8.0 / 5.0 ) * ( ( myI_filtered + _LEM_HAIS_V_OFFSET ) - Device_Vref ) * _LEM_HAIS_IPM;
        }
        else
            myAuxSQI     =   ( 8.0 / 5.0 ) * ( ( myAuxVol + _LEM_HAIS_V_OFFSET ) - Device_Vref ) * _LEM_HAIS_IPM;   
        
        
        myAuxSQI    *=   myAuxSQI;
        
        
        myAuxCurrent.Current      +=   myAuxSQI;                                                        
    }
    
    
    if ( myFilter    ==  FILTER_ENABLED )
        i    =   1;
    else
        i    =   0;
        
    
    myAuxCurrent.Current    /=   ( float )( SAMPLE_DATA - i );
    myAuxCurrent.Current     =   sqrt( myAuxCurrent.Current );
    
    

    return   myAuxCurrent;
}



/**
 * @brief       LEM_HAIS_SetAutoOffset ( float , float )
 *
 * @details     It calculates the offset automatically ( at 0A current ).
 *
 * @param[in]    ADC_Vref:          Voltage reference for the ADC.
 *
 * @param[out]   NaN.
 *
 *
 * @return       The actual offset volatge.
 *
 *
 * @author      Manuel Caballero
 * @date        19/September/2017
 * @version     19/September/2017   The ORIGIN
 * @pre         NaN.
 * @warning     This test has to be perfomed at 0A ( no current through
 *              the sensor at all ).
 */
float  LEM_HAIS::LEM_HAIS_SetAutoOffset ( float Device_Vref )
{
    uint32_t i          =   0;
    float    myVoltage  =   0;
    
    
    // Calculate the average, get a new measurement every 0.25s
    for ( i = 0; i < CALIBRATION_AVERAGE; i++ ){
        myVoltage   +=   _OUTPUT.read();
        wait ( 0.25 );
    }
    
    myVoltage   /=   ( float )CALIBRATION_AVERAGE;
    
    
    // Store the offset
    _LEM_HAIS_V_OFFSET   =   Device_Vref - ( _VOLTAGE_DIVIDER * myVoltage * _ADC_VREF );
     
    //_LEM_HAIS_V_OFFSET   =   Device_Vref - ( 2.0 * myVoltage * 3.3 );
    


    return   _LEM_HAIS_V_OFFSET;
}