Jump to content

JRys

MCC Staff
  • Posts

    1,460
  • Joined

  • Last visited

Everything posted by JRys

  1. Please review the following forum thread regarding Raspberry PI 5 support.
  2. The PersonalDaq 54, 55, and 56 do not support Windows 10 or 11. However, some of our customers have found ways to make them work. One tip I have found is to ensure the computer's hardware has the latest updates from the manufacturer. This is especially true for new computers, which often ship with outdated firmware. I have also found that some manufacturers do not make drivers available for Windows 10 or 11 that run on older hardware. I have a Dell Precision 5820 desktop with Windows 11 that works with the PersonalDaqs, so it can work.
  3. I apologize for the late response. GND and AGND are connected on the PCB board. However, the AGND path is meant for analog grounds only. Digital grounds tend to have switching noise, and running separate paths reduces overall measurement noise. On the other hand, a ground loop can appear as a noisy signal. If you suspect a ground loop, use a differential connection instead of a single-ended one.
  4. Hello, I've tested the emacspif_speed.c file patch with Vitis 2022.1 and 2023.1 using a Zybo Z7-10 Ref F chip. At first, it didn't work for me, but it was because I applied the patch after I created and built the project. I thought I could just rebuild the project for the patch to work, but it failed. The solution I found was to make a new project. Attached is the patch file I used. Change the extension to .c and copy it to: C:\Xilinx\Vitis\2021.1\data\embeddedsw\ThirdParty\sw_services\lwip211_v1_7\src\contrib\ports\xilinx\netif\. Best regards, John xemacpsif_physpeed.txt
  5. We recommend the USB-2408-2AO and the free DAQami software.
  6. Hello, To determine the key being pressed, you must set each column line low one at a time while simultaneously reading the rows. Review the following article to get an idea of what is needed to read the key and update the display: https://fpgacoding.com/pmod-keypad-peripheral-first-look/. Their method uses a counter to create a one-millisecond delay between setting each column low, one at a time, while reading the rows. Best regards, John
  7. The driver issue could be caused by the hardware no longer functioning correctly. Unplug the USB connection, then restart Windows. Plug it back in and try again. If it is in working order, Windows will reinstall it. If not, let me know the device's serial number, and I will see if it can be repaired.
  8. There are no example programs that show how to read the HPF file, but an end user did attempt it. https://github.com/jogrundy/Read_QuickDAQ_.hpf/blob/master/read_hpf.py Attached is the file format document. HPF_High_Performance_File_specification.doc
  9. PostView is a separate program used to display saved data. It needs to be installed, so, exit Personal DaqView and run the following: https://files.digilent.com/downloads/iotech_software/PersonalDaq50_Series/postviewsetup.exe
  10. None of our current products offer gated control. However, they do have external ADC clock support, and if you could control the external ADC clock, you would be able to control the ADC. A device like the USB-1608GX and USB-1808X have a timer output that can be used as a clock, which is half the battle. The other half is developing a gate circuit to function as a control.
  11. The USB-1208FS-PLUS is on the list of devices they support. https://www.mathworks.com/hardware-support/measurement-computing.html
  12. Please watch the following video about installing DASYLab and the Measurement Computing support. It will show how to install the Measurement Computing driver and access the input and output modules. When the driver installation gets to the destination folder panel, edit the path (press Change) so that it is \Program Files (x86)\DASYLab 2022.1_en\. Otherwise, you will get a path not found error.
  13. The manual says to connect a 50-ohm resistor to the ground on the detector output. The output is current, and the resistor generates the output voltage. Connect the MCC 128 input across the resistor. I recommend placing the inputs in differential mode for the measurement. If the signal is too low with the 50 ohm resistor, use a 1000-ohm load resistor.
  14. Could you send me the optical detector datasheet and model number, and let me know the voltage measured from the input ground to the output ground of the 12V to 5V Transformer?
  15. The message pops up because 1.) you do not have a sound card installed, and 2.) you have the sound card support enabled in the Configurator. It is enabled by default, and you can either check the box on the message not to display it again or disable the sound card support in the Configurator. I recommended checking the message box so it doesn't bug you anymore.
  16. Restart DASYLab with administrator privileges. Go to c:\Program Files (x86)\DASYLab 2022.1_en\ and get the properties for DASYLab.exe. Select the Compatibility tab and enable Run this program as an administrator.
  17. Neither DAQami nor DASYLab can display 64 channels on a single graph or chart. Instead, 64 channels should be distributed to several DAQami strip charts. You can create additional tab pages to make it easier to navigate multiple charts. When using various devices, DAQami writes the data for each one into a separate file.
  18. You can add more USB-TEMPs and use DAQami. But if you want one file with 64 channels, use DASYLab BASIC. You have too many channels for DASYLab LITE. DASYLab modules are limited to 16 channels, which limits the number you can write to file. To get around the limitation, the Multiplexer module can take up to 16 inputs and output them as a single stream. Connect this output to a Data Write module, and, in the setting, configure the number of channels coming in on that input. When properly configured, the Data Write unpacks channels to be written to a file.
  19. The following program generates a ~10 Hz sine wave on analog output 0 with an update rate of 1000 S/s. It also captures data on the analog input channel 0 at 500 S/s. I have also tested it at 1100, which is the max. You should be able to use two channels at 550 S/s. The config(board_num, num_chans) function performs the setting normally done by InstaCal. Attached below is the file. from __future__ import absolute_import, division, print_function import time from builtins import * # @UnusedWildImport from ctypes import addressof, sizeof, cast, POINTER, c_double, c_ushort from math import pi, sin from time import sleep from mcculw import ul from mcculw.enums import (AiChanType, BoardInfo, Status, InterfaceType, FunctionType, InfoType, ScanOptions, ULRange, AnalogInputMode) use_device_detection = True packet_size = 32 def config(board_num: int, n_channels: int): for ch in range(n_channels): ul.set_config( InfoType.BOARDINFO, board_num, ch, BoardInfo.ADCHANTYPE, AiChanType.VOLTAGE ) # ul.set_config( # InfoType.BOARDINFO, board_num, ch, # BoardInfo.CHANTCTYPE, TcType.K # ) ul.set_config( InfoType.BOARDINFO, board_num, ch, BoardInfo.ADDATARATE, 3750 ) def run_example(): dev_id_list = [] board_num = 0 desired_rate = 512 actual_rate = 0 desired_out_rate = 1000 actual_out_rate = 0 file_name = 'scan_data.csv' memhandle = None # The size of the UL buffer to create, in seconds buffer_size_seconds = 2 # The number of buffers to write. After this number of UL buffers are # written to file, the example will be stopped. num_buffers_to_write = 5 board_num = 0 board_index = 0 find_device = "USB-2416-4AO" if use_device_detection: board_num = -1 ul.ignore_instacal() dev_list = ul.get_daq_device_inventory(InterfaceType.USB) if len(dev_list) > 0: for device in dev_list: if str(device) == find_device: print(f"Found {find_device} board number = {board_index}") print(f"Serial number: {device.unique_id}") print(f"Product type: {hex(device.product_id)}") board_num = board_index ul.create_daq_device(board_num, device) board_index = board_index + 1 if board_num == -1: print(f"Device {find_device} not found") return else: print("No devices detected") return # **********End of Discovery************ try: chan = 0 num_chans = 1 config(board_num, num_chans) ul.a_chan_input_mode(board_num, chan, AnalogInputMode.SINGLE_ENDED) # Create a circular buffer that can hold buffer_size_seconds worth of # data, or at least 10 points (this may need to be adjusted to prevent # a buffer overrun) points_per_channel = max(desired_rate * buffer_size_seconds, 10) ul_buffer_count = points_per_channel * num_chans # Write the UL buffer to the file num_buffers_to_write times. points_to_write = ul_buffer_count * num_buffers_to_write # When handling the buffer, we will read 1/10 of the buffer at a time write_chunk_size = int(ul_buffer_count / 10) scan_options = (ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS | ScanOptions.SCALEDATA) memhandle = ul.scaled_win_buf_alloc(ul_buffer_count) # Allocate an array of doubles temporary storage of the data write_chunk_array = (c_double * write_chunk_size)() # Check if the buffer was successfully allocated if not memhandle: raise Exception('Failed to allocate memory') # set output to zero zero_volts = 0.0 ul.v_out(board_num, 0, ULRange.BIP10VOLTS, zero_volts, 0) # Allocate a buffer for the scan count = 1024 memhandle2 = ul.win_buf_alloc(count) # Convert the memhandle to a ctypes array # Note: the ctypes array will no longer be valid after win_buf_free # is called. # A copy of the buffer can be created using win_buf_to_array # before the memory is freed. The copy can be used at any time. ctypes_array = cast(memhandle2, POINTER(c_ushort)) # Check if the buffer was successfully allocated if not memhandle2: raise Exception('Error: Failed to allocate memory') frequencies = add_example_data(board_num, ctypes_array, ULRange.BIP10VOLTS, num_chans, desired_out_rate, count) print("Channel", chan, 'Output Signal Frequency:', frequencies[chan]) # Start single channel output scan actual_out_rate = ul.a_out_scan(board_num, chan, chan, count, desired_out_rate, ULRange.BIP10VOLTS, memhandle2, ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS) print('desired output rate =: ' + str(desired_out_rate)) print('actual output rate =: ' + str(actual_out_rate)) # Start the scan actual_rate = ul.a_in_scan( board_num, chan, chan, ul_buffer_count, desired_rate, ULRange.BIP10VOLTS, memhandle, scan_options) print('desired input rate =: ' + str(desired_rate)) print('actual input rate =: ' + str(actual_rate)) status = Status.IDLE # Wait for the scan to start fully while status == Status.IDLE: status, _, _ = ul.get_status(board_num, FunctionType.AIFUNCTION) # Create a file for storing the data with open(file_name, 'w') as f: print('Writing data to ' + file_name, end='') # Write a header to the file for chan_num in range(chan, chan + 1): f.write('Channel ' + str(chan_num) + ',') f.write(u'\n') prev_count = 0 prev_index = 0 write_ch_num = chan while status != Status.IDLE: # Get the latest counts status, curr_count, _ = ul.get_status(board_num, FunctionType.AIFUNCTION) new_data_count = curr_count - prev_count # Check for a buffer overrun before copying the data, so # that no attempts are made to copy more than a full buffer # of data if new_data_count > ul_buffer_count: # Print an error and stop writing ul.stop_background(board_num, FunctionType.AIFUNCTION) print('A buffer overrun occurred') break # Check if a chunk is available if new_data_count > write_chunk_size: wrote_chunk = True # Copy the current data to a new array # Check if the data wraps around the end of the UL # buffer. Multiple copy operations will be required. if prev_index + write_chunk_size > ul_buffer_count - 1: first_chunk_size = ul_buffer_count - prev_index second_chunk_size = ( write_chunk_size - first_chunk_size) # Copy the first chunk of data to the # write_chunk_array ul.scaled_win_buf_to_array( memhandle, write_chunk_array, prev_index, first_chunk_size) # Create a pointer to the location in # write_chunk_array where we want to copy the # remaining data second_chunk_pointer = cast(addressof(write_chunk_array) + first_chunk_size * sizeof(c_double), POINTER(c_double)) # Copy the second chunk of data to the # write_chunk_array ul.scaled_win_buf_to_array( memhandle, second_chunk_pointer, 0, second_chunk_size) else: # Copy the data to the write_chunk_array ul.scaled_win_buf_to_array( memhandle, write_chunk_array, prev_index, write_chunk_size) # Check for a buffer overrun just after copying the data # from the UL buffer. This will ensure that the data was # not overwritten in the UL buffer before the copy was # completed. This should be done before writing to the # file, so that corrupt data does not end up in it. status, curr_count, _ = ul.get_status( board_num, FunctionType.AIFUNCTION) if curr_count - prev_count > ul_buffer_count: # Print an error and stop writing ul.stop_background(board_num, FunctionType.AIFUNCTION) print('A buffer overrun occurred') break for i in range(write_chunk_size): f.write(str(write_chunk_array[i]) + ',') write_ch_num += 1 if write_ch_num == chan + 1: write_ch_num = chan f.write(u'\n') else: wrote_chunk = False if wrote_chunk: # Increment prev_count by the chunk size prev_count += write_chunk_size # Increment prev_index by the chunk size prev_index += write_chunk_size # Wrap prev_index to the size of the UL buffer prev_index %= ul_buffer_count if prev_count >= points_to_write: break print('.', end='') else: # Wait a short amount of time for more data to be # acquired. sleep(0.1) ul.stop_background(board_num, FunctionType.AOFUNCTION) ul.v_out(board_num, 0, ULRange.BIP10VOLTS, zero_volts, 0) ul.stop_background(board_num, FunctionType.AIFUNCTION) except Exception as e: print('\n', e) finally: print('Done') if memhandle: # Free the buffer in a final block to prevent a memory leak. ul.win_buf_free(memhandle) if use_device_detection: ul.release_daq_device(board_num) def add_example_data(board_num, data_array, ao_range, num_chans, rate, points_per_channel): # Calculate frequencies that will work well with the size of the array frequencies = [] for channel_num in range(num_chans): frequencies.append( (channel_num + 1) / (points_per_channel / rate) * 10) # Calculate an amplitude and y-offset for the signal # to fill the analog output range amplitude = (ao_range.range_max - ao_range.range_min) / 2 y_offset = (amplitude + ao_range.range_min) / 2 # Fill the array with sine wave data at the calculated frequencies. # Note that since we are using the SCALEDATA option, the values # added to data_array are the actual voltage values that the device # will output data_index = 0 for point_num in range(points_per_channel): for channel_num in range(num_chans): freq = frequencies[channel_num] value = amplitude * sin(2 * pi * freq * point_num / rate) + y_offset raw_value = ul.from_eng_units(board_num, ao_range, value) data_array[data_index] = raw_value data_index += 1 return frequencies if __name__ == '__main__': run_example() a_in_scan_file_2416_py.txt
  20. The DAQ Adaptor for MATLAB does not have a channel Sensitivity function, hence the error message. Instead, you could do your own scaling with some simple math. Let's say you have an array of voltage measurements. Divide the values in the array by 0.00922 to get g's.
  21. Use the QuickDAQ export feature to generate a text version of the data. See page 37 in the following PDF: https://files.digilent.com/downloads/DTSoftware/QuickDAQ/QuickDAQ.pdf Use File->Open Hpf Data File to reopen and convert previously recorded files.
  22. Could you jump into InstaCal and check how channel 0 is configured and how the Data Rate filter property is set? It must be set to 3750 to sample at 550 samples per second. Page 16 in the user manual discusses throughput rates. Another thing to keep in mind is that the USB-2416-4AO is a device that remembers how it is set even after power is removed. Not all MCC devices do this. So, if a colleague sets it for temperature and you try to use it for voltage, it will generate an error until it is reconfigured with InstaCal.
  23. You can synchronize two or more devices using the Sync IO output clock. It is turned off by default, but you can enable it with InstaCal or the programming interface. Connect the Sync terminal to both devices, but allow Sync output only on one. Program the device that outputs the Sync last. Sharing the Sync signal will allow both devices to record data simultaneously.
  24. Below is my get-board number function. It takes a device name string, such as '1208FS', to search for the device. Once it finds a device name that contains '1208FS', it determines if 'Plus' is in the name and, if so, sets the global variable PACKETSIZE to 32. Otherwise, it's 31. It is crucial to size the buffer as a multiple of PACKETSIZE times channel count. I have also attached my test program below that uses this function. public static int GetBoardNum(string dev) { MccDaq.DaqDeviceManager.IgnoreInstaCal(); MccDaq.DaqDeviceDescriptor[] inventory = MccDaq.DaqDeviceManager.GetDaqDeviceInventory(MccDaq.DaqDeviceInterface.Any); int DevicesFound = inventory.Length; if (DevicesFound > 0) { for (int boardNum = 0; boardNum < DevicesFound; boardNum++) { try { if (inventory[boardNum].ProductName.Contains(dev)) { MccDaq.MccBoard daqBoard = MccDaq.DaqDeviceManager.CreateDaqDevice(boardNum, inventory[boardNum]); if (daqBoard.BoardName.Contains("Plus")) PACKETSIZE = 32; else PACKETSIZE = 31; return boardNum; } } catch (ULException ule) { Console.WriteLine("Error occurred: " + ule.Message); } } } return -1; } USB_1208FS_CONT_EXAMPLE.cs
  25. The MCC 172 is not designed to use an external clock because the clock runs 512x the sample rate, and a sync pulse is used to synchronize the ADCs. GPIO 19 is used to clock other MCC 172 boards on the RPI stack, and a sync pulse on GPIO 6 synchronizes all the ADCs. None of the other MCC daqhat boards can use its clock. After the sync pulse is set low, it takes 128 conversions before data is ready. You can make the clock appear on GPIO 19 using the SOURCE_MASTER clock mode with the mcc172_a_in_clock_config_write function.
×
×
  • Create New...