Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Timed and persistent analog output

Hi guys,

 

I am trying to control a Piezo stage through Daqmx and C# (not necessarily measurement studio). The stage is very sensitive to sudden, big voltage stations. Therefore all movements of the stage have to be incremental and should be done slow enough (to prevent hysteresis of the piezo.

 

For this reason I created a program with a class that uses:

 

1) 2 private member Daqmx AO tasks (one for every movement axis).

2) two global doubles that store whatever voltage value was last sent out using the above tasks.

3) A method to do actual writes on both tasks.

 

The defenition of the AO tasks is as follows:

 

Constructor()

  // Setup an Analog Out task to move the Piezo stage along X.
  // Commit the task and start it here to make iterative acces significantly faster, response will be virtually instantaneous.
  m_daqtskMoveStageX = new Task();
  m_daqtskMoveStageX.AOChannels.CreateVoltageChannel("/Dev1/ao0", "aoChannelX", m_dVoltageMin, m_dVoltageMax, AOVoltageUnits.Volts);
  m_daqtskMoveStageX.Control(TaskAction.Commit);

}

 

This way, the tasks are created when the program starts.

 

Next, there is the method for writing to the task:

 

void MoveStage1D(Task _daqtskCurrentAxis, double _dblVoltageStart, double _dblVoltageStop, int _intSteps)
        {
            try
            {
                int _intI;
                double _dblVoltageStep;
                double[] _dblVoltage = new double[_intSteps];

                // Moving the piezo will happen in a hardware timed manner.
                _daqtskCurrentAxis.Timing.MasterTimebaseSource = "/Dev1/20MHzTimebase";
               
                _daqtskCurrentAxis.Timing.ConfigureSampleClock("/Dev1/MasterTimeBase", 1000, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, _intSteps);
                // _daqtskCurrentAxis.Timing.ReferenceClockSource = "/Dev1/20MHzTimebase";
                // Create a channel writer object to write the actual voltage values.
                AnalogSingleChannelWriter _achanwriWriter = new AnalogSingleChannelWriter(_daqtskCurrentAxis.Stream);

                // Determine the voltage step unit.
                _dblVoltageStep = (_dblVoltageStop - _dblVoltageStart) / _intSteps;

                // Populate an array with the values to write.
                for (_intI = 0; _intI < _intSteps; _intI++)
                {
                    _dblVoltage[_intI] = _dblVoltageStart + _dblVoltageStep * _intI;
                   
                }

                // Write the freshly generated array of voltages in a timed way.
                _achanwriWriter.WriteMultiSample(false, _dblVoltage);

                // Start the task.
                _daqtskCurrentAxis.Start();
                _daqtskCurrentAxis.WaitUntilDone();

            }

            catch (DaqException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

 

Where I pass the task for the axis I want to move, the beginning voltage is always the value of the global voltage variables, the target voltage. The number of steps for each move can be variable of course.

 

The reason I do it like this is to prevent having to stop the task each time (because the voltage on the channel would jump to 0 probably).

 

Everything works when I try it for one task (call MoveStage1D once only) but if I do this (call it multiple times in a row);

 

 MoveStage1D(m_daqtskMoveStageX, m_dVoltageXCurrent, _dVoltageXMin, 20000);
 MoveStage1D(m_daqtskMoveStageY, m_dVoltageYCurrent, _dVoltageYMin, 20000);

 

I get "Specified resource is reserved" Code = -50103 errors. Probably because the timebase resource cannot be shared or something.

 

However, I don't see how I could solve this. Who could help me out or provide a better way of doing things (PCI 6731 Board is used)?

 

Also, is there anybody who could offer me a way to create a hardware timed loop using my PCI 6602 board? I am desperately looking for a way to do this, but again, I don't have enough experience with the API to see a solution.

 

Regards,

 

Kris J.

0 Kudos
Message 1 of 5
(3,202 Views)

I did some more looking around online and I was wondering:

 

// Setup an Analog Out task to move the Piezo stage along X.
            // Commit the task and start it here to make iterative acces significantly faster, response will be virtually instantaneous.
            m_daqtskMoveStageX = new Task();
            m_daqtskMoveStageX.AOChannels.CreateVoltageChannel("/Dev1/ao0", "aoChannelX", m_dVoltageMin, m_dVoltageMax, AOVoltageUnits.Volts);
          
            m_daqtskMoveStageX.Timing.
            m_daqtskMoveStageX.Timing.ConfigureSampleClock("", 1000, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
            m_daqtskMoveStageX.Start();

 

If you use ConfigureSampleClock in this way will it cause all other AO channels on the card to use the same SampleClock settings (which would probably be the solution for my problem)?

 

I got this idea from http://www.ni.com/pdf/manuals/370735e.pdf where the following is mentioned:

 

"There is one AO Sample Clock that causes all AO channels to update
simultaneously.
"

 

Am I correct?

0 Kudos
Message 2 of 5
(3,182 Views)

Nobody?

 

I'm really lost :s

0 Kudos
Message 3 of 5
(3,170 Views)

Kris

 

Since there is only one sample clock available for the analog outputs, you cannot configure a sample clock for two AO tasks running at the same time. The best thing to do would be to combine the two outputs into one task. So you would first have a function which creates a task with ao0 and ao1, configure the sample clock for this task and start the task. Using another function you  can then write to the AO channels. Just just have to keep in mind you are writing to both channels at the same time, so if you don't want the stage to move in a certain direction, you should still send the appropriate value for this to the AO. At the end you can then use another function to clear the task.

 

I hope this helpes you on.

Message Edited by Michiel Herman on 09-18-2008 04:27 PM
Best Regards

Michiel
Applications Engineer
NI Belgium
http://www.ni.com/ask
0 Kudos
Message 4 of 5
(3,150 Views)

Thanks for the suggestion. I wasn't aware of the possibility to combine channels like this and still being able to write them more or less independently. I don't think there are any code samples in the Daqmx install that actually do this.

 

I think I figured it out... Daqmx is really powerfull, a pity the documentation isn't richer...

0 Kudos
Message 5 of 5
(3,140 Views)