Files

511 lines
16 KiB
C

//Author: LabJack
//April 5, 2011
//This example program reads analog inputs AI0-AI4 using stream mode.
#include "u6.h"
int ConfigIO_example(HANDLE hDevice);
int StreamConfig_example(HANDLE hDevice);
int StreamStart(HANDLE hDevice);
int StreamData_example(HANDLE hDevice, u6CalibrationInfo *caliInfo);
int StreamStop(HANDLE hDevice);
const uint8 NumChannels = 5; //For this example to work proper, SamplesPerPacket needs
//to be a multiple of NumChannels.
const uint8 SamplesPerPacket = 25; //Needs to be 25 to read multiple StreamData responses
//in one large packet, otherwise can be any value between
//1-25 for 1 StreamData response per packet.
int main(int argc, char **argv)
{
HANDLE hDevice;
u6CalibrationInfo caliInfo;
//Opening first found U6 over USB
if( (hDevice = openUSBConnection(-1)) == NULL )
goto done;
//Getting calibration information from U6
if( getCalibrationInfo(hDevice, &caliInfo) < 0 )
goto close;
if( ConfigIO_example(hDevice) != 0 )
goto close;
//Stopping any previous streams
StreamStop(hDevice);
if( StreamConfig_example(hDevice) != 0 )
goto close;
if( StreamStart(hDevice) != 0 )
goto close;
StreamData_example(hDevice, &caliInfo);
StreamStop(hDevice);
close:
closeUSBConnection(hDevice);
done:
return 0;
}
//Sends a ConfigIO low-level command to turn off timers/counters
int ConfigIO_example(HANDLE hDevice)
{
uint8 sendBuff[16], recBuff[16];
uint16 checksumTotal;
int sendChars, recChars, i;
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = (uint8)(0x05); //Number of data words
sendBuff[3] = (uint8)(0x0B); //Extended command number
sendBuff[6] = 1; //Writemask : Setting writemask for TimerCounterConfig (bit 0)
sendBuff[7] = 0; //NumberTimersEnabled : Setting to zero to disable all timers.
sendBuff[8] = 0; //CounterEnable: Setting bit 0 and bit 1 to zero to disable both counters
sendBuff[9] = 0; //TimerCounterPinOffset
for( i = 10; i < 16; i++ )
sendBuff[i] = 0; //Reserved
extendedChecksum(sendBuff, 16);
//Sending command to U6
if( (sendChars = LJUSB_Write(hDevice, sendBuff, 16)) < 16 )
{
if( sendChars == 0 )
printf("ConfigIO error : write failed\n");
else
printf("ConfigIO error : did not write all of the buffer\n");
return -1;
}
//Reading response from U6
if( (recChars = LJUSB_Read(hDevice, recBuff, 16)) < 16 )
{
if( recChars == 0 )
printf("ConfigIO error : read failed\n");
else
printf("ConfigIO error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 16);
if( (uint8)((checksumTotal / 256 ) & 0xff) != recBuff[5] )
{
printf("ConfigIO error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[4] )
{
printf("ConfigIO error : read buffer has bad checksum16(LSB)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ConfigIO error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x05) || recBuff[3] != (uint8)(0x0B) )
{
printf("ConfigIO error : read buffer has wrong command bytes\n");
return -1;
}
if( recBuff[6] != 0 )
{
printf("ConfigIO error : read buffer received errorcode %d\n", recBuff[6]);
return -1;
}
if( recBuff[8] != 0 )
{
printf("ConfigIO error : NumberTimersEnabled was not set to 0\n");
return -1;
}
if( recBuff[9] != 0 )
{
printf("ConfigIO error : CounterEnable was not set to 0\n");
return -1;
}
return 0;
}
//Sends a StreamConfig low-level command to configure the stream.
int StreamConfig_example(HANDLE hDevice)
{
int sendBuffSize;
sendBuffSize = 14+NumChannels*2;
uint8 sendBuff[sendBuffSize], recBuff[8];
int sendChars, recChars;
uint16 checksumTotal;
uint16 scanInterval;
int i;
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = 4 + NumChannels; //Number of data words = NumChannels + 4
sendBuff[3] = (uint8)(0x11); //Extended command number
sendBuff[6] = NumChannels; //NumChannels
sendBuff[7] = 1; //ResolutionIndex
sendBuff[8] = SamplesPerPacket; //SamplesPerPacket
sendBuff[9] = 0; //Reserved
sendBuff[10] = 0; //SettlingFactor: 0
sendBuff[11] = 0; //ScanConfig:
// Bit 3: Internal stream clock frequency = b0: 4 MHz
// Bit 1: Divide Clock by 256 = b0
scanInterval = 4000;
sendBuff[12] = (uint8)(scanInterval&(0x00FF)); //scan interval (low byte)
sendBuff[13] = (uint8)(scanInterval/256); //scan interval (high byte)
for( i = 0; i < NumChannels; i++ )
{
sendBuff[14 + i*2] = i; //ChannelNumber (Positive) = i
sendBuff[15 + i*2] = 0; //ChannelOptions:
// Bit 7: Differential = 0
// Bit 5-4: GainIndex = 0 (+-10V)
}
extendedChecksum(sendBuff, sendBuffSize);
//Sending command to U6
sendChars = LJUSB_Write(hDevice, sendBuff, sendBuffSize);
if( sendChars < sendBuffSize )
{
if( sendChars == 0 )
printf("Error : write failed (StreamConfig).\n");
else
printf("Error : did not write all of the buffer (StreamConfig).\n");
return -1;
}
for( i = 0; i < 8; i++ )
recBuff[i] = 0;
//Reading response from U6
recChars = LJUSB_Read(hDevice, recBuff, 8);
if( recChars < 8 )
{
if( recChars == 0 )
printf("Error : read failed (StreamConfig).\n");
else
printf("Error : did not read all of the buffer, %d (StreamConfig).\n", recChars);
for( i = 0; i < 8; i++)
printf("%d ", recBuff[i]);
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 8);
if( (uint8)((checksumTotal / 256) & 0xff) != recBuff[5])
{
printf("Error : read buffer has bad checksum16(MSB) (StreamConfig).\n");
return -1;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[4] )
{
printf("Error : read buffer has bad checksum16(LSB) (StreamConfig).\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("Error : read buffer has bad checksum8 (StreamConfig).\n");
return -1;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x01) || recBuff[3] != (uint8)(0x11) || recBuff[7] != (uint8)(0x00) )
{
printf("Error : read buffer has wrong command bytes (StreamConfig).\n");
return -1;
}
if( recBuff[6] != 0 )
{
printf("Errorcode # %d from StreamConfig read.\n", (unsigned int)recBuff[6]);
return -1;
}
return 0;
}
//Sends a StreamStart low-level command to start streaming.
int StreamStart(HANDLE hDevice)
{
uint8 sendBuff[2], recBuff[4];
int sendChars, recChars;
sendBuff[0] = (uint8)(0xA8); //Checksum8
sendBuff[1] = (uint8)(0xA8); //Command byte
//Sending command to U6
sendChars = LJUSB_Write(hDevice, sendBuff, 2);
if( sendChars < 2 )
{
if( sendChars == 0 )
printf("Error : write failed.\n");
else
printf("Error : did not write all of the buffer.\n");
return -1;
}
//Reading response from U6
recChars = LJUSB_Read(hDevice, recBuff, 4);
if( recChars < 4 )
{
if( recChars == 0 )
printf("Error : read failed.\n");
else
printf("Error : did not read all of the buffer.\n");
return -1;
}
if( normalChecksum8(recBuff, 4) != recBuff[0] )
{
printf("Error : read buffer has bad checksum8 (StreamStart).\n");
return -1;
}
if( recBuff[1] != (uint8)(0xA9) || recBuff[3] != (uint8)(0x00) )
{
printf("Error : read buffer has wrong command bytes \n");
return -1;
}
if( recBuff[2] != 0 )
{
printf("Errorcode # %d from StreamStart read.\n", (unsigned int)recBuff[2]);
return -1;
}
return 0;
}
//Reads the StreamData low-level function response in a loop.
//All voltages from the stream are stored in the voltages 2D array.
int StreamData_example(HANDLE hDevice, u6CalibrationInfo *caliInfo)
{
int recBuffSize;
recBuffSize = 14 + SamplesPerPacket*2;
int recChars, backLog;
int i, j, k, m, packetCounter, currChannel, scanNumber;
int totalPackets; //The total number of StreamData responses read
uint16 voltageBytes, checksumTotal;
long startTime, endTime;
int autoRecoveryOn;
int numDisplay; //Number of times to display streaming information
int numReadsPerDisplay; //Number of packets to read before displaying streaming information
int readSizeMultiplier; //Multiplier for the StreamData receive buffer size
int responseSize; //The number of bytes in a StreamData response (differs with SamplesPerPacket)
numDisplay = 6;
numReadsPerDisplay = 24;
readSizeMultiplier = 5;
responseSize = 14 + SamplesPerPacket*2;
/* Each StreamData response contains (SamplesPerPacket / NumChannels) * readSizeMultiplier
* samples for each channel.
* Total number of scans = (SamplesPerPacket / NumChannels) * readSizeMultiplier * numReadsPerDisplay * numDisplay
*/
double voltages[(SamplesPerPacket/NumChannels)*readSizeMultiplier*numReadsPerDisplay*numDisplay][NumChannels];
uint8 recBuff[responseSize*readSizeMultiplier];
packetCounter = 0;
currChannel = 0;
scanNumber = 0;
totalPackets = 0;
recChars = 0;
autoRecoveryOn = 0;
printf("Reading Samples...\n");
startTime = getTickCount();
for( i = 0; i < numDisplay; i++ )
{
for( j = 0; j < numReadsPerDisplay; j++ )
{
/* For USB StreamData, use Endpoint 3 for reads. You can read the multiple
* StreamData responses of 64 bytes only if SamplesPerPacket is 25 to help
* improve streaming performance. In this example this multiple is adjusted
* by the readSizeMultiplier variable.
*/
//Reading stream response from U6
recChars = LJUSB_Stream(hDevice, recBuff, responseSize*readSizeMultiplier);
if( recChars < responseSize*readSizeMultiplier )
{
if(recChars == 0)
printf("Error : read failed (StreamData).\n");
else
printf("Error : did not read all of the buffer, expected %d bytes but received %d(StreamData).\n", responseSize*readSizeMultiplier, recChars);
return -1;
}
//Checking for errors and getting data out of each StreamData response
for( m = 0; m < readSizeMultiplier; m++ )
{
totalPackets++;
checksumTotal = extendedChecksum16(recBuff + m*recBuffSize, recBuffSize);
if( (uint8)((checksumTotal >> 8) & 0xff) != recBuff[m*recBuffSize + 5] )
{
printf("Error : read buffer has bad checksum16(MSB) (StreamData).\n");
return -1;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[m*recBuffSize + 4] )
{
printf("Error : read buffer has bad checksum16(LSB) (StreamData).\n");
return -1;
}
checksumTotal = extendedChecksum8(recBuff + m*recBuffSize);
if( checksumTotal != recBuff[m*recBuffSize] )
{
printf("Error : read buffer has bad checksum8 (StreamData).\n");
return -1;
}
if( recBuff[m*recBuffSize + 1] != (uint8)(0xF9) || recBuff[m*recBuffSize + 2] != 4 + SamplesPerPacket || recBuff[m*recBuffSize + 3] != (uint8)(0xC0) )
{
printf("Error : read buffer has wrong command bytes (StreamData).\n");
return -1;
}
if( recBuff[m*recBuffSize + 11] == 59 )
{
if( !autoRecoveryOn )
{
printf("\nU6 data buffer overflow detected in packet %d.\nNow using auto-recovery and reading buffered samples.\n", totalPackets);
autoRecoveryOn = 1;
}
}
else if( recBuff[m*recBuffSize + 11] == 60 )
{
printf("Auto-recovery report in packet %d: %d scans were dropped.\nAuto-recovery is now off.\n", totalPackets, recBuff[m*recBuffSize + 6] + recBuff[m*recBuffSize + 7]*256);
autoRecoveryOn = 0;
}
else if( recBuff[m*recBuffSize + 11] != 0 )
{
printf("Errorcode # %d from StreamData read.\n", (unsigned int)recBuff[11]);
return -1;
}
if( packetCounter != (int)recBuff[m*recBuffSize + 10] )
{
printf("PacketCounter (%d) does not match with with current packet count (%d)(StreamData).\n", recBuff[m*recBuffSize + 10], packetCounter);
return -1;
}
backLog = (int)recBuff[m*48 + 12 + SamplesPerPacket*2];
for( k = 12; k < (12 + SamplesPerPacket*2); k += 2 )
{
voltageBytes = (uint16)recBuff[m*recBuffSize + k] + (uint16)recBuff[m*recBuffSize + k+1]*256;
getAinVoltCalibrated(caliInfo, 1, 0, 0, voltageBytes, &(voltages[scanNumber][currChannel]));
currChannel++;
if( currChannel >= NumChannels )
{
currChannel = 0;
scanNumber++;
}
}
if(packetCounter >= 255)
packetCounter = 0;
else
packetCounter++;
}
}
printf("\nNumber of scans: %d\n", scanNumber);
printf("Total packets read: %d\n", totalPackets);
printf("Current PacketCounter: %d\n", ((packetCounter == 0) ? 255 : packetCounter-1));
printf("Current BackLog: %d\n", backLog);
for( k = 0; k < NumChannels; k++ )
printf(" AI%d: %.4f V\n", k, voltages[scanNumber - 1][k]);
}
endTime = getTickCount();
printf("\nRate of samples: %.0lf samples per second\n", (scanNumber*NumChannels)/((endTime - startTime)/1000.0));
printf("Rate of scans: %.0lf scans per second\n\n", scanNumber/((endTime - startTime)/1000.0));
return 0;
}
//Sends a StreamStop low-level command to stop streaming.
int StreamStop(HANDLE hDevice)
{
uint8 sendBuff[2], recBuff[4];
int sendChars, recChars;
sendBuff[0] = (uint8)(0xB0); //Checksum8
sendBuff[1] = (uint8)(0xB0); //Command byte
//Sending command to U6
sendChars = LJUSB_Write(hDevice, sendBuff, 2);
if( sendChars < 2 )
{
if( sendChars == 0 )
printf("Error : write failed (StreamStop).\n");
else
printf("Error : did not write all of the buffer (StreamStop).\n");
return -1;
}
//Reading response from U6
recChars = LJUSB_Read(hDevice, recBuff, 4);
if( recChars < 4 )
{
if( recChars == 0 )
printf("Error : read failed (StreamStop).\n");
else
printf("Error : did not read all of the buffer (StreamStop).\n");
return -1;
}
if( normalChecksum8(recBuff, 4) != recBuff[0] )
{
printf("Error : read buffer has bad checksum8 (StreamStop).\n");
return -1;
}
if( recBuff[1] != (uint8)(0xB1) || recBuff[3] != (uint8)(0x00) )
{
printf("Error : read buffer has wrong command bytes (StreamStop).\n");
return -1;
}
if( recBuff[2] != 0 )
{
printf("Errorcode # %d from StreamStop read.\n", (unsigned int)recBuff[2]);
return -1;
}
/*
//Reading left over data in stream endpoint. Only needs to be done with firmwares
//less than 0.94.
uint8 recBuffS[64];
int recCharsS = 64;
printf("Reading left over data from stream endpoint.\n");
while( recCharsS > 0 )
recCharsS = LJUSB_Stream(hDevice, recBuffS, 64);
*/
return 0;
}