Copy AIOEDIO.dll next to the program that will use it (or to the 32-bit system directory, or anywhere else the program can find it).
The general sequence is:
If the connection fails during operation, a new connection can be swapped in, like this:
The server serializes and deserializes packets in Intel (little-endian) bit order. For example, if the first 8 bits of a packet are 0 1 0 1 1 0 1 1, then the first byte of the packet is 0xDA.
function AED_Connect(Host: PChar; bReadPort: LongBool; Index: LongInt): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_Connect(char *Host, unsigned long bReadPort, signed long Index);
AED_Connect() connects to the specified device on the specified host. It returns a client reference (like a handle) that represents the connection, or zero on a failure. Before data can be read or written, AED_Go() must be called.
Host can be an IP address in dotted decimal string form (like "10.1.1.42"), a DNS name (like "dio.overthere.com"), or a name in the HOSTS file (like "localhost").
bReadPort should be nonzero to connect to the port for an input board on the host, or zero to connect to the port for an output board.
Index is a zero-based index of the port, separate for read and write ports. The current design has three read ports (index 0, index 1, index 2) and one write port (index 0).
The returned client reference is opaque — just a 4-byte value that you pass to the other AED_* APIs when dealing with that connection. While this is similar to a handle, it doesn't work with any handle-specific APIs, like GetHandleInformation() or CloseHandle(). On a failure, the returned reference will be zero, and the associated Windows error code can be retrieved via GetLastError(). Error codes include:
The server does allow more than one client to connect to a single device. This feature is intended for recovery from network problems, but does allow (for example) two programs to connect, one that reads data and one that changes clock frequency.
function AED_SetFreq(uClientRef: LongWord; Hz: LongInt): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetFreq(unsigned long uClientRef, signed long Hz);
AED_SetFreq() sets the clock frequency of a device.
Hz is the clock frequency to set the board to. For external/slave operation, use 0. The default at power-on is external/slave, but this setting is remembered by the server while powered on.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes include:
function AED_SetPacketBits(uClientRef: LongWord; NewPacketBits: LongInt): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetPacketBits(unsigned long uClientRef, signed long NewPacketBits);
AED_SetPacketBits() sets the number of bits in the device's packets. This also sets the number of bytes to one-eighth (round up) the number of bits. While AED_GetData() and AED_GetLatestPacketAndDiscard() get one packet, and therefore don't need a fixed packet size, the current packet bytes is used for the array filled in by AED_GetLatestPacketAndDiscard(), and the current packet bits is used by packets sent with AED_PutData(). The server will truncate or zero-pad as needed.
NewPacketBits is the new packet size, in bits. The default at power-on is 176, but this setting is remembered by the server while powered on.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are mostly covered under AED_SetFreq(), but also include:
function AED_SetBlockSize(uClientRef: LongWord; SizeBytes: LongInt): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetBlockSize(unsigned long uClientRef, signed long SizeBytes);
AED_SetBlockSize() sets the block/frame size for DIO_StreamFrame() reads. In this high-responsiveness design, the default minimum block size is ideal, so it's generally best to leave it alone. If called while the server's acquisition loops are running, this setting will take effect after the current block finishes.
SizeBytes is the new block size, in bytes. It will be rounded up to the next multiple of 512. The default at power-on is 512, but this setting is remembered by the server while powered on.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are mostly covered under AED_SetFreq(), but also include:
function AED_SetTimeout(uClientRef: LongWord; TimeoutMS: LongInt): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetTimeout(unsigned long uClientRef, signed long TimeoutMS);
AED_SetTimeout() sets the inter-receive timeout for reply network packets. This is a client setting, and thus setting it doesn't involve network traffic.
TimeoutMS is the new timeout, in milliseconds. The default for a new connection is 2000.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are mostly covered under AED_SetFreq(), but also include:
function AED_SetAZero(uClientRef: LongWord; bNewBit: LongBool): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetAZero(unsigned long uClientRef, unsigned long bNewBit);
AED_SetAZero() sets the first "medium-speed" digital bit on a device.
bNewBit is interpreted as a boolean, true to set the bit high, false to set it low. The default at power-on is high, but this setting is remembered by the server while powered on.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are covered under AED_SetFreq().
function AED_SetMDIO1(uClientRef, Index: LongWord; bNewBit: LongBool): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_SetMDIO1(unsigned long uClientRef, unsigned long Index, unsigned long bNewBit);
AED_SetMDIO1() sets one of the "medium-speed" digital bits on a device.
Index indicates which bit to set. Port A has bits 0-7, port B has bits 8-11, port C has bits 16-18. Port D technically has bits 24-26, but it's in input mode, and writes to input bits are ignored. Any bit 0-31 is accepted, but other bits in this range are unoccupied.
bNewBit is interpreted as a boolean, true to set the bit high, false to set it low. The default at power-on is high, but this setting is remembered by the server while powered on.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are mostly covered under AED_SetFreq(), but also include:
function AED_Go(uClientRef: LongWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_Go(unsigned long uClientRef);
AED_Go() starts the server's acquisition loops. This is necessary before data can be read or written; the block size will be used at this time, and should be set first.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are covered under AED_SetFreq().
function AED_GoClear(uClientRef: LongWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_GoClear(unsigned long uClientRef);
As AED_Go(), except the various buffers are cleared first as for AED_Clear().
function AED_Clear(uClientRef: LongWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_Clear(unsigned long uClientRef);
Clears the various buffers in the server. If the server was already acquiring a slow block, that block will finish first (so it can be cleared).
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are covered under AED_SetFreq().
function AED_GetLatestPacketAndDiscard(uClientRef: LongWord; pTimestampDataBytes: PLongInt; pTimestampData: PDouble; pPacketDataBytes: PLongInt; pPacketData: PByte): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_GetLatestPacketAndDiscard(unsigned long uClientRef, signed long *pTimestampDataBytes, double *pTimestampData, signed long *pPacketDataBytes, unsigned char *pPacketData);
AED_GetLatestPacketAndDiscard() gets the latest packet from a read port, along with its timestamp, and discards any other queued packets. If no packets are available in the port's queue, it will return a zero-length success.
pTimestampDataBytes is a pointer to a variable that holds the size of the variable pointed to by pTimestampData, in bytes. On return, this variable will be set to the bytes of timestamp read. Both should be 8 when functioning properly.
pTimestampData is a pointer to an IEEE double-precision floating-point variable to read the timestamp into. The timestamp is a TDateTime, equal to days since the 30th of December 1899, according to the server's system clock.
pPacketDataBytes is a pointer to a variable that holds the size of the buffer to read a packet into, in bytes. On return, this variable will be set to the bytes of packet read.
pPacketData is a pointer to the buffer to read a packet into.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Some error codes are covered under AED_SetFreq(), but also include:
function AED_GetAllPackets(uClientRef: LongWord; pTimestampDataBytes: PLongInt; pTimestampData: PDouble; pPacketDataBytes: PLongInt; pPacketData: PByte): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_GetAllPackets(unsigned long uClientRef, signed long *pTimestampDataBytes, double *pTimestampData, signed long *pPacketDataBytes, unsigned char *pPacketData);
AED_GetAllPackets() gets all packets queued on a read port, along with their timestamps. If no packets are available in the port's queue, it will return a zero-length success.
pTimestampDataBytes is a pointer to a variable that holds the size of the buffer to read timestamps into, in bytes. On return, this variable will be set to the bytes of timestamps read.
pTimestampData is a pointer to the buffer to read timestamps into, seen as an array of IEEE double-precision floating-point values. Since the max queue depth is currently 400, it is perhaps ideal for this to be an array of 400 (3 200 bytes).
pPacketDataBytes is a pointer to a variable that holds the size of the buffer to read packets into, in bytes. On return, this variable will be set to the bytes of packets read.
pPacketData is a pointer to the buffer to read packets into, seen as an array of packet structs. Each packet struct has the same size, given by the current packet bytes. Since the max queue depth is currently 400, it is perhaps ideal for this to be an array of 400; with 176-bit (22-byte) packets, that comes to 8 800 bytes.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are covered under AED_GetLatestPacketAndDiscard().
function AED_GetData(uClientRef: LongWord; pDataBytes: PLongInt; pData: PWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_GetData(unsigned long uClientRef, signed long *pDataBytes, unsigned short *pData);
AED_GetData() gets the oldest packet from a read port. If no packets are available in the port's queue, it will return a zero-length success. This function is deprecated in this high-responsiveness design.
pDataBytes is a pointer to a variable that holds the size of the buffer to read into, in bytes. On return, this variable will be set to the amount of data read.
pData is a pointer to the buffer to read into.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are covered under AED_GetLatestPacketAndDiscard(), except there's one pDataBytes in place of pTimestampDataBytes and pPacketDataBytes.
function AED_PutData(uClientRef: LongWord; pDataBytes: PLongInt; pData: PWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_PutData(unsigned long uClientRef, signed long *pDataBytes, unsigned short *pData);
AED_PutData() writes a packet to a write port. If this packet is smaller than the current packet bits, it will be truncated; if larger, it will be zero-padded.
pDataBytes is a pointer to a variable that holds the size of the buffer to write from, in bytes. On return, this variable will be set to the amount of data written.
pData is a pointer to the buffer to write from.
The return value is ERROR_SUCCESS (equal to zero) on success, or another Windows error code on failure. Error codes are mostly covered under AED_SetFreq() and AED_GetData(), but also include:
function AED_Close(uClientRef: LongWord): LongWord; cdecl; external 'AIOEDIO.dll';
__declspec(dllimport) unsigned long AED_Close(unsigned long uClientRef);
AED_Close() closes a client reference, disconnecting the connection and cleaning up any memory used. After being passed to AED_Close(), the client reference is invalid.
Each device has a specific value in the first four bytes of the EEPROM, which the server looks for. In order to facilitate field replacements, these values are listed below (in hex):
EEPROM Address | 000 | 001 | 002 | 003 |
---|---|---|---|---|
DI/DIO board for read index 0 | 10 | ED | A5 | 00 |
DI/DIO board for read index 1 | 11 | ED | A5 | 00 |
DI/DIO board for read index 2 | 12 | ED | A5 | 00 |
DO/DIO board for write index 0 | 00 | ED | A5 | 00 |
These EEPROM addresses are relative to the user-programmable space, as seen by eWriter.exe, GetDeviceByEEPROMByte(), CustomEEPROMRead(). If using "raw" EEPROM access, e.g. by sending arbitrary USB requests, you'll need to add 1E00, producing absolute addresses 1E00, 1E01, 1E02, and 1E03.