0

I just wrote a simple C# to get an eventcallback from PCI-7250 (Data Acquisition Card) when any of the digital inputs go high. Here is my code:

public delegate void ReadDelegate(uint value)
public void Form1_Load(object sender, EventArgs e)
 { 
    m_dev = DASK.Register_Card(DASK.PCI_7250,0);

    ReadDelegate ReadNow = new ReadDelegate(FunctionToCall) 
    DASK.DI_EventCallBack((ushort)m_dev,1,(short)DASK.DBEvent,ReadNow) 
} 
private void FunctionToCall(uint int_value) 
{
 MessageBox.Show(int_value) 
}

When run it just keep"s up throwing some random numbers during runtime and then finally crashes. I believe it has something to do with the EventType (DASK.DBEvent). I went through the manual but nothing more is mentioned about the DASK.DBEvent.

Kindly please advise.

user726720
  • 1,127
  • 7
  • 25
  • 59
  • I received an update from the ADLINK support team that unfortunately, PCI-7250 doesn't support any callbacks or Interrupts. I was trying to use callbacks above, no wonder why it wasn't working properly. Anyway, does anyone else have a workaround for this, by using some other technnique to trigger the read. – user726720 Nov 28 '14 at 05:15
  • Which function reference do you use? I found only one for c++ (Date 2009) and in this one the PCI-7250 is not listed under supported cards for the DI_EventCallBack-Method. – AquilaRapax Dec 18 '14 at 07:46
  • @AquilaRapax: As in my post above Adlink support team has verified that PCI-7250 doesn't support an callback's or interrupts. – user726720 Dec 23 '14 at 05:24

1 Answers1

0

Since the device doesn't have support for callbacks in its driver, you could adapt the driver's API from synchronous calls to callbacks by polling the device in a background thread.

First, create a class that polls the device for the physical event you're interested in responding to. Then, in your GUI code, put the polling work in the background and respond to the callback in the main thread.

I'm not familiar with the ADLink driver, so I'll just summarize a design approach and sketch some pseudocode that isn't threadsafe. This is a naive approach to using Tasks, but you could also update it to use continuations or async/await. Or, if you need more than one responder, make the callback raise an event that your other classes can subscribe to.

Polling class

public class EdgeDetector
{
  public delegate void OnRisingEdgeDetected(uint currentValue, uint linesThatAsserted);
  private bool m_shouldPoll;

  private void PollForRisingEdge(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
    while (m_shouldPoll)
    {
      // Optional: sleep to avoid consuming CPU

      uint newPortValue = device.ReadAllDigitalLines();
      uint changedLines = m_currentPortValue ^ newPortValue;
      uint risingEdges = newPortValue & changedLines;
      m_currentPortValue = newPortValue;

      if (risingEdges != 0)
      {
        onRisingEdgeDetected(currentValue: newPortValue,
                             linesThatAsserted: risingEdges);
      }
  }

  public void Start(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
      m_shouldPoll = true;
      PollForRisingEdge(device, onRisingEdgeDetected);
  }

  public void Stop()
  {
      m_shouldPoll = false;
  }
}

WinForm class

private void Initialize()
{
  m_dev = DASK.Register_Card(DASK.PCI_7250, 0);
  m_mainThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
}

private void StartEdgeDetection()
{
  m_edgeDetectionTask = Task.Factory.StartNew( () =>
    {
      m_edgeDetector.Start(device: m_dev, onRisingEdgeDetected: RescheduleOnMainThread);
    });
}

private RescheduleOnMainThread(uint currentValue, uint linesThatAsserted)
{
  m_onEdgeDetectionTask = Task.Factory.StartNew(
    action: () =>
      {
        MessageBox.Show(currentValue);
      },
    cancellationToken: null,
    creationOptions: TaskCreationOptions.None,
    scheduler: m_mainThreadScheduler);
}

private void CleanUp()
{
  m_edgeDetector.Stop();
  m_edgeDetectionTask.Wait();
  m_onEdgeDetectionTask.Wait();
}

public void Form1_Load(object sender, EventArgs e)
{
  Initialize();
  StartEdgeDetection();
}

public void Form1_Closed(object sender, EventArgs e)
{
  CleanUp();
}
Joe Friedrichsen
  • 1,976
  • 14
  • 14
  • this seems a good idea, similar to what i have tried earlier. Im surely going to try this once im back at the office. Thank you – user726720 Jan 02 '15 at 11:08