Jump to content
  • 0

Fastest Acquisition Mode of the AD2 Logic Analyzer


Lesiastas

Question

Greetings!

I'm working on a project involving the use of the AD2's Logic Analyzer Function. I need to receive 510 bytes of data in the shortest time possible. 

My questions are:

1). Can the Single/Repeated Acquisition Mode of the Logic Analyzer handle 510 bytes of data?
- I observed that it can only handle up to 4096 samples and 1 byte of the data I'm handling is 10 bits (1 start bit, 8 data bits, 1 stop bit).
So all in all, the Single/Repeated Acquisition Mode can only handle 409 bytes of data.
Is there a way to make it capable of handling 510 bytes of data?

2). What is the fastest acquisition mode of the Logic Analyzer Function?
- I observed that the Record Mode can handle thousands of data. The downside is it takes a very long time to receive data.
Whenever I use the Record Mode, I receive all of the 510 bytes of data. The problem is I end up with 20.5 seconds before the results are displayed and that is too long.

3). What is the best acquisition mode if I want to receive 510 bytes of data as fast as possible?
 

Any advice would really help.

Best regards,
Lesiastas
 

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

Hi @Lesiastas

The simple captures can be performed in a few millisecond.

With the default device configuration of Analog Discovery you have 4096 samples / digital channel. 
With the 4th configuration you have 16384 sample / channel.

See the examples in the WF SDK, like DigitalIn_Spi_Spy.py:

#dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
#  device configuration of index 3 (4th) for Analog Discovery has 16kS digital-in buffer
dwf.FDwfDeviceConfigOpen(c_int(-1), c_int(3), byref(hdwf)) 

 

For repeated captures you don't have to rearm the instrument. The new capture is automatically started after the data is fetched from the device. This, to improve the capture rate.

dwf.FDwfDigitalInConfigure(hdwf, c_bool(False), c_bool(True))
for iTrigger in range(100):
    # new acquisition is started automatically after done state 
    while True:
        dwf.FDwfDigitalInStatus(hdwf, c_int(1), byref(sts))
        if sts.value == DwfStateDone.value :
            break
     dwf.FDwfDigitalInStatusData(hdwf, rgwSamples, 2*cSamples)

 

Link to comment
Share on other sites

Hi @attila

Thanks for the advice regarding the ConfigOpen. The buffer size of the Logic Analyzer can now handle up to 16384 samples.This is the setup that I'm working on. Please see the following code:
- Selects the 4th configuration of AD2 which allocates 16k+ digital buffer
- Uses the Pattern Generator to transmit the processed string data.
- Uses the Logic Analyzer to receive and decode the transmitted data from the Pattern Generator.

Spoiler



Module Module1
    Function AD2_UARTCommRead(ByVal hdwf As Integer, ByRef rgData() As Byte, ByVal countOfDataBytes As Integer, ByVal hzRate As Integer, ByVal hzUart As Integer, ByVal pin As Integer, ByRef rgParsed As String, ByRef rgLength As Integer) As Integer

        'Customized Uart Decoder
        Dim pData As Boolean
        Dim fData As Boolean : fData = True
        Dim cSamples As Integer : cSamples = rgData.Length
        Dim rgHex(cSamples) As Byte
        Dim cSamplePerBit As Integer : cSamplePerBit = hzRate / hzUart
        'Decoding Raw Samples into Decimal
        For i = 0 To cSamples - 1
            Dim s As Byte : s = rgData(i)
            pData = fData
            fData = 1 And (s >> pin)
            If pData <> 0 And fData = 0 Then
                Dim bValue As Integer : bValue = 0
                For b = 0 To 7
                    Dim ii As Double : ii = Math.Round(i + (1.499 + b) * cSamplePerBit)   '''''
                    If ii >= cSamples Then
                        Exit For
                    End If
                    s = rgData(ii)
                    fData = 1 And (s >> pin)
                    If fData Then
                        bValue = bValue + (1 << b)
                    End If
                Next
                rgHex(i) = bValue
                i = i + cSamplePerBit * 9.499 - 1 '1 start + 8 bits + 0.5 stop  -1 because For will increment
            End If
        Next

        'Converting Decimal to ASCII
        Dim rgString As String
        For e = 0 To cSamples - 1
            If rgHex(e) = 0 Then
                rgString = rgString
            Else
                rgString = rgString + Chr(rgHex(e))
            End If
        Next e
        rgParsed = rgString
        rgLength = Len(rgParsed)

    End Function

    Function AD2_FDwfDigitalOutDataLong(ByVal Hdwf As Integer, ByVal IdxChannel As Integer,
                                                     ByRef RgLong As String, ByVal LongBits As Integer) As Integer
        'Post Processing Method
        'Conversion of ASCII String to Binary
        Dim Text As String : Text = RgLong
        Dim n As Integer : n = Len(Text)
        Dim oReturn As New StringBuilder
        Dim StartBit As String : StartBit = "0"
        Dim StopBit As String : StopBit = "1"
        For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(Text)
            oReturn.Append(StartBit)
            oReturn.Append(StrReverse(Convert.ToString(Character, 2).PadLeft(8, "0")))
            oReturn.Append(StopBit)
        Next
        Dim Text2 As String : Text2 = (oReturn.ToString)

        'Padding of Additional 1s
        Dim Counter As Integer : Counter = Len(Text2)
        Dim PadMod As Integer : PadMod = (Counter + (Counter + (Counter Mod 8))) Mod 8
        Dim PadBin As String : PadBin = New String("1", PadMod)
        Text2 = Text2 + PadBin
        Dim PadResult As Integer : PadResult = Counter + PadMod

        'Chunking of Bits into 8
        Dim RevBytes(PadResult) As String
        For e As Integer = 0 To RevBytes.Length - 8 Step 8
            RevBytes(e) = Text2.Substring(e, 8)
        Next e

        Dim backup As String
        Dim Extracted(PadResult) As String
        Dim TxBits(PadResult) As Byte
        Dim f As Integer, x As Integer
        Dim lTemp As Integer : lTemp = 0
        Dim lngValue As Integer

        'Inverting and Conversion of Bits
        For f = 0 To RevBytes.Length
            backup = StrReverse(RevBytes(8 * f))
            If backup = "" Then Extracted(f) = "0"
            Extracted(f) = Extracted(f) & backup

            'Conversion of Binary to Decimal
            lngValue = Convert.ToInt32(Extracted(f), 2)

            TxBits(f) = lngValue
            lngValue = 0
            If TxBits(f) = 0 Then Exit For
        Next f

        Call FDwfDigitalOutDataSet(Hdwf, IdxChannel, TxBits, PadResult)

    End Function

    Sub Main()

        Dim hdwf As Long
        ' 3 = 4th device configuration of AD2 with 16k digital-in/out buffer
        If FDwfDeviceConfigOpen(-1, 3, hdwf) = False Then
            Dim szError As String
            FDwfGetLastErrorMsg(szError)
            System.Console.WriteLine("Device open failed" & vbCrLf & szError, vbExclamation + vbOKOnly)
            End
        End If

        ' UART channels: DIO-0 and DIO-1, h3 = (1 << 0)|(1 << 1)
        Const fsDio = &HFFFF
        Const hzUart = 230400
        Const hzRate = hzUart * 1 '''''
        Const cSamples = 10 * 510 'RgLong is 510 characters
        Dim cBuffer As Integer
        Dim RgLong As String : RgLong = "02FF0FFA001101F600030000000000EC0000000220500219D802010E2222021AFA22222222FF021A26FFFFFFFFFF021B08FFFFFFFFFF021ACFFFFFFFFFFF021B07FFFFFFFFFF021AF9E4F56BF569F56AF56C220220868E838F82EB6005EDF0A3DBFB2275A50002205085A53B75A502128D9A853BA522021B088F608D618A628B63E56345626054121E9E903275EEF0FCA3EFF0FD903275E0FEA3E0FF2404F582E43EF5837403F0EF2406FFE43EFE8F82F583E564F0AA06A9077B01900001E56012056C900002E56112056C900003E5628563F012062F7F07121E5A22000000000000000000000022D310AF01C3C0D0EFF5E9EDF5EDEEF5EAECF5EE74021400"
        Dim secRun As Double : secRun = (Len(RgLong) * 10) * (1 / hzUart)

        Dim phzFreq As Double
        'PatGen Parameters - Initialized One Time
        FDwfDigitalOutInternalClockInfo(hdwf, phzFreq)
        FDwfDigitalOutRepeatSet(hdwf, 1)
        FDwfDigitalOutRunSet(hdwf, secRun)

        'Enabling DIO-0
        FDwfDigitalOutEnableSet(hdwf, 0, 1)
        FDwfDigitalOutTypeSet(hdwf, 0, 1)
        FDwfDigitalOutIdleSet(hdwf, 0, 2)
        FDwfDigitalOutDividerSet(hdwf, 0, (phzFreq / hzUart))

        Dim hzDI As Double
        FDwfDigitalInInternalClockInfo(hdwf, hzDI)
        FDwfDigitalInTriggerSourceSet(hdwf, trigsrcDetectorDigitalIn)
        'Falling Edge of any specified channel
        FDwfDigitalInTriggerSet(hdwf, 0, 0, 0, fsDio)
        FDwfDigitalInDividerSet(hdwf, hzDI / hzRate)
        FDwfDigitalInSampleFormatSet(hdwf, 8)
        FDwfDigitalInBufferSizeInfo(hdwf, cBuffer)

        If cSamples > cBuffer Then '
            FDwfDigitalInAcquisitionModeSet(hdwf, acqmodeRecord)
            FDwfDigitalInTriggerPrefillSet(hdwf, 0)
            'Number of samples after trigger
            FDwfDigitalInTriggerPositionSet(hdwf, cSamples)
            'We are interested only on toggles of the specified channels
            FDwfDigitalInSampleSensibleSet(hdwf, fsDio)
        Else
            FDwfDigitalInBufferSizeSet(hdwf, cSamples)
            FDwfDigitalInTriggerPositionSet(hdwf, cSamples - 10)
        End If

        'Data needs to be tested for 744 times
        Dim StartTime As Double
        Dim SecondsElapsed As Double
        'Measuring Test Time
        StartTime = Timer
        '*****************************
        For i = 0 To 743
            'Processing Data for Transmission
            AD2_FDwfDigitalOutDataLong(hdwf, 0, RgLong, 510)

            'Triggering the Logic Analyzer first before transmitting data
            FDwfDigitalInConfigure(hdwf, 1, 1)
            FDwfDigitalOutConfigure(hdwf, 1)

            Dim rgData(cSamples) As Byte
            Dim sts As Byte
            Dim fOverflow As Boolean = False
            Dim iSample As Integer = 0

            If cSamples > cBuffer Then ' record
                Dim cAvailable As Integer
                Dim cLost As Integer
                Dim cCorrupted As Integer
                While iSample < cSamples
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Or sts = DwfStateTriggered Then
                        FDwfDigitalInStatusRecord(hdwf, cAvailable, cLost, cCorrupted)
                        If cLost <> 0 Or cCorrupted <> 0 Then
                            fOverflow = True
                        End If
                        cAvailable = Math.Min(cAvailable, cSamples - iSample)
                        Dim rgTemp(cAvailable) As Byte
                        ' in other programming languages use pass pointer to rgData[iSample]
                        FDwfDigitalInStatusData(hdwf, rgTemp, 1 * cAvailable)
                        For l = 0 To cAvailable - 1
                            rgData(iSample) = rgTemp(i)
                            iSample += 1
                        Next
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
            Else
                While True
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
                iSample = rgData.Length
                FDwfDigitalInStatusData(hdwf, rgData, 1 * rgData.Length)
            End If

            Dim DIO0Used As Long : DIO0Used = 2 'DIO #2
            Dim DIO0Mesg As String : DIO0Mesg = ""
            Dim DIO0Length As Long
            AD2_UARTCommRead(hdwf, rgData, (1 * cSamples), hzRate, hzUart, DIO0Used, DIO0Mesg, DIO0Length)

        Next i
        '*****************************
        'Determine how many seconds code took to run
        'Notify user in seconds
        SecondsElapsed = Math.Round(Timer - StartTime, 6)
        MsgBox("This code ran successfully in " & SecondsElapsed & " seconds", vbInformation)

        FDwfDeviceCloseAll()

    End Sub

End Module


 

The data to be transmitted is RgLong which contains 510 characters. Each character is 10 bits long (1 start bit, 8 data bits, 1 stop bit). 
The contents of RgLong has 744 lines which will vary for each iteration of the For Loop but I decided to use just one line for this example.
I used the AD2 Pattern Generator as the Transmitter and the AD2 Logic Analyzer as the Receiver to do a Loopback test using RgLong.

Doing this test takes about 20.5 seconds which is too long. Is there a way to minimize the test time?
Can you please check if the codes can be optimized? 

Best regards,
Lesiastas

Link to comment
Share on other sites

Hi @LesiastasHere you have ~19.2 sec run time.
You have 744 iterations of 25.8ms. The capture is 22.135sec, 5100 samples at 230.4kHz.
So the latency of each iteration is about 3-4ms. This to configure the digital-out and fetch the data from digital-in.

Spoiler



Imports System.Text

Module Module1
    Function AD2_UARTCommRead(ByVal hdwf As Integer, ByRef rgData() As Byte, ByVal countOfDataBytes As Integer, ByVal hzRate As Integer, ByVal hzUart As Integer, ByVal pin As Integer, ByRef rgParsed As String, ByRef rgLength As Integer) As Integer

        'Customized Uart Decoder
        Dim pData As Boolean
        Dim fData As Boolean : fData = True
        Dim cSamples As Integer : cSamples = rgData.Length
        Dim rgHex(cSamples) As Byte
        Dim cSamplePerBit As Integer : cSamplePerBit = hzRate / hzUart
        'Decoding Raw Samples into Decimal
        For i = 0 To cSamples - 1
            Dim s As Byte : s = rgData(i)
            pData = fData
            fData = 1 And (s >> pin)
            If pData <> 0 And fData = 0 Then
                Dim bValue As Integer : bValue = 0
                For b = 0 To 7
                    Dim ii As Double : ii = Math.Round(i + (1.499 + b) * cSamplePerBit)   '''''
                    If ii >= cSamples Then
                        Exit For
                    End If
                    s = rgData(ii)
                    fData = 1 And (s >> pin)
                    If fData Then
                        bValue = bValue + (1 << b)
                    End If
                Next
                rgHex(i) = bValue
                i = i + cSamplePerBit * 9.499 - 1 '1 start + 8 bits + 0.5 stop  -1 because For will increment
            End If
        Next

        'Converting Decimal to ASCII
        Dim rgString As String
        For e = 0 To cSamples - 1
            If rgHex(e) = 0 Then
                rgString = rgString
            Else
                rgString = rgString + Chr(rgHex(e))
            End If
        Next e
        rgParsed = rgString
        rgLength = Len(rgParsed)

    End Function

    Function AD2_FDwfDigitalOutDataLong(ByVal Hdwf As Integer, ByVal IdxChannel As Integer,
                                                     ByRef RgLong As String, ByVal LongBits As Integer) As Integer
        'Post Processing Method
        'Conversion of ASCII String to Binary
        Dim Text As String : Text = RgLong
        Dim n As Integer : n = Len(Text)
        Dim oReturn As New StringBuilder
        Dim StartBit As String : StartBit = "0"
        Dim StopBit As String : StopBit = "1"
        For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(Text)
            oReturn.Append(StartBit)
            oReturn.Append(StrReverse(Convert.ToString(Character, 2).PadLeft(8, "0")))
            oReturn.Append(StopBit)
        Next
        Dim Text2 As String : Text2 = (oReturn.ToString)

        'Padding of Additional 1s
        Dim Counter As Integer : Counter = Len(Text2)
        Dim PadMod As Integer : PadMod = (Counter + (Counter + (Counter Mod 8))) Mod 8
        Dim PadBin As String : PadBin = New String("1", PadMod)
        Text2 = Text2 + PadBin
        Dim PadResult As Integer : PadResult = Counter + PadMod

        'Chunking of Bits into 8
        Dim RevBytes(PadResult) As String
        For e As Integer = 0 To RevBytes.Length - 8 Step 8
            RevBytes(e) = Text2.Substring(e, 8)
        Next e

        Dim backup As String
        Dim Extracted(PadResult) As String
        Dim TxBits(PadResult) As Byte
        Dim f As Integer, x As Integer
        Dim lTemp As Integer : lTemp = 0
        Dim lngValue As Integer

        'Inverting and Conversion of Bits
        For f = 0 To RevBytes.Length
            backup = StrReverse(RevBytes(8 * f))
            If backup = "" Then Extracted(f) = "0"
            Extracted(f) = Extracted(f) & backup

            'Conversion of Binary to Decimal
            lngValue = Convert.ToInt32(Extracted(f), 2)

            TxBits(f) = lngValue
            lngValue = 0
            If TxBits(f) = 0 Then Exit For
        Next f

        Call FDwfDigitalOutDataSet(Hdwf, IdxChannel, TxBits, PadResult)

    End Function

    Sub Main()

        Dim hdwf As Long
        ' 3 = 4th device configuration of AD2 with 16k digital-in/out buffer
        If FDwfDeviceConfigOpen(-1, 3, hdwf) = False Then
            Dim szError As String
            FDwfGetLastErrorMsg(szError)
            System.Console.WriteLine("Device open failed" & vbCrLf & szError, vbExclamation + vbOKOnly)
            End
        End If
        FDwfDeviceAutoConfigureSet(hdwf, 0) ' only the #Configure functions will apply settings

        ' UART channels: DIO-0 and DIO-1, h3 = (1 << 0)|(1 << 1)
        Const nLoop = 744
        Const fsDio = &HFFFF
        Const hzUart = 230400
        Const hzRate = hzUart * 1 '''''
        Const cSamples = 10 * 510 'RgLong is 510 characters
        Dim cBuffer As Integer
        Dim RgLong As String : RgLong = "02FF0FFA001101F600030000000000EC0000000220500219D802010E2222021AFA22222222FF021A26FFFFFFFFFF021B08FFFFFFFFFF021ACFFFFFFFFFFF021B07FFFFFFFFFF021AF9E4F56BF569F56AF56C220220868E838F82EB6005EDF0A3DBFB2275A50002205085A53B75A502128D9A853BA522021B088F608D618A628B63E56345626054121E9E903275EEF0FCA3EFF0FD903275E0FEA3E0FF2404F582E43EF5837403F0EF2406FFE43EFE8F82F583E564F0AA06A9077B01900001E56012056C900002E56112056C900003E5628563F012062F7F07121E5A22000000000000000000000022D310AF01C3C0D0EFF5E9EDF5EDEEF5EAECF5EE74021400"
        Dim secRun As Double : secRun = (Len(RgLong) * 10) * (1 / hzUart)

        Dim phzFreq As Double
        'PatGen Parameters - Initialized One Time
        FDwfDigitalOutInternalClockInfo(hdwf, phzFreq)
        FDwfDigitalOutRepeatSet(hdwf, 1)
        FDwfDigitalOutRunSet(hdwf, secRun)

        'Enabling DIO-0
        FDwfDigitalOutEnableSet(hdwf, 0, 1)
        FDwfDigitalOutTypeSet(hdwf, 0, 1)
        FDwfDigitalOutIdleSet(hdwf, 0, 2)
        FDwfDigitalOutDividerSet(hdwf, 0, (phzFreq / hzUart))

        Dim hzDI As Double
        FDwfDigitalInInternalClockInfo(hdwf, hzDI)
        FDwfDigitalInTriggerSourceSet(hdwf, trigsrcDetectorDigitalIn) '
        'Falling Edge of any specified channel
        FDwfDigitalInTriggerSet(hdwf, 0, 0, 0, fsDio)
        FDwfDigitalInDividerSet(hdwf, hzDI / hzRate)
        FDwfDigitalInSampleFormatSet(hdwf, 8)
        FDwfDigitalInBufferSizeInfo(hdwf, cBuffer)

        If cSamples > cBuffer Then '
            FDwfDigitalInAcquisitionModeSet(hdwf, acqmodeRecord)
            FDwfDigitalInTriggerPrefillSet(hdwf, 0)
            'Number of samples after trigger
            FDwfDigitalInTriggerPositionSet(hdwf, cSamples)
            'We are interested only on toggles of the specified channels
            FDwfDigitalInSampleSensibleSet(hdwf, fsDio)
        Else
            FDwfDigitalInBufferSizeSet(hdwf, cSamples)
            FDwfDigitalInTriggerPositionSet(hdwf, cSamples - 10)
        End If

        'Processing Data for Transmission
        AD2_FDwfDigitalOutDataLong(hdwf, 0, RgLong, 510)

        'Data needs to be tested for 744 times
        Dim StartTime As Double
        Dim SecondsElapsed As Double

        'Measuring Test Time
        StartTime = Timer
        If cSamples <= cBuffer Then ' prime for repeated captures
            FDwfDigitalInConfigure(hdwf, 1, 1) ' it will rearm for consecutive iterations
            FDwfDigitalOutConfigure(hdwf, 1)
        End If

        For i = 0 To nLoop - 1

            Dim rgData(cSamples) As Byte
            Dim sts As Byte
            Dim fOverflow As Boolean = False
            Dim iSample As Integer = 0

            If cSamples > cBuffer Then ' record
                FDwfDigitalInConfigure(hdwf, 1, 1) ' restart is only required for record
                FDwfDigitalOutConfigure(hdwf, 1)

                Dim cAvailable As Integer
                Dim cLost As Integer
                Dim cCorrupted As Integer
                While iSample < cSamples
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Or sts = DwfStateTriggered Then
                        FDwfDigitalInStatusRecord(hdwf, cAvailable, cLost, cCorrupted)
                        If cLost <> 0 Or cCorrupted <> 0 Then
                            fOverflow = True
                        End If
                        cAvailable = Math.Min(cAvailable, cSamples - iSample)
                        Dim rgTemp(cAvailable) As Byte
                        ' in other programming languages use pass pointer to rgData[iSample]
                        FDwfDigitalInStatusData(hdwf, rgTemp, 1 * cAvailable)
                        For l = 0 To cAvailable - 1
                            rgData(iSample) = rgTemp(i)
                            iSample += 1
                        Next
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
            Else
                While True
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
                iSample = rgData.Length
                FDwfDigitalInStatusData(hdwf, rgData, 1 * rgData.Length)
                If i < nLoop - 1 Then
                    FDwfDigitalOutConfigure(hdwf, 1) ' start next while processing data below
                End If
            End If

            Dim DIO0Used As Long : DIO0Used = 2 'DIO #2
            Dim DIO0Mesg As String : DIO0Mesg = ""
            Dim DIO0Length As Long
            AD2_UARTCommRead(hdwf, rgData, (1 * cSamples), hzRate, hzUart, DIO0Used, DIO0Mesg, DIO0Length)

        Next i
        '*****************************
        'Determine how many seconds code took to run
        'Notify user in seconds
        SecondsElapsed = Math.Round(Timer - StartTime, 6)
        Console.WriteLine("This code ran successfully in " & SecondsElapsed & " seconds.\n")
        Console.WriteLine((nLoop) & " x" & (1000 * SecondsElapsed / nLoop) & "ms loop latency:" & (1000 * (SecondsElapsed / nLoop - cSamples / hzRate)) & "ms")

        FDwfDeviceCloseAll()

    End Sub

End Module


 

 

Link to comment
Share on other sites

Hi @attila

Thanks for the tweaks you've made with the code that I sent. I really appreciate it :lol: 
I have a few questions regarding the capabilities of Analog Discovery 2 and its features:

1). Is it possible to achieve a test time of 5 - 10 seconds using the Pattern Generator and Logic Analyzer features of AD2? Can you please explain what needs to be done to achieve this?

2). If not, are there other functions of AD2 that can be used to test RgLong for 744 iterations to achieve a test time of 5 - 10 seconds or is this the limit of Analog Discovery 2?

Best regards,
Lesiastas
 

Link to comment
Share on other sites

Hi @Lesiastas

1. No, unless we invent time machine :)
You are capturing 5100 samples at 230.4kHz which is 22.135ms. With 744 iterations it takes 16.47sec. The whole process can't be less than this.
The data transfer for each capture adds 3-4ms and we end up with ~19sec run time.

2. Instead separate captures you could do continuous capture and data processing.
 

Link to comment
Share on other sites

Hi @attila

Thanks for being straightforward with your answer :)
I have a few questions regarding the capabilities of Analog Discovery 2 and its features:

1). Are there other features of AD2 besides the Pattern Generator and Logic Analyzer that can be used to test RgLong to achieve a faster test time?

2). Just in case this is the limitation of AD2, are there other Digilent products that you would recommend to achieve a test time of 10 seconds or less?

3). Can you please explain what setup I need to use to do continuous capture and data processing for RgLong?

On 12/19/2019 at 5:12 PM, attila said:

2. Instead separate captures you could do continuous capture and data processing

Best regards,
Lesiastas

 

Link to comment
Share on other sites

Hi @attilaI was able to reduce the time it takes for RgLong to be processed by putting the start and stop bit  between the entire data, not between each character. 
I also customized several settings. Here's the latest code that I'm using:

Spoiler



Imports System.Text

Module Module1
    Function AD2_UARTCommRead(ByVal hdwf As Integer, ByRef rgData() As Byte, ByVal cSamples As Integer, ByVal hzRate As Integer, ByVal hzUart As Integer, ByVal DIOUsed As Integer, ByRef RxMesg As String, ByRef MesgLength As Integer) As Integer

        'Customized Uart Decoder
        Dim pData As Boolean
        Dim fData As Boolean : fData = True
        cSamples = rgData.Length
        Dim rgHex(cSamples) As Byte
        Dim s As Byte
        Dim cSamplePerBit As Integer : cSamplePerBit = 1
        'Decoding Raw Samples into Decimal
        For i = 7 To cSamples - 1
            If i < 16 Then
                'Detecting Start Bit
                s = rgData(i)
                pData = fData
                fData = 1 And (s >> DIOUsed)
                If pData <> 0 And fData = 0 Then
                    'Converting Raw Samples into Decimal
                    Dim bValue As Integer : bValue = 0
                    For b = 0 To 7
                        Dim ii As Double : ii = Math.Round(i + (1.499 + b) * cSamplePerBit)   '''''
                        If ii >= cSamples Then
                            Exit For
                        End If
                        s = rgData(ii)
                        fData = 1 And (s >> DIOUsed)
                        If fData Then
                            bValue = bValue + (1 << b)
                        End If
                    Next
                    rgHex(i) = bValue
                    i = i + (cSamplePerBit * 9.499) - 1 '1 start + 8 bits + 0.5 stop  -1 because For will increment
                End If
            Else
                'Detecting Stop Bit
                If i = (cSamples - 1) Then
                Else
                    'Continue converting Raw Samples into Decimal
                    Dim bValue As Integer : bValue = 0
                    For b = 0 To 7
                        Dim ii As Double : ii = Math.Round((i + b))   '''''
                        If ii >= cSamples Then
                            Exit For
                        End If
                        s = rgData(ii)
                        fData = 1 And (s >> DIOUsed)
                        If fData Then
                            bValue = bValue + (1 << b)
                        End If
                    Next
                    rgHex(i) = bValue
                    i = i + (cSamplePerBit * 8) - 1
                End If
            End If
        Next

        'Converting Decimal to ASCII
        Dim rgString As String
        For e = 0 To cSamples - 1
            If rgHex(e) = 0 Then
                rgString = rgString
            Else
                rgString = rgString + Chr(rgHex(e))
            End If
        Next e
        RxMesg = rgString
        MesgLength = Len(RxMesg)

    End Function

    Function AD2_FDwfDigitalOutDataLong(ByVal Hdwf As Integer, ByVal IdxChannel As Integer, ByRef RgLong As String) As Integer

        'Post Processing Method
        'Conversion of ASCII String to Binary
        Dim Text As String : Text = RgLong
        Dim n As Integer : n = Len(Text)
        Dim oReturn As New StringBuilder
        Dim StartBit As String : StartBit = "0"
        Dim StopBit As String : StopBit = "1"
        oReturn.Append(StartBit)
        For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(Text)
            'oReturn.Append(StartBit)
            oReturn.Append(StrReverse(Convert.ToString(Character, 2).PadLeft(8, "0")))
            'oReturn.Append(StopBit)
        Next
        oReturn.Append(StopBit)
        Dim Text2 As String : Text2 = (oReturn.ToString)

        'Padding of Additional 1s
        Dim Counter As Integer : Counter = Len(Text2)
        Dim PadMod As Integer : PadMod = (Counter + (Counter + (Counter Mod 8))) Mod 8
        Dim PadBin As String : PadBin = New String("1", PadMod)
        Text2 = Text2 + PadBin
        Dim PadResult As Integer : PadResult = Counter + PadMod

        'Chunking of Bits into 8
        Dim RevBytes(PadResult) As String
        For e As Integer = 0 To RevBytes.Length - 8 Step 8
            RevBytes(e) = Text2.Substring(e, 8)
        Next e

        Dim backup As String
        Dim Extracted(PadResult) As String
        Dim TxBits(PadResult) As Byte
        Dim f As Integer, x As Integer
        Dim lTemp As Integer : lTemp = 0
        Dim lngValue As Integer

        'Inverting and Conversion of Bits
        For f = 0 To RevBytes.Length
            backup = StrReverse(RevBytes(8 * f))
            If backup = "" Then Extracted(f) = "0"
            Extracted(f) = Extracted(f) & backup

            'Conversion of Binary to Decimal
            lngValue = Convert.ToInt32(Extracted(f), 2)
            TxBits(f) = lngValue
            lngValue = 0
            If TxBits(f) = 0 Then Exit For
        Next f

        Call FDwfDigitalOutDataSet(Hdwf, IdxChannel, TxBits, PadResult)

    End Function

    Sub Main()

        Dim hdwf As Long
        ' 3 = 4th device configuration of AD2 with 16k digital-in/out buffer
        If FDwfDeviceConfigOpen(-1, 3, hdwf) = False Then
            Dim szError As String
            FDwfGetLastErrorMsg(szError)
            System.Console.WriteLine("Device open failed" & vbCrLf & szError, vbExclamation + vbOKOnly)
            End
        End If
        FDwfDeviceAutoConfigureSet(hdwf, 0) ' only the #Configure functions will apply settings

        ' UART channels: DIO-0 and DIO-1, h3 = (1 << 0)|(1 << 1)
        Const nLoop = 734
        Const fsDio = &HFFFF
        Const hzUart = 230400
        Const hzRate = hzUart * 1 '''''
        Const cSamples = (8 * 510) + 8 'RgLong is 510 characters. +8 is for filling extra byte
        Const cSamplesAfterTrigger = 18000
        Dim cBuffer As Integer
        Dim RgLong As String : RgLong = "02FF0FFA001101F600030000000000EC0000000220500219D802010E2222021AFA22222222FF021A26FFFFFFFFFF021B08FFFFFFFFFF021ACFFFFFFFFFFF021B07FFFFFFFFFF021AF9E4F56BF569F56AF56C220220868E838F82EB6005EDF0A3DBFB2275A50002205085A53B75A502128D9A853BA522021B088F608D618A628B63E56345626054121E9E903275EEF0FCA3EFF0FD903275E0FEA3E0FF2404F582E43EF5837403F0EF2406FFE43EFE8F82F583E564F0AA06A9077B01900001E56012056C900002E56112056C900003E5628563F012062F7F07121E5A22000000000000000000000022D310AF01C3C0D0EFF5E9EDF5EDEEF5EAECF5EE74021400"
        Dim secRun As Double : secRun = (cSamples) * (1 / hzUart)

        'PatGen Parameters - Initialized One Time
        FDwfDigitalOutRepeatSet(hdwf, 1)
        FDwfDigitalOutRunSet(hdwf, secRun)

        'Enabling DIO-0
        FDwfDigitalOutEnableSet(hdwf, 0, 1)
        FDwfDigitalOutTypeSet(hdwf, 0, 1)
        FDwfDigitalOutIdleSet(hdwf, 0, 2)
        FDwfDigitalOutDividerSet(hdwf, 0, (100000000.0 / hzUart))

        'Logic Parameters
        FDwfDigitalInTriggerSourceSet(hdwf, trigsrcDetectorDigitalIn) '
        'Falling Edge of any specified channel
        FDwfDigitalInTriggerSet(hdwf, 0, 0, 0, fsDio)
        FDwfDigitalInDividerSet(hdwf, 100000000.0 / hzRate)
        FDwfDigitalInSampleFormatSet(hdwf, 8)
        FDwfDigitalInBufferSizeInfo(hdwf, cBuffer)

        If cSamples > cBuffer Then '
            FDwfDigitalInAcquisitionModeSet(hdwf, acqmodeRecord)
            FDwfDigitalInTriggerPrefillSet(hdwf, 0)
            'Number of samples after trigger
            FDwfDigitalInTriggerPositionSet(hdwf, cSamplesAfterTrigger)
            'We are interested only on toggles of the specified channels
            FDwfDigitalInSampleSensibleSet(hdwf, fsDio)
        Else
            FDwfDigitalInBufferSizeSet(hdwf, cSamples)
            FDwfDigitalInTriggerPositionSet(hdwf, cSamples - 9)
        End If

        'Processing Data for Transmission
        AD2_FDwfDigitalOutDataLong(hdwf, 0, RgLong)

        'Data needs to be tested for 734 times
        Dim StartTime As Double
        Dim SecondsElapsed As Double

        'Measuring Test Time
        StartTime = Timer
        If cSamples <= cBuffer Then ' prime for repeated captures
            FDwfDigitalInConfigure(hdwf, 1, 1) ' it will rearm for consecutive iterations
            FDwfDigitalOutConfigure(hdwf, 1)
        End If

        For i = 0 To nLoop - 1

            Dim rgData(cSamples) As Byte
            Dim sts As Byte
            Dim fOverflow As Boolean = False
            Dim iSample As Integer = 0

            If cSamples > cBuffer Then ' record
                FDwfDigitalInConfigure(hdwf, 1, 1) ' restart is only required for record
                FDwfDigitalOutConfigure(hdwf, 1)

                Dim cAvailable As Integer
                Dim cLost As Integer
                Dim cCorrupted As Integer
                While iSample < cSamples
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Or sts = DwfStateTriggered Then
                        FDwfDigitalInStatusRecord(hdwf, cAvailable, cLost, cCorrupted)
                        If cLost <> 0 Or cCorrupted <> 0 Then
                            fOverflow = True
                        End If
                        cAvailable = Math.Min(cAvailable, cSamples - iSample)
                        Dim rgTemp(cAvailable) As Byte
                        ' in other programming languages use pass pointer to rgData[iSample]
                        FDwfDigitalInStatusData(hdwf, rgTemp, 1 * cAvailable)
                        For l = 0 To cAvailable - 1
                            rgData(iSample) = rgTemp(i)
                            iSample += 1
                        Next
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
            Else
                While True
                    If FDwfDigitalInStatus(hdwf, 1, sts) = 0 Then
                        Return
                    End If
                    If sts = DwfStateDone Then
                        Exit While
                    End If
                End While
                iSample = rgData.Length
                FDwfDigitalInStatusData(hdwf, rgData, 1 * rgData.Length)
                If i < nLoop - 1 Then
                    FDwfDigitalOutConfigure(hdwf, 1) ' start next while processing data below
                End If
            End If

            Dim DIO0Used As Long : DIO0Used = 2 'DIO #2
            Dim DIO0Mesg As String : DIO0Mesg = ""
            Dim DIO0Length As Long
            AD2_UARTCommRead(hdwf, rgData, (1 * cSamples), hzRate, hzUart, DIO0Used, DIO0Mesg, DIO0Length)

        Next i
        '*****************************
        'Determine how many seconds code took to run
        'Notify user in seconds
        SecondsElapsed = Math.Round(Timer - StartTime, 6)
        Console.WriteLine("This code ran successfully in " & SecondsElapsed & " seconds.\n")
        Console.WriteLine((nLoop) & " x" & (1000 * SecondsElapsed / nLoop) & "ms loop latency:" & (1000 * (SecondsElapsed / nLoop - cSamples / hzRate)) & "ms")

        FDwfDeviceCloseAll()

    End Sub

End Module


 

The test time that I've measured so far are:

image.png.4aaf3b42e9712d9d39ac9d39b7b315d0.png

Can you please check if there are possible improvements to the latest code? I'm not confident that it is the best setup to use at the moment.
Thank you for your guidance.

Best regards,
Lesiastas

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...