' Minimalist example showing acquisition and
' graphing of analog signals
' using DriverLINX/VB

' Global Variables
Dim ADdata() As Integer           ' sample buffer
Dim ADbits As Integer             ' A/D resolution in bits
Dim ADminCode As Integer          ' min A/D code
Dim ADmaxCode As Integer          ' max A/D code
Dim ADresolution As Integer       ' A/D resolution in steps
Dim ADminVolts As Single          ' min A/D voltage
Dim ADmaxVolts As Single          ' max A/D voltage
Dim ADrangeVolts As Single        ' A/D voltage range
Dim ADvoltsUnit As Single         ' A/D volts/A/D unit
Dim ADvoltsOffset As Single       ' A/D offset
Dim ClkPeriod As Single           ' Clock tic in seconds
Dim ADshift As Integer            ' right-shift A/D data
Dim ADmask As Integer             ' A/D mask

Sub ShowResult (dl As Control)
  ' Display result of last DriverLINX Service Request
  If dl.Res_Result <> DL_NoErr Then
    Readout.Text = dl.Message  ' Show text on form
    dl.Req_op = DL_MESSAGEBOX  ' and pop-up message box
    dl.Refresh
  Else
    Readout.Text = "OK"
  End If
End Sub

Sub LoadLDDinfo (LDD As Control)
  ' Get hardware information
  Dim range As Single
  Dim mask As Long

  ' Validate argument
  If TypeOf LDD Is DriverLINXLDD Then
  Else
    MsgBox "Invalid argument", 48, "Parameter error"
    Stop
  End If

  ' Get hardware specs from Logical Device Descriptor
  ADbits = LDD.AI_Bits
  ADminCode = LDD.AI_MM_minCode(0)
  ADmaxCode = LDD.AI_MM_maxCode(0)
  ADresolution = ADmaxCode - ADminCode + 1
  ADminVolts = LDD.AI_MM_min(0)
  ADmaxVolts = LDD.AI_MM_max(0)
  ADrangeVolts = ADmaxVolts - ADminVolts

  ' +FS is actually +FS - 1 LSB
  ADmaxVolts = ADmaxVolts - (ADrangeVolts / ADresolution)

  ' Calc A/D units to volts transform
  ADvoltsUnit = ADrangeVolts / ADresolution
  ADvoltsOffset = ADmaxVolts - ADmaxCode * ADvoltsUnit

  ' Determine sampling frequencies
  ClkPeriod = LDD.CT_TicPeriod(LDD.AI_DefaultCT) * .000001!

  ' Calc # of positions to right-shift A/D data if native format
  mask = LDD.AI_Mask
  ADshift = 1
  Do Until (mask And 1&) <> 0
    mask = mask \ 2
    ADshift = ADshift * 2
  Loop
  If LDD.AI_Mask > 32767 Then
    ADmask = LDD.AI_Mask - 65536  ' compensate for lack of unsigned integer
  Else
    ADmask = LDD.AI_Mask
  End If
End Sub

Sub GraphData (dl As Control)
  ' Quick plot of input data
  Dim n As Integer, i As Integer, yi As Integer
  Dim WVxm As Single, WVxa As Single
  Dim WVym As Single, WVya As Single
  Dim X As Single, Y As Single

  ' Calculate number of points and copy data from buffer
  n = dl.Sel_buf_samples
  ReDim ADdata(n)
  dummy = VBArrayBufferXfer(dl, 0, ADdata(0), 0)

  ' Calculate viewing transform factors
  WVxm = ScaleWidth / n
  WVxa = ScaleLeft - 0 * WVxm
  WVym = ScaleHeight / ADresolution
  WVya = ScaleHeight - (2 ^ (ADbits - 1)) * WVym

  Cls
  ' Draw baseline
  Line (WVxa, WVya)-Step(ScaleWidth, 0), RGB(0, 128, 0)

  Select Case dl.Sel_chan_format
    Case DL_tNATIVE
      WVya = ScaleHeight - ADmaxCode * WVym
      For i = 0 To n - 1
        X = WVxm * i + WVxa
        yi = ADdata(i) And ADmask
        If ADshift > 1 Then       ' right shift?
          yi = yi \ ADshift
          If yi < 0 Then          '
            ' compensate for lack of unsigned integer
            Y = yi And (ADresolution - 1)
          Else
            Y = yi
          End If
        Else
          Y = yi                  ' no right shift
        End If
        Y = WVym * Y + WVya
        PSet (X, Y), 0
      Next i
    Case Else
      For i = 0 To n - 1
        X = WVxm * i + WVxa
        Y = WVym * ADdata(i) + WVya
        PSet (X, Y), 0
      Next i
  End Select
End Sub

Sub Test_Click ()
  Dim EditFlag As Integer

  DriverLINX_SR1.Req_subsystem = DL_AI
  DriverLINX_SR1.Req_mode = DL_POLLED
  DriverLINX_SR1.Req_op = DL_START
  EditFlag = 1
  DriverLINX_SR1.Req_op_edit = EditFlag
  DriverLINX_SR1.Evt_Tim_type = DL_RATEEVENT
  DriverLINX_SR1.Evt_Tim_rateChannel = DL_DEFAULTTIMER
  DriverLINX_SR1.Evt_Tim_rateMode = DL_RATEGEN
  DriverLINX_SR1.Evt_Tim_rateClock = DL_INTERNAL1
  DriverLINX_SR1.Evt_Tim_rateGate = DL_DISABLED
  ' Convert 10 kHZ sampling rate to tics
  DriverLINX_SR1.Evt_Tim_ratePeriod = 1 / (10000! * DriverLINX_LDD1.CT_TicPeriod(DriverLINX_LDD1.AI_DefaultCT) * .000001!)
  DriverLINX_SR1.Evt_Str_type = DL_COMMAND
  DriverLINX_SR1.Evt_Stp_type = DL_TCEVENT
  DriverLINX_SR1.Sel_buf_N = 1
  DriverLINX_SR1.Sel_buf_size = 1000
  DriverLINX_SR1.Sel_chan_N = 1
  DriverLINX_SR1.Sel_chan_start = 0
  If DriverLINX_SR1.Req_mode = DL_DMA Then
    DriverLINX_SR1.Sel_chan_format = DL_tNATIVE
  Else
    DriverLINX_SR1.Sel_chan_format = DL_tINTEGER
  End If
  If EditFlag Then
    Readout.Text = "Edit AI"
  Else
    Readout.Text = "Polled AI"
  End If
  DriverLINX_SR1.Refresh
  If EditFlag Then
    ShowResult DriverLINX_SR1
    If DriverLINX_SR1.Req_mode = DL_DMA Then
      DriverLINX_SR1.Sel_chan_format = DL_tNATIVE
    End If
    DriverLINX_SR1.Refresh
  End If
  ShowResult DriverLINX_SR1
End Sub

Sub DriverLINX_SR1_ServiceDone (task As Integer, Device As Integer, subsystem As Integer, mode As Integer)
  ' Graph acquired data
  Readout.Text = "Service Done"
  GraphData DriverLINX_SR1
End Sub

Sub DriverLINX_SR1_ServiceStart (task As Integer, Device As Integer, subsystem As Integer, mode As Integer)
  ' Update status
  Readout.Text = "Service Start"
End Sub

Sub RequestDLL (SR As Control)
  ' Request name of DLL
  If TypeOf SR Is DriverLINXSR Then
  Else
    Stop
    Exit Sub
  End If
  
  Load FileForm     ' Load form
  FileForm.Caption = "File Open"
  FileForm.TXT_TextBox.Text = "*.dll"
  FileForm.FIL_Files.Refresh
  On Error GoTo CheckError
  Do Until SR.Req_DLL_name <> ""
    FileForm.Show 1 ' MODAL
    If Not CancelOp Then
      SR.Req_DLL_name = FileForm.TXT_TextBox.Text
    End If
  Loop
  Unload FileForm  ' Unload form
  Exit Sub

CheckError:
  If Err = 48 Then
    SR.Req_DLL_name = ""
  End If
  Resume Next
End Sub

Sub Form_Load ()
  Readout.Text = "Initializing"
  If DriverLINX_SR1.Req_DLL_name = "" Then
    RequestDLL DriverLINX_SR1
  End If
  DriverLINX_LDD1.Req_DLL_name = DriverLINX_SR1.Req_DLL_name
  ' Initialize hardware
  DriverLINX_SR1.Req_device = 0
  DriverLINX_SR1.Req_subsystem = DL_DEVICE
  DriverLINX_SR1.Req_mode = DL_OTHER
  DriverLINX_SR1.Req_op = DL_INITIALIZE
  DriverLINX_SR1.Refresh
  ShowResult DriverLINX_SR1
  DriverLINX_LDD1.Device = DriverLINX_SR1.Req_device
  LoadLDDinfo DriverLINX_LDD1
End Sub

