• 0

Proper Arrangements of Bits for Pattern Generator using Analog Discovery 2


Question

Greetings,

I am working on a project using the Pattern Generator and Logic Analyzer functions of Analog Discovery 2.
I'm trying to figure out the proper arrangements of bits to be assigned to the Pattern Generator so that the Logic Analyzer can receive it in UART format properly.

Let's say I want to transmit the word "UART" using the Pattern Generator. Here's how I'm doing it using the Custom Signal setting in the Pattern Generator:

image.png.96c6d36c177f71bc7cd8fe3e5f774975.pngimage.png.ff49317cef851b56840a200e321afd87.png    image.png.69f1990c2266d249507b183e7b45dd04.pngimage.png.b565098ba5e819f019e35362a080eb61.png

The bits highlighted in green are the start and stop bits while those in yellow are the inverted data bits of the word "UART".
I also adjusted the Run and Repeat time to only transmit it once. (40/9600 = 0.004166666)
image.png.b070d78d919b529a10562af061651b03.png

I transmitted it to the Logic Analyzer and it was able to receive it using the UART setting.

image.png.c44bed10ad767e144c608314ed0489a8.png

The problem that I see with this is if you want to transmit a single character, you'll need 10 bits for it. For big data, it will take too long to be received by the Logic Analyzer.

I was wondering if the Pattern Generator can be set up like this:
1 start bit + (32 Data bits of "UART") + 1 stop bit

This reduces the no. of bits by only using the start and stop bits at the beginning and at the end of the data to be transmitted.
I tried doing this by rearranging the bits, the run time and repeat settings in the Pattern Generator:

image.png.e4c181834665a8231969df9e9c30bdde.pngimage.png.3f16d620c844f675ce562b9ddf4941b8.pngimage.png.da8e97e531d7b595accfe498644918d7.pngimage.png.a825cc91e6360ce8555c09544b50cc10.png

image.png.747b48090b1cc74faab0fde70a8a534c.png

The results that I got using the Logic Analyzer became incorrect for the next characters:
image.png.4d4b427befa48b38a7cf148128fa1576.png

I'm also trying to do it in VB. Here's the code for it:

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"
        oReturn.Append(StartBit)
        For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(Text)
            oReturn.Append(StrReverse(Convert.ToString(Character, 2).PadLeft(8, "0")))
            'oReturn.Append((Convert.ToString(Character, 2).PadLeft(8, "0")))
        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 = 744
        Const fsDio = &HFFFF
        Const hzUart = 230400
        Const hzRate = hzUart * 1 '''''
        Const cSamples = 8 * 4 'RgLong is 4 characters
        Dim cBuffer As Integer
        Dim RgLong As String : RgLong = "UART"
        Dim secRun As Double : secRun = (Len(RgLong) * 8) * (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

Can anyone please explain why this is the case? Any advice will do.
 

Best regards,
Lesiastas

 

Edited by Lesiastas
Incomplete content
Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Update:
I was able to transmit a binary sequence consisting of:
image.png.48e060bee2c9b3cf12bdb87565578be1.png
1 start bit + (32 inverted data bits of the word "UART") + 1 stop bit + 6 additional "1" bits (to fill in missing bits in extra byte)

I enabled DIOs 0, 1, and 2. I transmitted the data using DIO 0 to DIO 2. The Logic Analyzer was able to receive these raw samples:

image.png.3726c6100d53358c1b94c35d908bcf9d.png

I was able to parse it by detecting the start bit first then converting the bits of the word "UART" into decimal values. After that, I convert the decimal values into ASCII format.

image.png.51f9dda2cc388948896b01dac5f4b1b3.png

The problem I observed is that the received result is still not the same with that of the transmitted data. We transmitted the word "UART" but received an incorrect data.

image.png.db42683f3f4771d69179ade4f4ad2400.png

image.png.bc24951fe4b9ec42978d66247b0c3b96.png

DIO0Mesg contains the received data. It has a few spaces after the received data.
Can anyone explain why this keeps on occuring? It would be a big help.Here's the latest VB code that I'm using:

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 = countOfDataBytes
        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 >> pin)
                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 >> 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
            Else
                'Detecting Stop Bit
                '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 >> pin)
                    If fData Then
                        bValue = bValue + (1 << b)
                    End If
                Next
                rgHex(i) = bValue
                i = i + (cSamplePerBit * 8) - 1

            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) 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 = 744
        Const fsDio = &HFFFF
        Const hzUart = 230400
        Const hzRate = hzUart * 1 '''''
        Const cSamples = 8 * 4 'RgLong is 4 characters
        Dim cBuffer As Integer
        Dim RgLong As String : RgLong = "UART"
        Dim secRun As Double : secRun = (Len(RgLong) * 8) * (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 - 9)
        End If

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

        '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 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


 

Best regards,
Lesiastas

image.png

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now