Visual Basic USB-1616HS DaqInScan with Asynchronous Digital Input & Output
The following example demonstrates how to continuously read data using DaqInScan and at the same time asynchronously controlling digital lines on FirstPortC. Helper functions are used but not shown as they typically are do not demonstrate MccDaq functionality. To view these function load the project attached to this article.
To access the API, add a reference to the MccDaq object. Adding the reference is usually accomplished by right clicking the Project [under the Project Explorer] and selecting Add Reference.
The functionality is fairly simple, the program puts data into the buffer and the program retrieves it one half buffer at a time. To command the API to sample continuously, the Scan Options enumeration Background and Continuous is used. How it collects data is it ping-pongs between reading the lower half then the upper in attempt to keep up with the incoming data. Care should be taken that data doesn't come so fast that the program fails to keep up. When this happens a buffer overrun occurs which is condition where unread data get overwritten.
For digital output, program uses use keyboard keys 0-3 as a signal to change the state of an I/O line on FirstPortC. In the digital update routine the program reads the digital output port and use an exclusive OR function (XOR) to flip the state. To continuously monitor the key input the program uses a loop and to read the input data it uses timer interrupt routine that fires off every 50mS.
Disclaimer: The attached Code or Example is provided As Is. It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments. You assume all risks for use of the Code for Example.
import statements help reduce line length and typing Imports MccDaq Imports MccDaq.ChannelType Imports MccDaq.Range Imports MccDaq.ScanOptions Imports MccDaq.DigitalPortType Imports MccDaq.FunctionType Imports MccDaq.ErrorInfo.ErrorCode Imports MccDaq.MccService Imports System.Convert Imports System.Threading.Thread Imports System.Timers Imports System.IO Module Module1 Const BLOCKSIZE As Integer = 100 'samples per channel Const CHANNELCOUNT As Integer = 4 Const SAMPLERATE As Integer = 100 'desired sample rate Const BUFFERSIZE As Integer = CHANNELCOUNT * BLOCKSIZE ' size of the buffer Const HALFBUFFER As Integer = BUFFERSIZE / 2 'size of half buffer Const TOTAL As Integer = SAMPLERATE * CHANNELCOUNT * 60 * 2 '2 minutes 'AInScan running options Dim theOptions As MccDaq.ScanOptions = Continuous + Background + ConvertData Dim CurrentCount As Integer = 0 'indicates total samples taken Dim CurrentIndex As Integer = 0 'points to the last scan read Dim Status As Short = 0 Dim theDevice As MccBoard 'device object Dim buffer As IntPtr Dim ret As ErrorInfo Dim ReadLower As Boolean = True 'semaphore flag that prevents duplicate buffer reads 'text file name and path. Use ASC extension if using DASYLab software to read the file. Dim Path As String = "C:\Users\Public\Documents\theDataFile.asc" Dim fStream As StreamWriter Dim ChanArray(CHANNELCOUNT) As Short ' array to hold channel queue information Dim ChanTypeArray(CHANNELCOUNT) As MccDaq.ChannelType ' array to hold channel type information Dim GainArray(CHANNELCOUNT) As MccDaq.Range ' array to hold gain queue information Dim ChanText(CHANNELCOUNT) As String Dim ChanScale(CHANNELCOUNT) As Single Sub Main() Dim atimer As Timer Dim ret As MccDaq.ErrorInfo Dim bNum As Integer Dim str As String = "USB-1616HS" bNum = GetBoardNum(str) If bNum = -1 Then Console.WriteLine("No {0} detected!", str) WaitForKey() End End If 'load the arrays with values ChanArray(0) = 0 ChanTypeArray(0) = Analog GainArray(0) = Bip10Volts ChanText(0) = "In0 [V]" + vbTab ChanScale(0) = Convert.ToSingle(10.0 / 32768) 'volts per bit for the +/- 10 volt range ChanArray(1) = 1 ChanTypeArray(1) = Analog GainArray(1) = Bip10Volts ChanText(1) = "In1 [V]" + vbTab ChanScale(1) = Convert.ToSingle(10.0 / 32768) 'volts per bit for the +/- 10 volt range ChanArray(2) = 3 ChanTypeArray(2) = Analog GainArray(2) = Bip10Volts ChanText(2) = "In1 [V]" + vbTab ChanScale(2) = Convert.ToSingle(10.0 / 32768) 'volts per bit for the +/- 10 volt range ChanArray(3) = FirstPortA ChanTypeArray(3) = Digital16 GainArray(3) = NotUsed ChanText(3) = "FirstPortA [dec]" ChanScale(3) = 1 theDevice = New MccBoard(bNum) 'get the devices' programming object 'set digital port C for output ret = theDevice.DConfigPort(FirstPortC, MccDaq.DigitalPortDirection.DigitalOut) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop End If 'let's start with all 8 bits low Dim PortVal As UShort = 0 ret = theDevice.DOut(FirstPortC, PortVal) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop End If buffer = MccService.WinBufAllocEx(BUFFERSIZE) atimer = New Timer atimer.AutoReset = True atimer.Interval = 50 AddHandler atimer.Elapsed, AddressOf TimerEvent Console.WriteLine("This program reads channel 1,2,3 & FirstPortA as a 16 bit word." + vbCrLf) Console.WriteLine("The program will stream the data continously to:") Console.WriteLine("{0}{1}", Path, vbCrLf) Console.WriteLine("While doing this the digital output lines on Port C can be changed as follows:" + vbCrLf) Console.WriteLine("Keys 0 - 3 toggles the state of D0-D3 on FirstPortC." + vbCrLf) Console.WriteLine("Press <SPACE> to clear all...<ESC> exit program" + vbCrLf) WaitForKey() ret = theDevice.DaqInScan(ChanArray, ChanTypeArray, GainArray, CHANNELCOUNT, SAMPLERATE, 0, BUFFERSIZE, buffer, theOptions) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop 'create a text file to hold the data fStream = New StreamWriter(Path) CreateFileHeader() 'Timer routines checks/reads data every 50mS atimer.Start() '''''''''''''''''''' MAIN LOOP '''''''''''''''''''''''''' Dim cki As ConsoleKeyInfo = New ConsoleKeyInfo Do If Console.KeyAvailable = True Then cki = Console.ReadKey() 'call function to update digital outputs UpdateFirstPortC(cki) End If Loop Until ((cki.Key = ConsoleKey.Escape) Or (CurrentCount > TOTAL)) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''' atimer.Stop() WaitForKey() theDevice.StopBackground(AiFunction) fStream.Close() End Sub Sub TimerEvent(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) ret = theDevice.GetStatus(Status, CurrentCount, CurrentIndex, MccDaq.FunctionType.DaqiFunction) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop 'ping pong between low half and upper half If ((CurrentIndex >= HALFBUFFER) And (ReadLower = True)) Then 'read the lower half and set Upper flag to zero so that next read is upper half Dim theArray(BUFFERSIZE) As UShort ret = MccDaq.MccService.WinBufToArray(buffer, theArray, 0, HALFBUFFER) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop ReadLower = False DisplayData(theArray, HALFBUFFER \ CHANNELCOUNT) ElseIf ((CurrentIndex < HALFBUFFER) And (ReadLower = False)) Then 'read the upper half and set Upper flag to one so that next read is lower half Dim theArray(BUFFERSIZE) As UShort ret = MccDaq.MccService.WinBufToArray(buffer, theArray, HALFBUFFER, HALFBUFFER) If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop ReadLower = True DisplayData(theArray, HALFBUFFER \ CHANNELCOUNT) End If End Sub Sub UpdateFirstPortC(ByVal cki As ConsoleKeyInfo) 'Function used to change level on individual FirstPortC lines Dim PortVal As UShort Dim ret As ErrorInfo = New ErrorInfo Select Case cki.Key Case ConsoleKey.D0 ret = theDevice.DIn(FirstPortC, PortVal) PortVal = PortVal Xor 1 ret = theDevice.DOut(DigitalPortType.FirstPortC, PortVal) Case ConsoleKey.D1 ret = theDevice.DIn(FirstPortC, PortVal) PortVal = PortVal Xor 2 ret = theDevice.DOut(DigitalPortType.FirstPortC, PortVal) Case ConsoleKey.D2 ret = theDevice.DIn(FirstPortC, PortVal) PortVal = PortVal Xor 4 ret = theDevice.DOut(DigitalPortType.FirstPortC, PortVal) Case ConsoleKey.D3 ret = theDevice.DIn(FirstPortC, PortVal) PortVal = PortVal Xor 8 ret = theDevice.DOut(DigitalPortType.FirstPortC, PortVal) Case ConsoleKey.Spacebar ret = theDevice.DOut(DigitalPortType.FirstPortC, 0) End Select If ret.Value <> MccDaq.ErrorInfo.ErrorCode.NoErrors Then Stop End Sub
Attachments
VBNET2008_USB-1616HS_CONT_READ_WITH_ASYNC_DIGITAL.zip