Setup the memory layout of the STG 4008 using Matlab?

View previous topic View next topic Go down

Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Mon Jan 06, 2014 9:39 am

Finally, I could stream random sinusoid signals from Matlab r2011b to all 8 channels of an STG4008 by using the McsUsbNet.dll compiled in .Net.
It's working perfectly. However, I have been facing with an other open question and would like to ask for some help.

Problem description: Instead of a randomly generated sinusoid waveform (see my previous post) I would like to be able to stream the context of the linked file (https://www.dropbox.com/s/anljh67r5gkkw4a/SampleASCII.txt) using the Matlab script developed based off of my previous posting.
In order to that the context of the text file (8 channels, ~3s of stimuli on each, rectangular signal form) must be used to generate a matrix containing the signal values depending on the time resolution for each channel. According to my best knowledge, such a matrix would contain 8 rows and as much columns as the longest signal length (~3s = 3.000.000us).

Q1. The above mentioned matrix would occupy a huge amount of the physical memory. Therefore, in applications, where the usage of physical resources and time of processing are crucial, simply it's not sufficient enough. Are there any other more sufficient ways to create the signals in Matlab?
Q2. How shall I setup the memory of the STG in order to get the most efficient solution?
Q3. Is it possible to en-queue the whole signal at a time or would it be more practical to divide it up into 50.000 long pieces as it was suggested previously by using the following Matlab commands:

Code:
device1 = CStg200xStreamingNet(50000)
Code:
device1.SetOutputRate(50000);

Any help and idea would be appreciated.
Thank you,
Robert Tibold Ph.D from the University of Arizona
The Fuglevand Lab

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Wed Jan 08, 2014 10:28 pm

Dear Robert,

to answer your questions:

Q1: Could you load your ASCII Files in peaces? You only need to have the data you are about to stream to the device in memory. so maybe you could load
only some ms of data at a time and discard the data after you have streamed it to the STG?

Q2: There is no need to change the memory setup compared to your previous configuration.

Q3: The STG has an other mode, called the "Download Mode", where you download data in advance.
When you use the streaming mode as you do currently, you automaticallly divide the file into small peaces since you only enqueue as much data as you can fit into the streaming queue.

I hope these answers are of some help to you. If you have further questions, please let me kown.

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Tue Jan 14, 2014 12:44 pm

Dear Peter,

Thank you for the useful answers. They have just enforced my thinking.
I wonder whether you might know what the units are in streaming mode when a randomly generated signal is to be delivered to the stimulus generator. Are they the same as in the Multichannel II? According to this, they should be in micro amps if current mode is selected. Is my assumption correct?

Thank you,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Tue Jan 14, 2014 8:18 pm

Dear Robert,

there is a call in the DLL: GetCurrentRangeInNanoAmp and GetCurrentResolutionInNanoAmp, which returns the maximum current and the
resolution of the current, thus the amount of current which corresponds to 1 bit, respectively.

Best regards,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Wed Jan 15, 2014 6:58 am

Dear Peter,

Thank you for the answer again. However I'm afraid that's not what I'm asking. I tried the callbacks you suggested. What I got were only the default parameters (range of current 16mA, and the resolution 2000 Hz) of the STG connected to my PC that I was aware of. My question was related to the units of the input signal generated based off of the following code:
Code:
Channels = 8;
 i=0:1999;             
 for channel =1:Channels     
    inputSignal(channel,:) = 1*((300)*sin(2*i*pi/1000*(channel+1)));     
 end
In my understanding, the peak +/- amplitude for all sine waves is +/-300 with the frequency varying. What I expected is that the this value (300) was expressed in micro amps. According to my measurements in Spike2 this assumption is not correct.
Let me give you an example to this.
There were 2 cases in my measurements: (A) Using Multichannel II Software - sine wave; B) Using Matlab with sign waves (see the code above). In both cases the +/- max amplitudes were set to 300. In A) the units were given in micro amps (uA). As a result in Spike2, I was able to get 0.3 mA at the peak locations. However in B) I could not reproduce the same peak currents. Literally, what I got was exactly the half of the peak currents (+/- 0.15 mA).

Would you have any idea why this was happening?
Thank you for the answer,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Wed Jan 15, 2014 10:35 pm

Dear Robert,

the values which you send to the STG are raw DAC values, they are not in units of uA.
To get the current in uA, you can calculate the current as:

current in nA =  raw DAC value * GetCurrentResolutionInNanoAmp()

so in your case it will be

current in nA =  300 * GetCurrentResolutionInNanoAmp()

What is the configuration of your STG? Which number does the GetCurrentResolutionInNanoAmp() return?
Does this correspond to your observations?

Best regards,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Tue Jan 21, 2014 12:37 pm

Dear Peter,

Below, you can find a short summary of my observations. Sorry for the delay, I just wanted to double-check them.

The output of the GetCurrentResolutionInNanoAmp() function is 2000nA while the output of the GetCurrentRangeInNanoAmp() is 16000000nA for each individual channel. I think these are the default values since I haven't changed anything.
Based on your suggestion (current in nA = raw DAC value * GetCurrentResolutionInNanoAmp() <-> 600000 nA = 300 * 2000nA) I should be able to get +/- 0.6mA at the peaks of the sine waves.
However, instead of getting +/-0.6mA I'm only measuring +/-0.15mA at the peaks which is ~ 4 times less than it should be. Even if I calculated the absolute amplitude (the amplitude between the - and + peaks) of the sine waves it would be only ~ 0.3mA.

Best Regards,
Robert



Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Thu Jan 23, 2014 8:40 pm

Dear Robert,

Could you check with MC_Stimulus II, what it displays in its "About" Dialog about STG range and resolultion?

And could you programm a test pulse (best for both current and voltage stimulation in MC_Stimulus II and measure
if you get the correct amplitudes there?

You can not change the range and resolutio, it is factory programmed and depends on the hardware configuration.

Best wishes,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Tue Jan 28, 2014 10:35 am

Dear Peter,

Here you can find the parameters you requested.

current range = +/- 16000uA
current resolution = +/- 2uA

They are identical with the outputs provided by the GetCurrentResolutionInNanoAmp() and GetCurrentRangeInNanoAmp()  functions called in Matlab.
They are default values.

Also, I have done 2 sets of test measurements by using the Multichannel II. Results can be seen below.

Sine waves (+/-300uA at peaks)
Sine waves

Step square function (.1mA steps between 0mA-1mA)
Square function

All in all, when I'm using the default Multichannel II I'm getting the appropriate amplitudes. As soon as we want to use the Matlab script we receive 4-times less current values at the peaks (only sine waves have been used so far for testing purposes). So in the case of our example sine wave at the peaks I'm getting +/- 0.15mA instead of +/-0.6mA.

Sine waves (+/-300 DAC values at peaks)
Matlab sine waves

Don't you think we might be facing with some bugs in the dll callbacks?

Regards,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Is there any difference between STG4008 and STG2008 in terms of how the dll should be used in Matlab?

Post  Robcsy83 on Thu Jan 30, 2014 8:37 am

Hi Peter,

We have been trying to speed up our progress in terms of our research. Besides the question of the unit issues I'm trying to combine 2 different types of stimulus generators and stream data from Matlab in real-time. Basically, 3*STG4008 and 1*STG2008 would be used at the same time during the course of data streaming. In the previous topics finally we ended up having a script which was able to handle and send sine waves from Matlab to one of our STG4008.

Since we are trying to use two different versions of the STGs my intention was to expand the system in 2 steps.

1. Add another STG4008 to check whether the script is able to handle multiple stimulators.
2. Add the STG2008 to check whether there are no compatibility issues with the original script.

Evaluation of the two steps:

1. The 1st step went smoothly. After establishing the appropriate modifications, two STG4008(s) were used to stream either sine waves or square signals with a delay of 3ms.
2. The 2nd step failed in a sense that I could not see any signals coming out from the STG2008 in our monitoring system (Spike2). The other two STG4008(s), however, worked perfectly (Picture: 3STG(s) operating together). It is strange that in the case of the STG2008 the PROG LED was activated while the SWEEP LED remained dark. Therefore, this unit showed an opposing behavior compared to the others where the PROG LED remained dark while the unit was sweeping with the SWEEP LED lighted.

Let me attach the script I have been using recently. It was built up by using the original code. In order to handle how many STG(s) were connected to the PC a switch-case structure with 3 cases had been added.
I suppose, the code itself does what it should do without throwing any errors. Do you think that either the sequence or the structure of the commands used should be changed in the case of the old STG2008? According to the documentation (McsUsbNet_for_STG.chm) however, the below script should work. It seemed to me like the patters were downloaded to the STG's buffer but they were not swept out. Furthermore, in the Matlab workspace I have checked that the buffer's space was decreased (spaceAfterEnq variable) by the sample number of the inputSignal meaning all the signals were enqued.

So I'm facing with another mysterious issue.
Any ideas?

Regards,
Robert

Code:
asm = NET.addAssembly('i:\UofA\Projects\MultipleStimulators\McsUsbNetPackage\McsUsbNet.dll');
import Mcs.Usb.*;

deviceList = CMcsUsbListNet();
deviceList.Initialize(DeviceEnumNet.MCS_STG_DEVICE);
number_devices_connected = deviceList.GetNumberOfDevices();
SerialNumber = cell(number_devices_connected,1);

fprintf('Found %d STGs\n', number_devices_connected);

for i=1:number_devices_connected
    SerialNumber{i,1} = char(deviceList.GetUsbListEntry(i-1).SerialNumber);
    fprintf('Serial Number: %s\n', SerialNumber{i,1});  
end

 %% Signal generation
 Channels = 8;
 i=0:1999;              
 for channel =1:Channels            
     inputSignal(channel,:) = 1*((300)*sin(2*i*pi/1000*(channel+1)));      
 end
 [row(1) col(1)]=size(inputSignal); % col = number of samples on a single channel
 
 ii=0:14999;              
 for channel =1:Channels            
     inputSignal_2(channel,:) = 1*((2000)*sin(2*ii*pi/1000*(channel+1)));      
 end
 [row(2) col(2)]=size(inputSignal_2); % col = number of samples on a single channel
 
 sqrSignal = [zeros(1,80) zeros(1,400)+250 zeros(1,80) zeros(1,400)+500 zeros(1,80) zeros(1,400)+1000 zeros(1,80) zeros(1,400)+2000 zeros(1,80)];
 
 iii = 4;
 for channel =1:Channels            
     inputSignal_3(channel,:) = iii.*sqrSignal;
     iii = iii-.5;
 end
 [row(3) col(3)]=size(inputSignal_3); % col = number of samples on a single channel
 
 %%

switch number_devices_connected
    case 1
        
        
        % 1st device
        ID = 1;
        device1 = CStg200xStreamingNet(50000);
        
        device1.Connect(deviceList.GetUsbListEntry(ID-1));
        device1.EnableContinousMode();
        device1.SetOutputRate(50000);
        ntrigger(ID) = device1.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device1.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_1=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_1=uint32(zeros(1,ntrigger(ID)));
        digoutmap_1=uint32(zeros(1,ntrigger(ID)));
        autostart_1=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_1=uint32(zeros(1,ntrigger(ID)));

        channelmap_1(1)=255; % assign all channels to trigger 1
        callbackThreshold_1(1)=50;

        device1.SetupTrigger(NET.convertArray(channelmap_1,'System.UInt32'),NET.convertArray(syncoutmap_1,'System.UInt32'),NET.convertArray(digoutmap_1,'System.UInt32'),NET.convertArray(autostart_1,'System.UInt32'),NET.convertArray(callbackThreshold_1,'System.UInt32'));
        

        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device1.SetCurrentMode();                                      
            end
        end                        
        
        %% Start looping depending on free space in the buffer
        device1.StartLoop();
        device1.SendStart(uint32(1));        
          
        loop = 1;
        for channel = 1:Channels
            %% 1st device
            space_1(channel)=device1.GetDataQueueSpace(channel-1);
            currentRange(channel)=device1.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution(channel)=device1.GetCurrentResolutionInNanoAmp(channel-1);
                      
            data2channels_1 = NET.convertArray(inputSignal_3(channel,:),'System.Int16');
                          
            enqued_1(channel,:) = device1.EnqueueData(channel-1,data2channels_1);
            spaceAfterEnq_1(channel,loop) = device1.GetDataQueueSpace(channel-1);      
        end                
        %%
  
        

    case 2
        %%
        % 1st device        
        ID = 1;
        device1 = CStg200xStreamingNet(50000);        

        device1.Connect(deviceList.GetUsbListEntry(ID-1));
        device1.EnableContinousMode();
        device1.SetOutputRate(50000);
        ntrigger(ID) = device1.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device1.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_1=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_1=uint32(zeros(1,ntrigger(ID)));
        digoutmap_1=uint32(zeros(1,ntrigger(ID)));
        autostart_1=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_1=uint32(zeros(1,ntrigger(ID)));

        channelmap_1(1)=255; % assign all channels to trigger 1
        callbackThreshold_1(1)=50;

        device1.SetupTrigger(NET.convertArray(channelmap_1,'System.UInt32'),NET.convertArray(syncoutmap_1,'System.UInt32'),NET.convertArray(digoutmap_1,'System.UInt32'),NET.convertArray(autostart_1,'System.UInt32'),NET.convertArray(callbackThreshold_1,'System.UInt32'));
        
        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device1.SetCurrentMode();                                      
            end
        end
        %%
        
        %%
        % 2nd device
        ID = 2;
        device2 = CStg200xStreamingNet(50000);        

        device2.Connect(deviceList.GetUsbListEntry(ID-1));
        device2.EnableContinousMode();
        device2.SetOutputRate(50000);
        ntrigger(ID) = device2.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device2.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_2=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_2=uint32(zeros(1,ntrigger(ID)));
        digoutmap_2=uint32(zeros(1,ntrigger(ID)));
        autostart_2=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_2=uint32(zeros(1,ntrigger(ID)));


        channelmap_2(1)=255; % assign all channels to trigger 1
        callbackThreshold_2(1)=50;

        device2.SetupTrigger(NET.convertArray(channelmap_2,'System.UInt32'),NET.convertArray(syncoutmap_2,'System.UInt32'),NET.convertArray(digoutmap_2,'System.UInt32'),NET.convertArray(autostart_2,'System.UInt32'),NET.convertArray(callbackThreshold_2,'System.UInt32'));
        
        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device2.SetCurrentMode();                                      
            end
        end
        %%
        
         %% Start looping depending on free space in the buffer
        device1.StartLoop();        
        device1.SendStart(uint32(1));  
        
        device2.StartLoop();
        device2.SendStart(uint32(1));        
          
        loop = 1;
        for channel = 1:Channels            
                        
            %% 1st device
            space_1(channel)=device1.GetDataQueueSpace(channel-1);
            currentRange_1(channel)=device1.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution_1(channel)=device1.GetCurrentResolutionInNanoAmp(channel-1);
            
            data2channels_1 = NET.convertArray(inputSignal_3(channel,:),'System.Int16');
                          
            enqued_1(channel,:) = device1.EnqueueData(channel-1,data2channels_1);
            spaceAfterEnq_1(channel,loop) = device1.GetDataQueueSpace(channel-1);                
            
            %% 2nd device
            space_2(channel)=device2.GetDataQueueSpace(channel-1);
            currentRange_2(channel)=device2.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution_2(channel)=device2.GetCurrentResolutionInNanoAmp(channel-1);
            
            data2channels_2 = NET.convertArray(inputSignal_2(channel,:),'System.Int16');
                          
            enqued_2(channel,:) = device2.EnqueueData(channel-1,data2channels_2);
            spaceAfterEnq_2(channel,loop) = device2.GetDataQueueSpace(channel-1);      
        end
        
        
    case 3
        %%
        % 1st device        
        ID = 1;
        device1 = CStg200xStreamingNet(50000);        

        device1.Connect(deviceList.GetUsbListEntry(ID-1));
        device1.EnableContinousMode();
        device1.SetOutputRate(50000);
        ntrigger(ID) = device1.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device1.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_1=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_1=uint32(zeros(1,ntrigger(ID)));
        digoutmap_1=uint32(zeros(1,ntrigger(ID)));
        autostart_1=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_1=uint32(zeros(1,ntrigger(ID)));

        channelmap_1(1)=255; % assign all channels to trigger 1
        callbackThreshold_1(1)=50;

        device1.SetupTrigger(NET.convertArray(channelmap_1,'System.UInt32'),NET.convertArray(syncoutmap_1,'System.UInt32'),NET.convertArray(digoutmap_1,'System.UInt32'),NET.convertArray(autostart_1,'System.UInt32'),NET.convertArray(callbackThreshold_1,'System.UInt32'));
        
        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device1.SetCurrentMode();                                      
            end
        end
        %%
        
        %%
        % 2nd device
        ID = 2;
        device2 = CStg200xStreamingNet(50000);        

        device2.Connect(deviceList.GetUsbListEntry(ID-1));
        device2.EnableContinousMode();
        device2.SetOutputRate(50000);
        ntrigger(ID) = device2.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device2.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_2=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_2=uint32(zeros(1,ntrigger(ID)));
        digoutmap_2=uint32(zeros(1,ntrigger(ID)));
        autostart_2=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_2=uint32(zeros(1,ntrigger(ID)));


        channelmap_2(1)=255; % assign all channels to trigger 1
        callbackThreshold_2(1)=50;

        device2.SetupTrigger(NET.convertArray(channelmap_2,'System.UInt32'),NET.convertArray(syncoutmap_2,'System.UInt32'),NET.convertArray(digoutmap_2,'System.UInt32'),NET.convertArray(autostart_2,'System.UInt32'),NET.convertArray(callbackThreshold_2,'System.UInt32'));
        
        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device2.SetCurrentMode();                                      
            end
        end
        %%
        
        %%
        % 3rd device
        ID = 3;
        device3 = CStg200xStreamingNet(50000);        

        device3.Connect(deviceList.GetUsbListEntry(ID-1));
        device3.EnableContinousMode();
        device3.SetOutputRate(50000);
        ntrigger(ID) = device3.GetNumberOfTriggerInputs();
        TotalMemory(ID) = device3.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{ID,1}) ' is: ' num2str(ntrigger(ID)) '\n']);
            
        channelmap_3=uint32(zeros(1,ntrigger(ID)));
        syncoutmap_3=uint32(zeros(1,ntrigger(ID)));
        digoutmap_3=uint32(zeros(1,ntrigger(ID)));
        autostart_3=uint32(zeros(1,ntrigger(ID)));
        callbackThreshold_3=uint32(zeros(1,ntrigger(ID)));

        channelmap_3(1)=255; % assign all channels to trigger 1
        callbackThreshold_3(1)=50;

          device3.SetupTrigger(NET.convertArray(channelmap_3,'System.UInt32'),NET.convertArray(syncoutmap_3,'System.UInt32'),NET.convertArray(digoutmap_3,'System.UInt32'),NET.convertArray(autostart_3,'System.UInt32'),NET.convertArray(callbackThreshold_3,'System.UInt32'));
        
        for k = 1:number_devices_connected                
            if ~strcmp(SerialNumber(k,1),'9027-0077')
                device3.SetCurrentMode();                                      
            end
        end
        %%
        
         %% Start looping depending on free space in the buffer
        device1.StartLoop();        
        device1.SendStart(uint32(1));  
        
        device2.StartLoop();
        device2.SendStart(uint32(1));        
        
        device3.StartLoop();
        device3.SendStart(uint32(1));        
          
        loop = 1;
        for channel = 1:Channels            
                        
            %% 1st device
            space_1(channel)=device1.GetDataQueueSpace(channel-1);
            currentRange_1(channel)=device1.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution_1(channel)=device1.GetCurrentResolutionInNanoAmp(channel-1);
            
            data2channels_1 = NET.convertArray(inputSignal_3(channel,:),'System.Int16');
                          
            enqued_1(channel,:) = device1.EnqueueData(channel-1,data2channels_1);
            spaceAfterEnq_1(channel,loop) = device1.GetDataQueueSpace(channel-1);                
            
            %% 2nd device
            space_2(channel)=device2.GetDataQueueSpace(channel-1);
            currentRange_2(channel)=device2.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution_2(channel)=device2.GetCurrentResolutionInNanoAmp(channel-1);
            
            data2channels_2 = NET.convertArray(inputSignal_2(channel,:),'System.Int16');
                          
            enqued_2(channel,:) = device2.EnqueueData(channel-1,data2channels_2);
            spaceAfterEnq_2(channel,loop) = device2.GetDataQueueSpace(channel-1);      
            
            %% 3rd device
            space_3(channel)=device3.GetDataQueueSpace(channel-1);
            currentRange_3(channel)=device3.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution_3(channel)=device3.GetCurrentResolutionInNanoAmp(channel-1);
            
            data2channels_3 = NET.convertArray(inputSignal(channel,:),'System.Int16');
                          
            enqued_3(channel,:) = device3.EnqueueData(channel-1,data2channels_3);
            spaceAfterEnq_3(channel,loop) = device3.GetDataQueueSpace(channel-1);      
        end                      
        
    otherwise
        disp('System is not ready to connect to more than 3 devices');
end

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Thu Jan 30, 2014 8:57 pm

Dear Robert,

looking at your script, the first thing I would try is to swap the SendStart and the EnqueueData commands,
so first enqueue some data to the device before using the SendStart command.

Can you check if that makes some difference?

Can you start the streaming on the STG200x when you press the front panel button after you startet your script?

Best regards,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Fri Jan 31, 2014 8:27 am

Dear Peter,

Peter MCS wrote:
the first thing I would try is to swap the SendStart and the EnqueueData commands, so first enqueue some data to the device before using the SendStart command.
Can you check if that makes some difference?

Good point. I had the same idea before posting my previous observations.
1. I put only the SendStart command after the for loop (data queuing).
2. I put both the StartLoop and SendStart commands after the for loop.
Result: neither of them worked.

Peter MCS wrote:
Can you start the streaming on the STG200x when you press the front panel button after you startet your script?
Good idea but I couldn't start sweeping.

Another observation:
I tried to stay on the direction why the hack I couldn't sweep after data queuing.
I realized that the PROG LED is not signing arrival of the samples but rather the successful execution of the Connect function. As soon as the Connect function has been called without an error the PROG LED will come on. After this if you executed the Disconnect function the led comes off.
Because I can see decrements in free space depending on the number of loops after each call of the EnqueueData function I think the issue might be due to either the malfunctioning of the StartLoop or the SendStart.

Is it possible that somehow they are not applicable in their current definition with the STG2008?

Regards,
Robert


Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Wed Feb 05, 2014 9:38 am

Dear Peter,

Could you figure out something on the issues we have been currently facing?

1) We are not able to sweep signals in the case of the STG2008. There is no issue with 3 STG4008(s). Sweeping is done correctly with a small amount of delay.
2) We are not getting appropriate current values on the outputs. Unfortunately, we are recording 4 times less current values then compared to what we should get by using the equation you referenced.

Thank you.
Regards,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Thu Feb 06, 2014 2:09 am

Dear Robert,

regarding the STG2008 question: Does the streaming work with our C# example project?

regarding the output current: Could you try to use MC_Stimulus II to program a stimuls pattern and see if you get correct output amplitudes with that program?

Both will help to see if the problem is hardware or software related.

Best wishes,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Thu Feb 06, 2014 2:36 pm

Dear Peter,
Thank you for the quick answer!

Peter MCS wrote:
regarding the STG2008 question: Does the streaming work with our C# example project?
I have already tested it. It's working. Therefore, I have started to compare the Matlab script (working with 3 STG4008) with the C# code. Basically, they are doing the same things. There are 2 differences, however:

1) in Matlab when the device object is created I'm not allowed to use the DataHandler and the ErrorHandler function defined in the C# code.
2) since I'm using the default settings the SetupMemory function is not called.

Can this be a Matlab related issue originating from how Matlab handles the .Net dll or there might be something else in form of a hidden bug in one of the functions linked in the dll? I can't imagine anything else.

Peter MCS wrote:
regarding the output current: Could you try to use MC_Stimulus II to program a stimuls pattern and see if you get correct output amplitudes with that program?
I have done this several times. The answer is yes, I'm getting the appropriate currents.

I keep debugging the Matlab script. I'm open to any other ideas.
The STG2008 issue would be much more important then the other one since we know we are down by a constant of 4. Therefore, having the DAC values multiplied by 4 we can get the necessary amplitudes.

Waiting for your response!

Regards,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Fri Feb 07, 2014 3:15 am

Dear Robert,

regarding your STG2008 issue: it must be the missing SetupMemory function. I think the STG2008 has no default memory setup when switched to
streaming mode, so please try to add that function and see if that fixes your problem.

regarding the amplitude issue: is the error exactly a factor of 4? What does MC_Stimulus show in in the about dialog as analog Range and Resolution?
Is it the same values you get as the DLL function?

Best regards,

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Fri Feb 07, 2014 9:09 am

Dear Peter,

Yesterday, I added the SetupMemory function to the Matlab script before receiving your reply because I had the same idea about the memory configuration of the STG2008.
The funny thing is that the modified code is working with the STG4008 but in the case of the STG2008 sweeping is still not executed. It is strange though that according to the GetDataQueueSpace function the signals are conveyed to the memory. All in all, after adding the SetupMemory() and still not being able to sweep despite the memory contains the signals, I'm almost 100% sure that the issue is due to either the SendStart function or to the StartLoop function when the Matlab interface for C# tries to call one or the other.

What I don't know why the hack it works in C# and it doesn't in Matlab?
Independently from which environment (Matlab or C#) is used, the handling of the USB 1.1 interface on the STG2008 should not be an issue. Is this correct? I have forgotten to mention that I have been using a 64bit version of Windows7 and a 32bit Matlab r2011b.

Here is the modified code for only 1 device attached:
Code:

asm = NET.addAssembly('i:\UofA\Projects\MultipleStimulators\McsUsbNetPackage\McsUsbNet.dll');
import Mcs.Usb.*;

deviceList = CMcsUsbListNet();
deviceList.Initialize(DeviceEnumNet.MCS_STG_DEVICE);
number_devices_connected = deviceList.GetNumberOfDevices();
SerialNumber = cell(number_devices_connected,1);

fprintf('Found %d STGs\n', number_devices_connected);

for i=1:number_devices_connected
    SerialNumber{i,1} = char(deviceList.GetUsbListEntry(i-1).SerialNumber);
    fprintf('Serial Number: %s\n', SerialNumber{i,1});  
end

 %% Signal generation
 Channels = 8;
 i=0:1999;                            
 for channel =1:Channels            
     inputSignal(channel,:) = 1*((2000)*sin(2*i*pi/1000*(channel+1)));      
 end
 [row col]=size(inputSignal); % col = number of samples on a single channel [2000]
 %%

switch number_devices_connected
    case 1        
        
        % 1st device        
        device1 = CStg200xStreamingNet(50000);
        
        device1.Connect(deviceList.GetUsbListEntry(0));
        device1.EnableContinousMode();
        device1.SetOutputRate(50000);
        device1.SetCurrentMode();
        ntrigger(number_devices_connected) = device1.GetNumberOfTriggerInputs();
        TotalMemory(number_devices_connected) = device1.GetTotalMemory();
        fprintf(['Number of Triggers for ' num2str(SerialNumber{1,1}) ' is: ' num2str(ntrigger(1)) '\n']);
            
        stg_triggercapacity = uint32(50000*ones(1,ntrigger(number_devices_connected))); % [50000,50000,50000,50000]
        device1.SetCapacity(NET.convertArray(stg_triggercapacity,'System.UInt32'));          
                
        channelmap=uint32(zeros(1,ntrigger(number_devices_connected)));
        syncoutmap=uint32(zeros(1,ntrigger(number_devices_connected)));
        digoutmap=uint32(zeros(1,ntrigger(number_devices_connected)));
        autostart=uint32(zeros(1,ntrigger(number_devices_connected)));
        callbackThreshold=uint32(zeros(1,ntrigger(number_devices_connected)));


        channelmap(1)=255; % assign all channels to trigger 1
        callbackThreshold(1)=50;

        device1.SetupTrigger(NET.convertArray(channelmap,'System.UInt32'),NET.convertArray(syncoutmap,'System.UInt32'),NET.convertArray(digoutmap,'System.UInt32'),NET.convertArray(autostart,'System.UInt32'),NET.convertArray(callbackThreshold,'System.UInt32'));            
                        
        
        %% Start looping depending on free space in the buffer
        %device1.StartLoop();
        %device1.SendStart(uint32(1));      
          
        loop = 1;
        for channel = 1:Channels            
            
            space(channel)=device1.GetDataQueueSpace(channel-1); %[49999,49999,49999,49999,49999,49999,49999,49999]
            currentRange(channel)=device1.GetCurrentRangeInNanoAmp(channel-1);
            currentResolution(channel)=device1.GetCurrentResolutionInNanoAmp(channel-1);
                        
            data2channels = NET.convertArray(inputSignal(channel,:),'System.Int16');
            enqued(channel,:) = device1.EnqueueData(channel-1,data2channels);
            spaceAfterEnq(channel,loop) = device1.GetDataQueueSpace(channel-1); %[47999,47999,47999,47999,47999,47999,47999,47999]                                          
                
        end  
        device1.StartLoop();
        device1.SendStart(uint32(1));

Regards,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Peter MCS on Sun Feb 09, 2014 8:59 pm

Dear Robert,

Could you try to run your Matlab example after you have successfully used the C# example?
Does it work than?

Peter

Peter MCS

Posts : 16
Join date : 2011-10-04

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Robcsy83 on Wed Feb 19, 2014 11:28 am

Dear Peter,

No change.
But I realized something. When we had the very first issue you uploaded a zip file, to one of your servers, with the following name (Arizona_20130514). I tried to execute the C# example by referencing the dll included by that zip file. Surprisingly, the same thing happened then in the case of out Matlab script. Only, the PROG LED came on on the STG2008 and it could not sweep out the signals.

Best,
Robert

Robcsy83

Posts : 21
Join date : 2013-05-20

View user profile

Back to top Go down

Re: Setup the memory layout of the STG 4008 using Matlab?

Post  Sponsored content


Sponsored content


Back to top Go down

View previous topic View next topic Back to top


 
Permissions in this forum:
You cannot reply to topics in this forum