PCGU1000 - Pulse burst generator

Hi,

I need generating N pulse bursts at a given rate (independant of the pulse frequency).

  1. One solution is to build the complete waveform, inside the 8192 points limit, then run PCGU1000 at the desired repetition rate. Optimising the waveform for the best pulse frequency resolution involves some simple calculations, which can be added to the software that controls the generator via the dll. Accuracy is not bad, but the method is somewhat cumbersome!

  2. A much simpler method would be toggling RunGen/StopGen at the required rate, which is easy and accurate with Windows QueryPerformance functions. Indeed, I added this to the VB6 demo without any functional problem, it works at very low repetition rates, but, since the PCGU1000 reacts after ~0.5 s delay, it is practically unusable.

  3. Using Wave Sequence shows the same problem: reprogramming the generator takes about 0.5 s too :frowning:

Any idea other than solution 1?

Regards,
Alain

You don’t have to define all 8192 points, in fact the 9 line “.lib” file shown below defines a waveform with two positive going pulses of 1/f * 0.020 width (of Vout amplitude), separated by 1/f * 0.050 (at 0.0V), with the remaining portion of the cycle (1/f * 0.91) being also at 0.0V.

If f = 1000 Hz then the pulses will be 1/1000 * 0.020 = 20 us, the space betwen pulses will be 1/1000 * 0.050 = 50 us, and the remainder of the wavform 1/1000 * 0.91 = 910 us. 20 us * 2 + 50 us + 910 us = 1.0 ms

I have commented the first listing, cut and paste the second into an editor and save it as 20usPulse.lib or whatever strikes your fancy. Note that to make the math easier I have only defined 8000 points, the PCGU1000 driver will expand this to a 8192 point lookup table.

0.0           ;start at Vout * 0 = 0.0V
(0)           ;(0) = do not ramp to next value
1.0 (160)     ;go to Vout * 1.0 for 160 points (8000 * 0.20)
(0)           ;do not ramp to next value
0.0 (400)     ;Vout * 0.0 for 400 points (8000 * 0.50)
(0)           ;do not ramp to next value
1.0 (160)     ;vout * 1.0 for 160 points (8000 * 0.020
(0)           ;do not ramp to next value
0.0 (7280)    ;Vout * 0.0 for 7280 points (8000 - 160 - 400 - 160, I.e. the remaining points)

You could use the full 8192 points, however there is no need as is does not improve the accuracy of the waveform to any observaable or measurable degree.

So basically, with 8000 points/cycle, just calculate the width of your pulses, and the time between pulses, as fractions of the whole, as described above; then stack up the pulses and “separations/divisions”, add up the number of points for the pulses and divisions and subtract the sum of same from 8000. The difference is the number of points in the remainder of the wave cycle.

I hope I have explained this well enough, if not let me know. It would be fairly easy to write a routine to do create these waveform descriptors, fed with the frequency or period of the wave, and the relative starting point, pulse width, interpulse width, and number of pulses.

'cut and paste listing–do not include the rows of dashes…

0.0
(0)
1.0 (160)
(0)
0.0 (400)
(0)
1.0 (160)
(0)
0.0 (7280)

Here’s the resulting wave as displayed om my WaveJet 322, the bottom widow is zoomed in on the pulses…

Here’s a VB6 function that will build the waveform library for a defined pulse waveform:

[code]'Function MakePulseLib() As String

’ created: 01/01/2009
’ by: Cliff Knight (freeware, honorary mention would by nice)

’ inputs:
’ pWidth - the desired pulse width as a decimal fraction of 1 cycle’s period
’ pDelay - the delay between pulses as a decimal fraction of 1 cycle’s period
’ pNumber - the desired number of pulses
’ pAmplMax - the desired maximum pulse amplitude multiplier (-1.0 to 1.0), defaults to 1.0
’ pAmplMin - the desired minimum pulse amplitude multiplier (-1.0 to 1.0), defaults to 0.0
’ sLength - the desired sample length, defaults to 8192

’ outputs:
’ function returns a text string containing the waveform library code

’ notes:
’ For flexibility the amplitude multipliers are not validated or qualified in any way other
’ than to assure thay are >= -1.0 and <= 1.0.

’ example:
’ sLib = MakePulseLib(0.02, 0.05, 2, 1.0, 0.0, 8000)

’ would create a waveform with 2 pulse of 0.020 of the cycle width;
’ with a 0.050 cycle width delay between them;
’ maximum amplitude will be the FG’s Vout * 1.0;
’ maximum amplitude will be the FG’s Vout * 0.0;
’ an 8000 point sample length will be used

’ At 1kHz this would be two 20 us pulse, separated by a 50 us delay
’ At 5kHz this would be two 4 us pulse, separated by a 10 us delay

Public Function MakePulseLib(ByVal pWidth As Double, _
ByVal pDelay As Double, _
ByVal pNumber As Long, _
Optional ByVal pAmplMax As Double = 1#, _
Optional ByVal pAmplMin As Double = -1#, _
Optional ByVal sLength As Long = 8192) As String

Dim ctr0 As Long

Dim lPulse As Long
Dim lDelay As Long

Dim sAmplMax As String
Dim sAmplMin As String

Dim ts As String
Dim tl As Long

On Error GoTo MakePulseLib_Err

'verify max and min amplitude values, Abs() cannot be greater than 1.0
If Abs(pAmplMax) > 1# Then _
    pAmplMax = 1#

If Abs(pAmplMin) > 1# Then _
    pAmplMin = 1#

'verify sample length, canmnot be > 8192
If sLength > 8192 Then _
    sLength = 8192

'get the # of sample points for the pulse and delay
lPulse = Round(sLength * pWidth, 0)
lDelay = Round(sLength * pDelay, 0)

'format the amplitudes as decimal
sAmplMax = Format(pAmplMax, "0.00000")
sAmplMin = Format(pAmplMin, "0.00000")

'init the output waveform as the minimum amplitude
ts = sAmplMin & vbCrLf & "(0)" & vbCrLf

'for each pulse
For ctr0 = 1 To pNumber
    
    'add it to the waveform as "n.nnnnn (points)" + CrLf + "(0)" to block ramping
    ts = ts & sAmplMax & " (" & lPulse & ")" & vbCrLf & "(0)" & vbCrLf
    
    'subtract # of points from sample length
    sLength = sLength - lPulse
    
    'if there's another pulse add the delay
    If ctr0 < pNumber Then
        'same as pulse above, but for delay
        ts = ts & sAmplMin & " (" & lDelay & ")" & vbCrLf & "(0)" & vbCrLf
        sLength = sLength - lDelay
    End If
    
Next

'remaining sample points must be >= 0
If sLength >= 0 Then
    'if > 0 then add the command
    If sLength > 0 Then _
        ts = ts & sAmplMin & " (" & sLength & ")" & vbCrLf
  Else
    'whoops, used up the sample buffer
    ts = "error -99; waveform definition error--likely too many pulses"
End If

MakePulseLib_Exit:

'set return value
MakePulseLib = ts

Exit Function

MakePulseLib_Err:
'set error as return value
ts = "error " & Err.Number & "; " & Err.Description
Err.Clear

Resume MakePulseLib_Exit

End Function
[/code]

I played with this a bit this morning and found that specifying the pulse width and delay as fractions of a single cycle awkward (at best) from an engineering standpoint. So, I changed things around to accept input parameters of the desired waveform period, pulse wdith, and pulse delay–specified in seconds. This removes the engineer from having to calculate the pulse width and delay ratios (typically specified in seconds) from the waveform’s period.

I think I will incorporate a pulse generator function into my PCGU1000Ctl application. The user would specify pulse width, delay, and number of pulses. Then, if in pulse mode, on each frequency change the app will create a temporary library file that maintains the specified width and delay.

[code]'Function MakePulseLib() As String

’ created: 01/17/2009
’ by: Cliff Knight (freeware, honorary mention would by nice)

’ modifed: 01/18/2009 by CIK to delete fractional specification of pulse width and delay

’ inputs:
’ periodWave - the desired waveform period in seconds, Ex 1kHz = 0.001, defaults to 0.001
’ note: may be passed as 1/f, Ex. 1kHz = 1/1000
’ widthPulse - the desired pulse width in seconds, Ex. 20us = 0.00002, defaults to 0.00002
’ delayPulse - the delay between pulses in seconds, defaults to 0.00005
’ mumPulses - the desired number of pulses, defaults to 1
’ amplitudeMax - the desired maximum pulse amplitude multiplier (-1.0 to 1.0), defaults to 1.0
’ amplitudeMin - the desired minimum pulse amplitude multiplier (-1.0 to 1.0), defaults to 0.0
’ sampleLength - the desired sample length, defaults to 8192

’ outputs:
’ function returns a text string containing the waveform library code

’ notes:
’ For flexibility the amplitude multipliers are not validated or qualified in any way other
’ than to assure thay are >= -1.0 and <= 1.0.

’ example:
’ sLib = MakePulseLib(0.001, 0.00002, 0.00005, 2, 1.0, 0.0, 8000)

’ would create a waveform that when reproduced at 1kHz (0.001s period) would have
’ 2 pulses of 20us width, with a 50us delay between them;
’ maximum amplitude will be the FG’s Vout * 1.0;
’ maximum amplitude will be the FG’s Vout * 0.0;
’ an 8000 point sample length will be used

’ Note that at other frequencies the pulse widths will be altered proportionaly
’ At 5kHz this would be two 4us pulses, separated by a 10us delay

’ The waveform period may be passed as the reciprocal of the frequency,

’ sLib = MakePulseLib(1/13587, 0.000002, 0.000005, 2, 1.0, 0.0, 8000)

’ would create a waveform that when reproduced at 13.587kHz (0.00007359s period) would have
’ 2 pulses of 2us width, with a 5us delay between them;
’ maximum amplitude will be the FG’s Vout * 1.0;
’ maximum amplitude will be the FG’s Vout * 0.0;
’ an 8000 point sample length will be used

Public Function MakePulseLib(Optional ByVal periodWave As Double = 0.001, _
Optional ByVal widthPulse As Double = 0.00002, _
Optional ByVal delayPulse As Double = 0.00005, _
Optional ByVal numPulses As Long = 1, _
Optional ByVal amplitudeMax As Double = 1#, _
Optional ByVal amplitudeMin As Double = -1#, _
Optional ByVal sampleLength As Long = 8192 _
) As String

Dim ctr0 As Long

Dim lPulse As Long
Dim lDelay As Long

Dim sAmplMax As String
Dim sAmplMin As String

Dim ts As String
Dim tl As Long
Dim td As Double

On Error GoTo MakePulseLib_Err

'verify max and min amplitude values, Abs() cannot be greater than 1.0
If Abs(amplitudeMax) > 1# Then _
    amplitudeMax = 1#

If Abs(amplitudeMin) > 1# Then _
    amplitudeMin = 1#

'verify sample length, canmnot be > 8192
If sampleLength > 8192 Then _
    sampleLength = 8192
    
'get the # of sample points for the pulse and delay
'calculate width ratio
td = widthPulse / periodWave

'calculate # of points
lPulse = Round(sampleLength * td, 0)

'same for delay
td = delayPulse / periodWave
lDelay = Round(sampleLength * td, 0)

'format the amplitudes as decimal
sAmplMax = Format(amplitudeMax, "0.00000")
sAmplMin = Format(amplitudeMin, "0.00000")

'init the output waveform as the minimum amplitude
ts = sAmplMin & vbCrLf & "(0)" & vbCrLf

'for each pulse
For ctr0 = 1 To numPulses
    
    'add it to the waveform as "n.nnnnn (points)" + CrLf + "(0)" to block ramping
    ts = ts & sAmplMax & " (" & lPulse & ")" & vbCrLf & "(0)" & vbCrLf
    
    'subtract # of points from sample length
    sampleLength = sampleLength - lPulse
    
    'if there's another pulse add the delay
    If ctr0 < numPulses Then
        'same as pulse above, but for delay
        ts = ts & sAmplMin & " (" & lDelay & ")" & vbCrLf & "(0)" & vbCrLf
        sampleLength = sampleLength - lDelay
    End If
    
Next

'remaining sample points must be >= 0
If sampleLength >= 0 Then
    'if > 0 then add the command
    If sampleLength > 0 Then _
        ts = ts & sAmplMin & " (" & sampleLength & ")" & vbCrLf
  Else
    'whoops, used up the sample buffer
    ts = "error -99; waveform definition error--likely too many pulses"
End If

MakePulseLib_Exit:

'set return value
MakePulseLib = ts

Exit Function

MakePulseLib_Err:
'set error as return value
ts = "error " & Err.Number & "; " & Err.Description
Err.Clear

Resume MakePulseLib_Exit

End Function
[/code]

Hi Cliff,

Thank you for your quick response… but I had programmed my own solution already! No wonder, it is exactly the same as yours, as far as the “algorithm” is concerned :laughing: :laughing: :laughing:

Seriously: when the waveform is defined with N points (N < 8192), is time scaling (stretching) made by the dll or PCGU1000? With what kind of resampling?

NB: I have not played with DDS for 30 years (in the late 70’s, I designed one of the very first digital music synthesizers :unamused: )

Best regards,
Alain

The resampling is made in the generator software (exe).
Linear interpolation is used.
For example the following simple file generates a waveform starting from minimum (00) - going to maximum (ff) and going back to minimum (00).

-1.0
1.0
-1.0

[quote=“iaorana”]Hi Cliff,

Thank you for your quick response… but I had programmed my own solution already! No wonder, it is exactly the same as yours, as far as the “algorithm” is concerned :laughing: :laughing: :laughing:

Seriously: when the waveform is defined with N points (N < 8192), is time scaling (stretching) made by the dll or PCGU1000? With what kind of resampling?

NB: I have not played with DDS for 30 years (in the late 70’s, I designed one of the very first digital music synthesizers :unamused: )

Best regards,
Alain[/quote]

The wavetable has to be 2^13 points or the phase accumulator would run out of lookup data at some point (you could limit the size of the phase accumulator to fit the wavetable size I suppose, but this would seriously degrade performance).

It would appear from what was said above that the PCGU100 uses linear interpolation, meaning that for all but rectangular waveforms the more defined points the better. However when describing rectangular waves linear interpolation is fine…

NB: I am a ME (MIT '71), always interested in electronics–when I was 10 I wanted an oscilloscope for Christmas–my uncle had received the Bell & Howell TV technician course under the GI bill and never completed it–I still have that old thing. In the early-70s, when I heard I could have my own computer, I went nuts and built every project and kit that came along, it’s been chaos ever since…

It’s nice to “talk” to someone of similar age and somewhat similar background!

Hi Cliff,

The above method is only valid if the pulse frequency inside the burst does not need to be “very” accurate. Actually, the rounding error when pre-computing fixed values for lPulse and LDelay accumulates into the whole waveform!

Since my specific application is concerned with accuracy, I eventually programmed another algorithm that resamples each pulse edge to the 8192 grid, so that the mean frequency along the recurrence is accurate to less than 6e-5.

On the other hand, of course, pulse edges are affected by a deterministic jitter (< 1 point), which can be annoying in other applications.

Alain

Hello,

I am looking for PC generator capable to generate tone burs signals. The content of the signal is: five periods of frequency from 1Khz-500Khz /adjustable/ with constant repetition period of 50ms. Currently I am using PCG10/8016 but there is no option for pause between the signals. I tryed to create a waveform library file by using all 32000 pionts to generate 50ms pause, but at this repetition rate I had between one or two points for period, if i wanted to generate five periods of 500Khz. I would like to know, is there a posibility to generate a pause / 20ms-100ms/ between the signals by using Velleman 2MHz USB PC Function Generator, PCGU1000.

[quote]I would like to know, is there a posibility to generate a pause / 20ms-100ms/ between the signals by using Velleman 2MHz USB PC Function Generator, PCGU1000.[/quote]Sorry, but this is not possible with the current version of the generator software.
Anyhow - this feature looks interesting. This can be added to next release of the software. - If you like, you can get the first version of the modified software for testing.

Hello,

I would be interested in that as well.

-cliff-

OK cliffyk. I’ll keep you informed how this “project” is advancing.

After a minor modification to the program code and to the .bit file I got the generator to output a single period of signal wave. This may be especially nice feature for the library waveforms.
At the moment the generator is not repeating the sequence - yet.
When ready, you may download it for testing purposes.

[quote=“VEL255”]OK cliffyk. I’ll keep you informed how this “project” is advancing.

After a minor modification to the program code and to the .bit file I got the generator to output a single period of signal wave. This may be especially nice feature for the library waveforms.
At the moment the generator is not repeating the sequence - yet.
When ready, you may download it for testing purposes.[/quote]

This is a nice addition in and of itself, this instrument and your support are of tremendous value!

-cliff-

Thank you for your replay VEL255. As I understand you are working on new software for PCGU1000 which will be capable to generate a pause between the pulses. This new feature of the software will it be applicapable for the older model PCG10. However, I`ll look for information about your progress.

Thanks

30f400

Sorry, this feature is not possible to add to the PCG10.
The PCGU1000 is very flexible due to the FPGA “core” with firmware upload at startup.

Now you can download the very draft software for the PCGU1000 from:
vel255.diinoweb.com/files/PCSU1000GU_repetive.zip
(Please copy and paste this link to download the files.)

This generator outputs now only repetitive signal (burst).
You may anyhow use it to test this new feature.
(It may be good idea to copy the files from the original PcLab2000SE folder to other folder before replacing the .exe and .bit files with these new ones.)

You can type the repetition interval in milliseconds and press enter.

Way cool!

-cliff-

[quote=“cliffyk”]Way cool![/quote]+1 :smiley:
Alain

Way, great results. :smiley:

Zak

VEL255, this new feature that generates pauses between the signals, does it applicapable
with more funct./.lib files.For example, if I create my on signal as a .lib file, will it be a repetition interval between the signals.

Zak

  1. Did anybody measure the repetition period stability?

  2. In a more developed version, would it be possible to improve the rep period resolution (i.e. better than 1 ms)?