Jump to content

Scardig

Members
  • Posts

    4
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Scardig's Achievements

Newbie

Newbie (1/4)

0

Reputation

  1. I agree with the results of your test (and thanx for the effort in trying it on real hardware) but, even if the basic principle is the same, my setup is the "opposite": read AI then write AO. Anyway, by taking a look at the main loop of my code in the first post (that you can run in whole without modifications to reproduce the behaviour: no timer involved, just wire AO0 to AI1 and use an external wavegen to AO0) this is what happens when I first start my script: 1. OUTPUT and INPUT setup output_sample_rate = 100000 output_samples_per_channel = 2 * 4000 out_buffer = create_float_buffer(output_high_channel - output_low_channel + 1, output_samples_per_channel) output_buffer_mid_point = int(len(out_buffer) / 2) input_sample_rate = 100000 input_samples_per_channel = 2 * 4000 in_buffer = create_float_buffer(input_high_channel - input_low_channel + 1, input_samples_per_channel) input_buffer_mid_point = int(len(in_buffer) / 2) input_buff_check = 0 # 0 = lowerhalf, 1 = upperhalf 2. Then I wait to have the in_buffer lower-half loaded (= 4000 samples of data) before proceeding further: input_status, input_transfer_status = ai_device.get_scan_status() while (input_transfer_status.current_index < input_buffer_mid_point): input_status, input_transfer_status = ai_device.get_scan_status() first_start = True to_play = None 3. Then I use current_index to determine in which half of the buffer the driver is working on (at first start, given the above lines, it's in the upper half so I'm going to Process the above 4000 samples) input_status, input_transfer_status = ai_device.get_scan_status() if input_transfer_status.current_index > input_buffer_mid_point: if input_buff_check == 0: input_buff_check = 1 to_play = Processa(in_buffer[:input_buffer_mid_point]) else: if input_buff_check == 1: input_buff_check = 0 to_play = Processa(in_buffer[input_buffer_mid_point:]) 4. Now I have 4000 samples to play and I do it with the following lines (please note that I first preload out_buffer with my 4000 samples and THEN I start a_out_scan for the first time) if to_play: output_status, output_transfer_status = ao_device.get_scan_status() if output_transfer_status.current_index > output_buffer_mid_point or first_start: out_buffer[:output_buffer_mid_point] = to_play if first_start: actual_output_rate = ao_device.a_out_scan(output_low_channel, output_high_channel, voltage_range, output_samples_per_channel, output_sample_rate, output_scan_options, output_scan_flags, out_buffer) first_start = False else: out_buffer[output_buffer_mid_point:] = to_play to_play = None 5. Main loop now goes back at point 3. If you run the above code by changing input and output samples_per_channel to, let's say, 2 * 100000, you correctly see 1 second of "silence" in the start of the second file (this is expected since I have to wait 1 second to have something to play thus my output will play 1 s later). 2 * 50000 -> half second later, ... BUT when I go lower I hit the limit of 400ms. Am I doing something wrong or I'm I hitting some hardware limit (MCC, Linux(Raspberry PI), Python, ...) ?
  2. I've already taken this into account: if you look at my original code I start a_out_scan the first time only after I have the first half of the input buffer AND already copied it in the first half of the output buffer. The initial delay is related to the input buffer dimension, that is, the play will start only after half the input buffer is collected ( so, the lower the buffer dimension the shortest delay) BUT I cannot go lower than 400ms. WHY ?
  3. Just tried your solution with the following modifications on my code (and shorting together TMR0 ICLKI OCLKI): input_scan_options = ScanOption.CONTINUOUS | ScanOption.EXTCLOCK output_scan_options = ScanOption.CONTINUOUS | ScanOption.EXTCLOCK timer_number = 0 frequency = 100000.0 # Hz duty_cycle = 0.5 # 50 percent pulse_count = 0 # Continuous initial_delay = 0.0 idle_state = TmrIdleState.LOW tmr_options = PulseOutOption.DEFAULT tmr_device = None tmr_device = daq_device.get_tmr_device() actual_input_rate = ai_device.a_in_scan(input_low_channel, input_high_channel, input_mode, ranges[input_voltage_range_index], input_samples_per_channel, input_sample_rate, input_scan_options, input_flags, in_buffer) actual_output_rate = ao_device.a_out_scan(output_low_channel, output_high_channel, voltage_range, output_samples_per_channel, output_sample_rate, output_scan_options, output_scan_flags, out_buffer) (frequency, duty_cycle, initial_delay) = tmr_device.pulse_out_start(timer_number, frequency, duty_cycle, pulse_count, initial_delay, idle_state, tmr_options) Everything is working (input is sampled at 100000 Hz and played at 100000 Hz.) BUT the 400 ms delay is still there: as you can see from the following image (input signal VS the output signal) it shows itself as a 400ms of "silence" followed by the exact replica of the input signal (obviously with a 400 ms delay) Where I'm doing wrong ?
  4. Hello, we have a MCC 1808X and we want to test it as an "echo repeater" that is everything that we read on ANALOG_IN_0 should be played as soon as possible on ANALOG_OUT_0. Our problem is that the signal on ANALOG_OUT_0 is always delayed of 400ms. As a test we used the attached Python code where we also record ANALOG_IN_0 input on file_1.bin and ANALOG_IN_1 on file_2.bin so that if you wire ANALOG_OUT_0 to ANALOG_IN_1 you can see the problem. How can we fix it ? Thanx #!/usr/bin/env python # -*- coding: UTF-8 -*- import time, datetime, serial, socket, struct, sys from uldaq import get_daq_device_inventory, DaqDevice, AInScanFlag, AOutScanFlag, ScanStatus, ScanOption, create_float_buffer, InterfaceType, AiInputMode def main(): f1 = open("file_1.bin", "wb") f2 = open("file_2.bin", "wb") # ==== MCC GENERAL SETUP ==== interface_type = InterfaceType.USB descriptor_index = 0 INPUT_SAMPLE_RATE = 100000 input_low_channel = 0 input_high_channel = 7 input_voltage_range_index = 0 input_scan_options = ScanOption.CONTINUOUS input_flags = AInScanFlag.DEFAULT input_status = ScanStatus.IDLE OUTPUT_SAMPLE_RATE = 100000 output_low_channel = 0 output_high_channel = 0 output_voltage_range_index = 0 output_scan_options = ScanOption.CONTINUOUS output_scan_flags = AOutScanFlag.DEFAULT output_status = ScanStatus.IDLE daq_device = None devices = get_daq_device_inventory(interface_type) number_of_devices = len(devices) if number_of_devices == 0: raise Exception("Errore: Nessun dispositivo MCC trovato") print("Trovato(i)", number_of_devices, "dispositivo(i) MCC:") for i in range(number_of_devices): print(" ", devices[i].product_name, " (", devices[i].unique_id, ")", sep = "") daq_device = DaqDevice(devices[descriptor_index]) ai_device = None ai_device = daq_device.get_ai_device() if ai_device is None: raise Exception("Errore: Il dispositivo non supporta un input analogico") ai_info = ai_device.get_info() if not ai_info.has_pacer(): raise Exception("\nErrore: Il dispositivo non supporta un input analogico hardware-paced") ao_device = None ao_device = daq_device.get_ao_device() if ao_device is None: raise RuntimeError("Errore: Il dispositivo non supporta un output analogico") ao_info = ao_device.get_info() if not ao_info.has_pacer(): raise RuntimeError("\nErrore: Il dispositivo non supporta un output analogico hardware-paced") descriptor = daq_device.get_descriptor() print("\nSto connettendo", descriptor.dev_string, "- attendere...") daq_device.connect() # ==== MCC INPUT SETUP ==== input_mode = AiInputMode.SINGLE_ENDED # input_mode = AiInputMode.DIFFERENTIAL ranges = ai_info.get_ranges(input_mode) if input_voltage_range_index >= len(ranges): input_voltage_range_index = len(ranges) - 1 print("\n", descriptor.dev_string, " INPUT pronto", sep = "") print(" Canali:", input_low_channel, "-", input_high_channel) print(" Modalità input:", input_mode.name) print(" Range:", ranges[input_voltage_range_index].name) print(" Sample rate:", INPUT_SAMPLE_RATE, "Hz") options = [] if input_scan_options == ScanOption.DEFAULTIO: options.append(ScanOption.DEFAULTIO.name) for so in ScanOption: if so & input_scan_options: options.append(so.name) print(" Opzioni di scan:", ", ".join(options)) # ==== MCC OUTPUT SETUP ==== chan_string = str(output_low_channel) num_channels = output_high_channel - output_low_channel + 1 if num_channels > 1: chan_string = " ".join((chan_string, "-", str(output_high_channel))) voltage_ranges = ao_info.get_ranges() if output_voltage_range_index < 0: output_voltage_range_index = 0 elif output_voltage_range_index >= len(voltage_ranges): output_voltage_range_index = len(voltage_ranges) - 1 voltage_range = ao_info.get_ranges()[output_voltage_range_index] print("\n", descriptor.dev_string, " OUTPUT pronto", sep = "") print(" Canali:", chan_string) print(" Range:", voltage_range.name) print(" Sample rate:", OUTPUT_SAMPLE_RATE, "Hz") options = [] if input_scan_options == ScanOption.DEFAULTIO: options.append(ScanOption.DEFAULTIO.name) for so in ScanOption: if so & input_scan_options: options.append(so.name) print(" Opzioni di scan:", ", ".join(options)) def Processa(data_buffer): ch_1 = data_buffer[0::8] f1.write(struct.pack("<%if" % len(ch_1), *ch_1)) ch_2 = data_buffer[1::8] f2.write(struct.pack("<%if" % len(ch_2), *ch_2)) return ch_1 try: started = None while(True): # MAIN LOOP if not started == 1: print("running, ctrl+c to stop...") started = 1 output_sample_rate = OUTPUT_SAMPLE_RATE output_samples_per_channel = 2 * 4000 out_buffer = create_float_buffer(output_high_channel - output_low_channel + 1, output_samples_per_channel) output_buffer_mid_point = int(len(out_buffer) / 2) input_sample_rate = INPUT_SAMPLE_RATE input_samples_per_channel = 2 * 4000 in_buffer = create_float_buffer(input_high_channel - input_low_channel + 1, input_samples_per_channel) input_buffer_mid_point = int(len(in_buffer) / 2) input_buff_check = 0 # 0 = lowerhalf, 1 = upperhalf actual_input_rate = ai_device.a_in_scan(input_low_channel, input_high_channel, input_mode, ranges[input_voltage_range_index], input_samples_per_channel, input_sample_rate, input_scan_options, input_flags, in_buffer) input_status, input_transfer_status = ai_device.get_scan_status() while (input_transfer_status.current_index < input_buffer_mid_point): input_status, input_transfer_status = ai_device.get_scan_status() first_start = True to_play = None input_status, input_transfer_status = ai_device.get_scan_status() if input_transfer_status.current_index > input_buffer_mid_point: if input_buff_check == 0: input_buff_check = 1 to_play = Processa(in_buffer[:input_buffer_mid_point]) else: if input_buff_check == 1: input_buff_check = 0 to_play = Processa(in_buffer[input_buffer_mid_point:]) if to_play: output_status, output_transfer_status = ao_device.get_scan_status() if output_transfer_status.current_index > output_buffer_mid_point or first_start: out_buffer[:output_buffer_mid_point] = to_play if first_start: actual_output_rate = ao_device.a_out_scan(output_low_channel, output_high_channel, voltage_range, output_samples_per_channel, output_sample_rate, output_scan_options, output_scan_flags, out_buffer) first_start = False else: out_buffer[output_buffer_mid_point:] = to_play to_play = None except KeyboardInterrupt: pass if __name__ == "__main__": main()
×
×
  • Create New...