From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Example Code

EXIGEN: A signal generator for structural dynamics

Code and Documents

Attachment

Download All

Overview

In academic situation, preparing practical training for students in structural dynamics, willing to obtain the frequency response function of a mechanical system, both signals are necessary: one excitation and one acceleration. The second one can be got from an accelerometer connected to a DAQ board. The excitation (the force) is often obtained thanks an instrumented impact hammer. Impact hammer delivers a sharp signal, close to a Dirac impuls and therefore covers a wide range of frequency. But sometimes a more customized signal is useful so that a signal generator is required. Of course, the generator has to be synchronized with the measurement of the response of the tested frame and must be managed from the analysis software. Some NI devices enable signal generation in PCI/PXI/USB configurations but a less expensive option can be considered when the signal accuracy is not very important. Remember that, any way, the measurement of the signal is done thanks a force sensor. This article deals with appropriate techniques enabling signal generation from a computer sound card. Of course, the excitation of the structure is obtained by connecting a power suplier behind the sound device and before a shaker.

Sound library

Microsoft Winmm

The method uses the library Windows SDK  NI\...\CVI\sdk\lib\winmm.lib

Header: Mmsystem.h  (include Windows.h)

DLL: Winmm.dll

See the site at address:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd743834(v=vs.85).aspx

Library functions

- waveOutGetNumDevs         returns the number of sound boards

- waveOutGetDevCaps          returns the abilities of the sound boards

- waveOutOpen                    opens a sound board

- waveOutSetVolume            sets the sound volume

- waveOutPrepareHeader      prepares a sound board for sounding

- waveOutWrite                    writes a wave and delivers a signal

- waveOutGetVolume            gets the current sound volume

- waveOutUnprepareHeader   releases the sound board

- waveOutReset                    clears the sound board (stop the signal)

- waveOutClose                    closes the sound board

Method

1/ automatic scanning of the available soud devices (for output)

2/ manual selection of a device

3/ open a sound device and set some parameters, mainly the frequency of the outputs, the number of channels (mono/stereo), the bits per samples.

4/ form a wave (sinus, white noise or scanning sinus) with the wished frequency and duration

5/ prepare the device for playing

5/ play the wave (asynchroneously)

When the signal is played it becomes be possible for the user to:

- change the sound volume

- stop the signal generation

- change the signal type

User interface

exigen.bmp

The uir includes controls, mainly:

- a knob for the volume adjustment

- a knob for the signal duration, a button enables its continuous repetition

- a knob for the frequency (or the final frequency in case of a sweep sinus)

- a ring for choosing the output sound board

- a ring for choosing the signal type (sinus, sweep sinus, white noise, hammer)

- a traditional EXIT button

- a STOP button for stopping the running signal

- A GO button for launching the signal generation

- A graph for plotting the FFT modulus of the signal and including two buttons for the display frequency range and a linear/log switch.

C Source code

Callbacks

DeviceCallback

Callback of the device ring. It stops the running signal, closes the current board and opens the new one.

RunCallback

Sets the signal and displays its FFT

Generates the signal on the output board

StopCallback

Resets the current board

ExitCallback

Exits the program

FreqCallback

The frequency can be adjusted thanks a knob and two button (UP and DOWN) connected to this callback. The output is reset (sound stops).

dBCallback

Changes the volume of the output. Signal goes on.

WtypeCallback

Callback of the signal type ring. Resets the output.

DurationCallback

Callback of the duration knob and the repetition button. Resets the output.

BodeCallback

Switchs between linear and Bode (log-log) FFT display. Acts on the graph

FreqRangeCallback

Set the FFT range frequency.

WaveOutCallback

Callback used by the output board when an event occurs among:

- WOM_DONE: the signal is terminated (or the board has been reset)

- WOM-CLOSE: the board is closed

- WOM_OPEN: the board is opened.

This callback manages two flags:

- openflag which indicates if a board is currently open or not

- runflag which indicates if a signal is currently running or not

Static functions

PlotFFT

Plots the FFT of the signal either in linear coordinates either in a log-dB coordinates

LookForOutputDevices

This function scans the hardware and set the available device ring. It uses the library functions waveOutGetNumDevs and waveOutGetDevCaps for getting the device names.

CloseSignalChannel

Closes the current channel. Uses the library functions waveOutReset, waveOutSetVolume and waveOutClose. The intial board volume is restored before closing.

OpenSignalChannel

This function open a channel. It previously closes any other open channel. It keeps in mind the initial volume level. It uses the library functions waveOutOpen and waveOutGetVolume. waveOutOpen is called with the adequat parameters gathered in a structure WAVEFORMATEX : the format (PCM), the number of channels (we use 1 channel for driving a shaker), the output rate (here 44100 Hz), the bytes per second, the block alignment, the number of bits per signal sample. All these values come from constants or macros which are defined at the beginning of the source code.

SetSignal

Releases the memory already allocated, if any. Allocates an array of SIGWORD values (SIGWORD for 'signal word'). This type is currently defined as a signed 32-bit integer. The number of values constituting the array is equal to one plus the duration multiplied by the output rate.

- the white noise if generated thanks the CVI Analysis Library function WhiteNoise.

- the sinus is generated according the chosen frequency

- the sweep sinus is generated with a frequency increasing from 1Hz to the chosen frequency during the chosen duration

- the hammer impact is simulated thanks a sinus bulb risen at the power 0.4. The duration impact is on hundred shorter than the chosen duration.

GenerateSound

Prepares the channel, rises the runflag and switches on the according virtual led, launches the signal on the sound board. Uses the functions waveOutUnprepareHeader, waveOutPrepareHeader and waveOutWrite. The signal is asynchronus so that the uir remains available for the user.

Main

Displays the panel and manages the events.

Constants

Signal generation:

#define NODEV            0xFFFF

#define MAXSIGWORD        (~(DWORD)0>>1)

#define AMPLITUDE         MAXSIGWORD

#define NCHAN            1

#define RATE            44100  // among 8.0-11.025-22.05-44.1 kHz

math:

#define M_PI    3.1415926535897932384626433832795

#define M_2PI    6.283185307179586476925286766559

Macros

Signal generation:

#define BITSPERSAMPLE    (8*sizeof(SIGWORD))

#define BYTESPERSEC        (RATE*NBLOCKALIGN)

#define NBLOCKALIGN        (NCHAN*BITSPERSAMPLE/8)

Error management:

#define FCT    "EXIGEN ("__FUNCTION__")"

#define mmErrChk(fct) if (mmres=(fct)) goto mmstop;

#define mmErrDisp    if (mmres) \

    {    char txt[256]; \

        sprintf(txt,"MMSYSERR %d",mmres); \

        MessagePopup(FCT,txt);        }

Program variable types

typedef int SIGWORD;  // signed type mandatory

typedef enum _STYPE {S_WHITE, S_SINUS, S_SINSWEEP, S_HAMMER} STYPE;

typedef enum _LOGICAL { OFF, ON } LOGICAL;

Main globals

hwo             = handle for the sound board

whdr            = header for a signal

dwVol          = initial board volume

runflag         = flag up is a signal is currently running

openflag       = flag up is a board is currently open

N                 = number of values constituting the signal sampling

mySignal      = signal sampling array

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Contributors