Simple impedance meter project with STM32F4 Discovery board
This post describes an experimental software-based impedance meter project that uses the STM32F4 Discovery board with very few additional components. The meter operates at a fixed exciting sinusoidal frequency of 59659 Hz, and it is capable to measure the impedance vector of a load, i.e. its resistance and reactance. A measurement is initiated by the user by pressing the blue button of the board and the readings are output to a terminal emulator program through the USB interface. The measurement principles are based on the article "An LMS Impedance Bridge – QEX Sept/Oct 2015" from Dr. George R. Steber.
The project and source code is available at the following link. It is assumed that the reader has background in the STM32 environment.
Overall operation
The block diagram of the illustration below shows the basic building blocks of the meter. The capacitor and resistor in addition to the interconnection elements, are the only external components required. However, note that an ideal realization should implement external buffers using op-amps for better performances.
The measurement process starts with a sine wave generator implemented as direct numerical calculation in software. The signal is a fixed frequency and is sent to a Digital-to-Analog converter (DAC) and it is outputted to the port PA4 of the board. The external resistor is used as a reference for measurement impedances and the value can be changed to better fit the measurement application.
Impedance measurements involve knowing the amplitude and phase of the sine wave at the external reference resistor input (reference channel) and at the load (measurement channel). These signals are sent to two 12-bit Analog-to-Digital (ADC) converters that are configured to acquire the data samples simultaneously. The digitized data, after applying a Hanning Window function, is supplied to the Goertzel algorithm that extracts the amplitude and phase of the signal for both channels.
The impedance is calculated with the following formula (complex numbers):
Z = REFERENCE_R * VM / (VR - VM)
Where:
- Z: impedance result (complex number)
- REFERENCE_R: value of external resistor
- VM: measurement channel reading (complex number)
- VR: reference channel reading (complex number)
This realization does not include alignment or calibration algorithms to improve the accuracy of the measurements, but the readings are still quite accurate.
Assembly
For the assembly of a prototype, I used components available in my junk box. I used a double-row female header for supporting the components and a SMA jack for connecting the loads. Connections must be performed to ports PA4, PA1 and PA2 of the Discovery board as illustrated in the block diagram above.
Operation
You will need to first clone the project available at link and import to your preferred Atollic TrueStudio Workspace, in case you will want to use this tool. From TrueStudio build the project and launch the debugger. For viewing the readings, launch a terminal emulator program on the computer and connect it to the micro-USB port of the board; you must to have installed the STM32 Virtual COM Port Driver from ST Microelectronics.
Launch the program from the debugger and you should see the message "*** Z Meter for STM32F4 ***" on the terminal emulator screen. Then connect a known load and press the blue button of the board to get the measurements.
Launch the program from the debugger and you should see the message "*** Z Meter for STM32F4 ***" on the terminal emulator screen. Then connect a known load and press the blue button of the board to get the measurements.
The readings have the following format:
29.85<-86.85, R:1.64, X:-29.81, Cs:89493.15, Ls:-79.52
Where the first numbers are the impedance in polar form (angle in degrees), R and X are the impedance in complex form, Cs is the capacitance in pF, and Ls is the inductance in uH.
Software description
The software is written in C language, it uses the Standard Peripheral and USB OTG libraries from ST, and it was build using Atollic TrueStudio IDE. Following are the more relevant blocks:
Signal generation
The sine wave generator is implemented as a direct numerical calculation in software implemented in siggen.c and siggen.h files. The sinewave is defined as a table of 128 12-bit values and is transferred to the DAC (DAC1) using DMA (DMA1_Stream5). Values are selected not to use the full dynamic range and overflow the ADC inputs. A timer (TIM6) is used to set the DMA update rate in order to output a frequency of 59659 Hz.
The screenshot below shows a scope capture of the sinewave signal generated numerically.
Data acquisition
The analog to digital conversion is performed by two Analog-to-Digital converters (ADC1 and ADC2) where the control code is implemented in sample.h and sample.c files. The ADCs are configured in simultaneous mode and use DMA access mode 2 to transfer the acquired data to memory automatically. The sample rate is set to 218750 Hz. During the acquisition it is disabled systick interrupts to reduce the noise.
Signal processing
The first step after acquiring the data from the ADCs is applying the Hanning window to minimize the effects of spectral leakage before applying the Discrete-Fourier-Transform (DFT) to the signal; in this case using the Goertzel algorithm. Hanning window function is implemented in windowing_fn.h and windowing_fn.c files and basically consist in pre-compute the coefficients of the Hanning function at the program initialization and multiply the acquired samples by the coefficients.
After applying the Hanning function, the samples are processed by the Goertzel algorithm to extract the signal magnitude and phase. This process is implemented in goertzel.h and goertzel.c files. The Goertzel algorithm is a technique for efficient evaluation of the individual terms of the discrete Fourier transform (DFT). In this case the Goertzel is configured to detect the measurement frequency of 59659 Hz for both channels. The block size (N) is set to 110; the result of ((N)*FREQ)/FSAMPLE must be an integer value.
Impedance calculation
Impedance calculation is implemented in MeasureZ() function in main.c after performing the signal processing described above from calls implemented in Measure() function. The impedance is calculated using the formula below and the results averaged over eight measurements to reduce the noise.
Z = REFERENCE_R * VM / (VR - VM)
Note that the resistance value of the external resistor must be specified in main.c; e.g.
#define REFERENCE_R 4740.0 /* Adjust to the actual implemented value */
Finally, the impedance is converted to polar form and calculated Cs and Ls, before sending the readings through USB using the virtual port serial class.
Conclusion
I expect that this project can be useful for building an experimental device for measuring the impedance of passive components and provides you some fundamentals about digital signal processing on the STM32 processor and impedance measurement principles. Also, this project can be used as a basis for a more complete and accurate impedance meter.
Comments
Post a Comment