Jump to content

Kirsan

Members
  • Posts

    18
  • Joined

  • Last visited

Posts posted by Kirsan

  1. Hi @reddish

    Thanks for the answer.)

    I fixed the code according to your recommendations:

    digitalIn.triggerSourceSet(DwfTriggerSource.DetectorDigitalIn) #set trigger source --> Digital Input
    digitalIn.triggerSet(0,0,1,0) #set edge_rise trigger on DIO0
    digitalIn.counterSet(1) #set 1s timeout
    
    # print(digitalIn.status(True))
    print(digitalIn.counterGet()) #get timeout setting
    print(digitalIn.counterInfo()) #get max Count and max timeout from device
    
    digitalIn.configure(1,1) #Load settings to Digital Input instrument and start it
    
    for i in range(10):
           digitalIn.status(False)
           time.sleep(0.5) #Wait + 0.5s for get results
           print(digitalIn.counterStatus()) #get result

    Now result is:

    1.0
    (4294967295, 17.179869176)
    (0.0, 0.0, 0)
    (0.0, 0.0, 0)
    (2070649.0, 2070648.5797816024, 1)
    (2070649.0, 2070648.5797816024, 1)
    (2070618.0, 2070618.358325643, 0)
    (2070618.0, 2070618.358325643, 0)
    (2070570.0, 2070569.8613570624, 1)
    (2070570.0, 2070569.8613570624, 1)
    (2070544.0, 2070544.391405831, 0)
    (2070544.0, 2070544.391405831, 0)

    I did not find DwfTriggerSource.DigitalInSource but I think that you mean DwfTriggerSource.DetectorDigitalIn.

    And it values is 3. Also in standard py example. Now I see it.

    DwfTriggerSource.DetectorDigitalIn has value 5.

    Also I noticed that no matter  digitalIn.status(False) or digitalIn.status(True), result will be the same.

  2. Hi @attila, @reddish

    Another question)

    It is about counter.

    65485871_.png.4fde753b829a48b9cd3bff50954c20a6.png

    Am I correct understand that "Counter" instrument work with base frequency which for AD3 is from 50MHz to 125MHz?

     

    And I try to use it and found some problem.

    I send ~2MHz signal on DIO0.

    So, I used standard  py example with little changes to see how it should works:

    """
       DWF Python Example
       Author:  Digilent, Inc.
       Revision:  2022-03-22
    
       Requires:                       
           Python 2.7, 3
    """
    
    from ctypes import *
    from dwfconstants import *
    import time
    import sys
    
    if sys.platform.startswith("win"):
        dwf = cdll.dwf
    elif sys.platform.startswith("darwin"):
        dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
    else:
        dwf = cdll.LoadLibrary("libdwf.so")
    
    
    version = create_string_buffer(16)
    dwf.FDwfGetVersion(version)
    print("DWF Version: "+str(version.value))
    
    #open device
    "Opening first device..."
    hdwf = c_int()
    if dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf)) != 1 or hdwf.value == hdwfNone.value:
        szerr = create_string_buffer(512)
        dwf.FDwfGetLastErrorMsg(szerr)
        print(szerr.value)
        print("failed to open device")
        quit()
    
    # any internal or external trigger source can be used
    if True:
        dwf.FDwfDigitalInTriggerSourceSet(hdwf, trigsrcDetectorDigitalIn)
        dwf.FDwfDigitalInTriggerSet(hdwf, c_int(0), c_int(0), c_int(1<<0), c_int(0))
    
    timeout = 1.0 # frequency measurement refresh interval, 0 just count
    dwf.FDwfDigitalInCounterSet(hdwf, c_double(timeout))
    
    dwf.FDwfDigitalInConfigure(hdwf, c_int(1), c_int(1))
    
    print("Press Ctrl+C to stop")
    try:
        count2 = 0
        tick2 = 0
        countSum = 0
        while True:
            if timeout == 0: time.sleep(1) # wait 1 second
            else: time.sleep(timeout/2) # wait less then the specified timeout to make sure each measurement is captured
    
            if dwf.FDwfDigitalInStatus(hdwf, c_int(0), None) != 1:
                szerr = create_string_buffer(512)
                dwf.FDwfGetLastErrorMsg(szerr)
                print(szerr.value)
                quit()
                
            count = c_double()
            freq = c_double()
            tick = c_int()
            dwf.FDwfDigitalInCounterStatus(hdwf, byref(count), byref(freq), byref(tick))
    
            if timeout == 0.0: # just count
                if count.value < count2: # counter rollover
                    countSum += countMax.value+1 
                print("Count: "+str(countSum+count.value))
            else: # frequency measurement
                if tick.value != tick2: # new measurement 
                    countSum += count2 # sum earlier counts
                    print("Count: "+str(countSum+count.value)+" Freq: "+str(freq.value)+"Hz")
            count2 = count.value
            tick2 = tick.value
            
    except KeyboardInterrupt:
        pass
    
    
    dwf.FDwfDeviceCloseAll()

    The result is:

    DWF Version: b'3.20.34'
    Press Ctrl+C to stop
    Count: 2071589.0 Freq: 2071589.1600899296Hz
    Count: 4143142.0 Freq: 2071553.1393542266Hz
    Count: 6214737.0 Freq: 2071595.38796891Hz

    It looks good.

     

    Then I tried to realized the same via pydwf with some little changes:

    import ctypes
    import time
    import numpy
    import pydwf.core.auxiliary.enum_types
    from pydwf import *
    
    dwf = pydwf.DwfLibrary()
    
    device = pydwf.DeviceControl(dwf)
    pydwf.DeviceEnumeration(dwf).enumerateDevices()
    device.openEx("index:1,config:0")
    
    AD3 = pydwf.DwfDevice(dwf,1)
    AD3.paramSet(pydwf.DwfDeviceParameter.Frequency, 100_000_000)
    
    digitalIn = AD3.digitalIn
    digitalIn.triggerSourceSet(DwfTriggerSource.DigitalIn) #set trigger source --> Digital Input
    digitalIn.triggerSet(0,0,1,0) #set edge_rise trigger on DIO0
    digitalIn.counterSet(1) #set 1s timeout
    
    print(digitalIn.counterGet()) #get timeout setting
    print(digitalIn.counterInfo()) #get max Count and max timeout from device
    
    digitalIn.configure(1,1) #Load settings to Digital Input instrument and start it
    for i in range(3):
           time.sleep(0.5) #Wait + 0.5s for get results
           print(digitalIn.counterStatus()) #get result

    The result is:

    1.0
    (4294967295, 21.47483647)
    (0.0, 0.0, 0)
    (0.0, 0.0, 0)
    (0.0, 0.0, 0)

    No data here.(

    Perhaps I missed something in the configuration of the "Counter" and the "Digital Inputs", but it seems that I repeated all the same steps as in the standard example.

  3. Hi @reddish )

    I have question about the next function:

     def triggerSet(self, level_low: int, level_high: int, edge_rise: int, edge_fall: int) -> None:
            """Set |DigitalIn| trigger detector conditions.
    
            The *level_low* and *level_high* settings effectively mask trigger detection events to clock cycles where
            the selected pins are low or high, respectively.
    
            The *edge_rise* and *edge_fall* indicate channels where the specific type of transition on any of the
            included channels will lead to a trigger event, ar least if the level conditions specified by the *level_low*
            and *level_high* settings are satisfied.
    
            Parameters:
                level_low (int): The channels that are required to be low for a trigger event to occur (bitfield).
                level_high (int): The channels that are required to be high for a trigger event to occur (bitfield).
                edge_rise (int): The channels where a rising edge will cause a trigger event (bitfield).
                edge_fall (int): The channels where a falling edge will cause a trigger event (bitfield).
    
            Raises:
                DwfLibraryError: An error occurred while executing the operation.
            """
            result = self.lib.FDwfDigitalInTriggerSet(
                self.hdwf,
                level_low,
                level_high,
                edge_rise,
                edge_fall)
            if result != RESULT_SUCCESS:
                raise self.dwf.exception()

    As I understand this functions is responsible for this settings:

    1756829186_.png.8e7ea11c8b5a0c34f8f4196d85cb472a.png

    Is the following lines correct?

    For example, if I need to set on DIO0 "Rise" edge:

    triggerSet(level_low = 0, level_high = 0, edge_rise = 1, edge_fall = 0)

    To set "Rise" edge on "DIO0" and "DIO1":

    triggerSet(level_low = 0, level_high = 0, edge_rise = 3, edge_fall = 0)

    To set "Ignore" on "DIO0" and "Rise" edge on "DIO1":

    triggerSet(level_low = 0, level_high = 0, edge_rise = 2, edge_fall = 0)

     

    And a little clarification about the next sentence:

    Quote

    The *edge_rise* and *edge_fall* indicate channels where the specific type of transition on any of the included channels will lead to a trigger event, ar least if the level conditions specified by the *level_low* and *level_high* settings are satisfied.

    Am I correct understand that it meas that, "level_low" and "level_high" trigger settings have higher priority then "edge_rise" and "edge_fall"?

    For example:

    If I set on DIO0 "Rise" edge and also set "level_high":

    triggerSet(level_low = 0, level_high = 1, edge_rise = 1, edge_fall = 0)

    So it means that trigger signal will be something like on next picture:

    wavedrom.png.520932b759a726b1c907c7d5d28db722.png

     

    I understand that such a case generally does not make sense. It's worth using just one thing: "edge_rise"/"edge_fall" or "level_high"/"level_low" not both. However, this question is more for a general understanding of how this function works.

  4. @reddishHi)

    I would like to clarify a little more about the next moment.

    digitalIn.bufferSizeSet(64)

    If I understand correctly, this setting is responsible for the buffer depth. And in the WaveForms it is:

    1070358567_.png.67694d9fd7ccb1cc0541321e351fd20a.png

    So, if I set 64 it means that samples buffer depth --> 64 samples.

    And then if read data:

    data = digitalIn.statusData(64)

    result will be:

    Waiting for acquisition...
       done
    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    64
    

    So, here length of array is 64. This is the maximum. And looks good.

     

    But, if I try read data(buffer depth the same, 64):

    data = digitalIn.statusData(2*64)

    result will be:

    Waiting for acquisition...
       done
    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    128

    Here the length of array is 2*64=128. It’s as if we’re reading them from the memory area just in a circle.

     

    In standard py example:

    dwf.FDwfDigitalInStatusData(hdwf, rgwSamples, 2*cSamples)

    It doesn't matter if the coefficient 2 changes to any other number. The array length will be the same as "buffer size":

    # set number of sample to acquire
    cSamples = 64
    rgwSamples = (c_uint16*cSamples)()
    dwf.FDwfDigitalInBufferSizeSet(hdwf, c_int(cSamples))

     

     

  5. Hi @reddish

    Thank you for help, now this script works fine.

    I'm willing to help with some testing as I'm still figuring this out.

     

    Also, how should I set "trigger_source" in this function?

        def triggerSourceSet(self, trigger_source: DwfTriggerSource) -> None:
            """Set |DigitalIn| instrument trigger source.
    
            Parameters:
                trigger_source (DwfTriggerSource): The trigger source to be configured.
    
            Raises:
                DwfLibraryError: An error occurred while executing the operation.
            """
            result = self.lib.FDwfDigitalInTriggerSourceSet(self.hdwf, trigger_source.value)
            if result != RESULT_SUCCESS:
                raise self.dwf.exception()

    I mean, do I need to connect enum _types in script file, like:

    import pydwf.core.auxiliary.enum_types

    ?

  6. Hi @reddish and @attila.

    I try to use digital inputs(logic analyzer[LA]) + pydwf + AD2/3.

    I'm relatively new to using Python.

    My main task is use patterns and LA at the same time to program and read some IC with unique protocol.

    So at first I tried to use LA and python.

    I send signals to two inputs (D0, D1):

    .thumb.png.73b9226ad3c57ba66c55fe99c63772e6.png

    The next step, I used standard  py example with little changes to see how it should works:

    from ctypes import *
    from dwfconstants import *
    import math
    import time
    import matplotlib.pyplot as plt
    import sys
    import numpy
    
    if sys.platform.startswith("win"):
        dwf = cdll.dwf
    elif sys.platform.startswith("darwin"):
        dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
    else:
        dwf = cdll.LoadLibrary("libdwf.so")
    
    hdwf = c_int()
    sts = c_byte()
    
    version = create_string_buffer(16)
    dwf.FDwfGetVersion(version)
    print("DWF Version: "+str(version.value))
    
    #open device
    print("Opening first device")
    dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
    
    if hdwf.value == 0:
        print("failed to open device")
        szerr = create_string_buffer(512)
        dwf.FDwfGetLastErrorMsg(szerr)
        print(str(szerr.value))
        quit()
    
    # sample rate = system frequency / divider
    hzDI = c_double()
    dwf.FDwfDigitalInInternalClockInfo(hdwf, byref(hzDI))
    dwf.FDwfDigitalInDividerSet(hdwf, c_int(int(hzDI.value/100e6))) # 100MHz
    # 16bit per sample format
    dwf.FDwfDigitalInSampleFormatSet(hdwf, c_int(16))
    # set number of sample to acquire
    cSamples = 64
    rgwSamples = (c_uint16*cSamples)()
    dwf.FDwfDigitalInBufferSizeSet(hdwf, c_int(cSamples))
    
    # begin acquisition
    dwf.FDwfDigitalInConfigure(hdwf, c_int(0), c_int(1))
    
    print("Waiting for acquisition...")
    while True:
        dwf.FDwfDigitalInStatus(hdwf, c_int(1), byref(sts))
        if sts.value == stsDone.value :
            break
        time.sleep(1)
    print("   done")
    
    # get samples, byte size
    dwf.FDwfDigitalInStatusData(hdwf, rgwSamples, 2*cSamples)
    dwf.FDwfDeviceCloseAll()
    print(numpy.fromiter(rgwSamples, dtype = numpy.uint16))
    print(len(numpy.fromiter(rgwSamples, dtype = numpy.uint16)))

    And result is:

    DWF Version: b'3.20.34'
    Opening first device
    Waiting for acquisition...
       done
    [3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 2 2 2 2]
    64

    It looks normal and correct.

     

    Next step, I tried to realized the same via pydwf with some little changes:

    import time
    import pydwf
    
    dwf = pydwf.DwfLibrary()
    
    device = pydwf.DeviceControl(dwf)
    pydwf.DeviceEnumeration(dwf).enumerateDevices()
    device.openEx("index:1,config:0")
    
    AD3 = pydwf.DwfDevice(dwf,1)
    AD3.paramSet(pydwf.DwfDeviceParameter.Frequency, 100_000_000)
    
    digitalIn = AD3.digitalIn
    digitalIn.dividerSet(1)
    digitalIn.sampleFormatSet(16)
    digitalIn.bufferSizeSet(64)
    digitalIn.configure(0,1)
    print("Waiting for acquisition...")
    while True:
        status = digitalIn.status(True).name
        if status == "Done":
            break
        time.sleep(1)
    print("   done")
    
    
    data = digitalIn.statusData(64)
    print(data)
    print(len(data))

    And result is:

    Waiting for acquisition...
       done
    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
     0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]
    64

    It looks strange. Looks like signal missed some data).

     

    In general, both scripts do the same, but results are different.

     

    I also noted that if I change in the next line:

    dwf.FDwfDigitalInStatusData(hdwf, rgwSamples, 2*cSamples)

    coefficient from 2 to 1 or 4(for example):

    dwf.FDwfDigitalInStatusData(hdwf, rgwSamples, 4*cSamples)

    result will be the same, and array length will be the same(64).

    If I understand correctly, then the data from the AD3 buffer with a depth of 64 bits was read into a memory area with a depth of 64 bits and therefore the result cannot be greater, which is logical.

    But, if I changed the next line:

    data = digitalIn.statusData(64)

    to

    data = digitalIn.statusData(2*64)

    array length will be the 128.

    But, if I understated correctly, this parameter in function should do the same as in original py example:

        def statusData(self, count_bytes: int) -> np.ndarray:
            """Retrieve the acquired data samples from the |DigitalIn| instrument.
    
            Todo:
                Figure out the data format.
    
            Raises:
                DwfLibraryError: An error occurred while executing the operation.
            """
            samples = np.empty(count_bytes, dtype='B')
            result = self.lib.FDwfDigitalInStatusData(
                self.hdwf,
                samples.ctypes.data_as(typespec_ctypes.c_unsigned_char_ptr),
                count_bytes)
            if result != RESULT_SUCCESS:
                raise self.dwf.exception()
            return samples

    Could you please help me?)

  7. Hi @attila

    Thank you for the answer.

    Yes, for the now this scheme work for my situation.

    Is it possible that in some future releases of the WaveForms, you will be able to add a similar behavior(as some option or few options) of the SPI for read and write modes?

    553324412_.png.369a20b158d7519d73d471266865f586.png

    170957277_.png.8b43a7984837f2a11b377d475e2f4397.png

     

  8. Hi @JColvin

    Thank you for the answer.

    Sorry, it was necessary to describe my question in more detail.

    I'm trying to figure out if it's possible to form a bit that tells the slave that this will be a "read\write procedure" command.

    As far as I can see, if I run the "read" command from the "protocol-spi" tool, then the AD3 will first transfer the data (I sent a some device address). Then the AD3 moves the MOSI line to the high level. What is the "read procedure" indicator for the slave device.

    927898451_.png.553495278559ca0c529ab9ce05e415a1.thumb.png.cc2b557c36765963a8458c9ead6d1784.png

    But, the device I'm trying to communicate with via the SPI protocol uses the first bit in the message as the "read/write procedure" indicator.

    Read(high level on MOSI line):

    519197907_.png.33ca471d74f8fa89bcce106a9279a07f.png.99ce307018f090031e8b70ee7312e9b7.png

    Write(low level on MOSI line):

    1977716787_.png.deecda4260c0ce36816e03e8410e460b.png.576da82cace358d8f8bc5c3506f80840.png

     

    At the moment, I found a way out in that I transfer the address not 0x0038, but 0x8038. That imitates the desired pattern of behavior. For some reason, I didn't think about it from the beginning.

  9. Hi forum users. Please tell me, is it possible using an analog discovery 2/3, using the "protocol" tool to implement the following behavior of the SPI?

    519197907_.png.33ca471d74f8fa89bcce106a9279a07f.png
    1977716787_.png.deecda4260c0ce36816e03e8410e460b.png

     

    I'm trying to figure it out, but as far as I can see, the transmission of the "read/write" event is different from what I would like to receive.

    .thumb.png.635329b498d347c2187aa9b413c2c7e6.png

  10. Hi @attila

    Thanks for the answer, I'll wait for the update of the program.)

    Still, I think it will be more convenient in future versions to give the ability to control the thickness of the cursor separately from the thickness of the line. This will give you more flexibility.

    I would also like to suggest duplicating the pointers of the beginning of the waveform after the trigger. And move to the left or right of the "0s" label relative to the pointer. So that they do not overlap each other. Or delete "0s" label.

    This will improve the user experience when it need to save separately(digital/oscilloscope) or together the waveform as a picture and issue some kind of report.

    2022-08-25 155416.png

  11. Hi @attila

    Thanks a lot. Indeed, in the new version of the software, the impedance works correctly. I am ready to help you in testing software paired with virtual bench 8034. I would be very happy to provide you with such help. Here is my mail: iutin.yan@gmail.com .

    I also noticed that visually the oscilloscope signal is shifted relative to the trigger. If you change the time base, then visually the signal is shifted in different ways relative to the trigger. I think this is related to the sample rate, since your software and standard software show it differently, and therefore interpret the data somewhat differently. Of course, the sample rate can be specified manually, which is very good. If one day you fix this in future releases, it will be great. Well, if not, then no. In any case, I will be glad to help you debug software paired with a bench.

    1_2021-11-23 154141.png

    2_2021-11-23 154214.png

    3_2021-11-23 154257.png

    4_2021-11-23 154327.png

    time_shift.7z

  12. Hi @JColvin, @attila

    As far as I understand, virtual bench 8012 and Digilent's Analog Discovery Pro ADP5250 are one and the same. Details and nuances are unknown to me.

    However, in fact, I see that your software detects my version of the virtual bench (8034). 8012 from 8034 is not very different.
    So it is expected that everything works very well with it, except that your software sets the input impedance of the oscilloscope's analog channel to 50 Ohm and does not allow you to change it.

    From my point of view, you just need to add a few commands to your software to send them to the virtual bench and push 1MOhm instead of 50Ohm. It's not hard to do.

    However, I understand that the virtual bench is probably some kind of internal competitor of Digilent's Analog Discovery Pro ADP5250. And in fact, the virtual bench should not be supported by your software. Marketing and all that. I can understand that.

    But since there is such compatibility, why not support it. Let it be secret, but still. Your software is better than the standard software virtual bench. Everything is better implemented.
     
    In my opinion, this kind of support would be helpful.
    However, the final decision is of course yours.

  13. Good afternoon. I own a virtual bench 8034. And recently I bought Analog Discovery 2. I really liked the WaveForms software. And I noticed that there is support for virtual bench. I was pleasantly surprised. However, as far as I understand, virtual bench support is a nice bonus and not the main goal of your software. But still. I noticed that not all settings work correctly. So far, only talking about the oscilloscope function. Screenshots I am attaching.

    The problem is that your software sets the impedance to 50 Ohm for some reason. And it does not allow switching the input to 1MΩ. Therefore, any input signal is clipped by the cut. I checked several times, there is no error. Your software version is 3.17.14 64 bit. Perhaps you can fix this? Your software is much better than the standard virtual bench software. And I would like to continue to use only your software.

    bench_2021-11-22 150318.png

    bench_ 2021-11-22 150408.png

    bench_2021-11-22 150907.png

    bench_2021-11-22 150935.png

×
×
  • Create New...