Git Product home page Git Product logo

libsfra's Introduction

LibSFRA

A software-based small signal analysis and measurement tool for digital controlled power supplies and more.

  • Platform-independent, this library can run on any hardware, F28379 and STM32F334 have been tested. Theoretically, it will work on the STM32F0 series, even on 8-bit microcontrollers.
  • High performance and minimal negative impact, functions that ISR routines may call contains minimal calculations.
  • FPU is not compulsory, functions that ISR routines may call can be fixed-point only.
  • MODBUS front-end and MATLAB scripts are available, data transfer is much faster than TI's closed-source implementation.
  • Written in C99, works on most compilers.
  • Multiple SFRA instances can co-exist.
  • Utilization of local hardware accelerations is possible, e.g., trigonometric functions can be faster and more accurate on some C2000 platforms (e.g., F28379).

Usage

Add all .c and .h files to the Makefile or your managed project, steps may vary, depend on your IDE, build tools, and toolchains.

The following example shows how to add this library to the Makefile generated by STM32CubeIDE:

C_SOURCES =  \
$(wildcard libsfra/*.c) \
...

C_INCLUDES =  \
-Ilibsfra \
...

Create configuration header

Create a file named "libsfra_config.h":

#ifndef INC_LIBSFRA_CONFIG_H_
#define INC_LIBSFRA_CONFIG_H_

// Use fixed-point
#define SFRA_INT 1

// No tests
#define SFRA_HAS_TEST 0

#endif /* INC_LIBSFRA_CONFIG_H_ */

Declare SFRA struct and prepare buffers

// Size of each SFRA result buffer field
#define SFRA_BUF_SIZE 100

typedef struct {
    float freq[SFRA_BUF_SIZE];  // In Hz, log-spaced
    float mag[SFRA_BUF_SIZE];   // In dB
    float phase[SFRA_BUF_SIZE]; // In degrees
} sfra_results_t;

// Holds measured bode plot
sfra_results_t sfra_results;

// Declare the SFRA instance
sfra_t sfra = {
    .config.isrFreq = 100000,   // Sampling frequency
    .config.freqStart = 10,     // Start frequency
    .config.freqStep = 1.584893192461113,  // Frequency step (log-spaced)
    .config.vecLength = SFRA_BUF_SIZE,     // Number of sweeps
    .results.freqVect = sfra_results.freq, // Points to the frequency vector
    .results.magnitudeVect = sfra_results.mag,	// Points to the magnitude vector
    .results.phaseVect = sfra_results.phase   // Points to the phase vector
};

freqStep is always 10 powers the reciprocal of the sweep number per decade.

The stop frequency can be calculated as freqEnd = freqStart * power(freqStep, vecLength - 1).

Given freqStep and freqStart, one can find the closest vecLength from a given stop frequency (freqEndExpected): floor(log(freqEndExpected/freqStart) / log(freqStep) + 1).

Note that vecLength should never exceed the buffer size (SFRA_BUF_SIZE, in this case).

Add initialization and background task calls

void main(void) {
...
    // Initialize common SFRA infrastructures
    sfra_init_all();
...
    while (1) {   // Main Loop
        ...

        // Run background tasks for each SFRA instance
        sfra_background_task(&sfra);

        ...
    }
}

Setup injection and measurement

The following code demonstrates how to measure the duty cycle to output voltage transfer function in a DC/DC converter.

// Measured output voltage, populated by ADC + DMA
float adc_result_output_voltage;

// Normally this is an ISR routine
void control_law_run(void) {
    // Duty cycle
    float duty = 1.0F;

    // Generate perturbation
    float preturb_magnitude = 1.0F;
    float perturb = sfra_inject_int32(&sfra) / (float) FAST_SIN_TABLE_SCALE;

    // Add perturbation
    duty += preturb_magnitude * perturb;

    // Scale both for a better accuracy
    float mon_in = duty * (float) 256.0F;
    float mon_out = adc_result_output_voltage * (float) 256.0F;

    // Update SFRA state
    sfra_monitor_int32(&sfra, mon_in, mon_out);
}

Alternatively, the digital filter in filter_rc.h can be used to test the SFRA without an actual power stage:

const float dc_gain = 100.0F;

// Normally this is an ISR routine
void control_law_run(void) {
    float filter_input = 1.0F;

    // Generate perturbation
    float preturb_magnitude = 1.0F;
    float perturb = sfra_inject_int32(&sfra) / (float) FAST_SIN_TABLE_SCALE;

    // Add perturbation
    filter_input += preturb_magnitude * perturb;

    // Run the filter
    float filter_output = dc_gain * vFilterRCRun(&test_filter, filter_input);

    // Scale both for a better accuracy
    float mon_in = filter_input * (float) 256.0F;
    float mon_out = filter_output * (float) 256.0F;

    // Update SFRA state
    sfra_monitor_int32(&sfra, mon_in, mon_out);
}

Start SFRA sweeping

Call sfra_start() in a non-ISR context, and poll sfra_is_done(). sfra.internal_state.freqIndex indicates the progress. Once finished, call sfra_clear_done() to clear the done flag.

Acquire the result

Struct sfra_results now holds the bode plot.

MODBUS

Add a light-weight MODBUS serial (Supports RS485) implementation to expose the results (also settings, of course). Sometimes, the application has already implemented MODBUS.

T.B.D

MATLAB provides functions to access MODBUS (supports serial and TCP) and plot the figure. With the help of ESP8266 as a MODBUS RS485-TCP bridge, it is now possible to wirelessly acquire the bode plot from a MCU on the hot-side.

Direct memory access

This approach requires minimal modification to the existing application code. However, it is subjected to certain limitations on certain platforms and IDEs.

This approach works great on TI's C2000 platforms, where Code Composer Studio (CCS) allows you to inspect and edit the memory content without pausing the code execution. One can start the sweeping by setting sfra.internal_state.start to 1 and copy the results directly from the Memory view.

However, this is not true on most other platforms. For instance, GDB cannot read the memory of an STM32 MCU unless the code execution has paused. __ Before pausing the code, make sure to disable the power stage and/or switch off its power. __

TODOs

  • Verify the accuracy on different topologies
  • MODBUS demo project

libsfra's People

Contributors

rikka0w0 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.