long eAIN(HANDLE Handle, ue9CalibrationInfo *caliInfo, long ChannelP, long ChannelN, double *Voltage, long Range, long Resolution, long Settling, long Binary, long Reserved1, long Reserved2) { uint8 IOType, Channel, AINM, AINH, ainGain; uint16 bytesVT; if(Range == LJ_rgBIP5V) ainGain = 8; else if(Range == LJ_rgUNI5V) ainGain = 0; else if(Range == LJ_rgUNI2P5V) ainGain = 1; else if(Range == LJ_rgUNI1P25V) ainGain = 2; else if(Range == LJ_rgUNIP625V) ainGain = 3; else { printf("eAIN error: Invalid Range\n"); return -1; } if(ehSingleIO(Handle, 4, (uint8)ChannelP, ainGain, (uint8)Resolution, (uint8)Settling, &IOType, &Channel, NULL, &AINM, &AINH) < 0) return -1; bytesVT = AINM + AINH*256; if(Binary != 0) { *Voltage = (double)bytesVT; } else { if(isCalibrationInfoValid(caliInfo) == -1) { if(Channel == 133 || ChannelP == 141) { binaryToUncalibratedAnalogTemperature(bytesVT, Voltage); } else { if(binaryToUncalibratedAnalogVoltage(ainGain, Resolution, bytesVT, Voltage) < 0) return -1; } } else { if(ChannelP == 133 || ChannelP == 141) { if(binaryToCalibratedAnalogTemperature(caliInfo, 0, bytesVT, Voltage) < 0) return -1; } else { if(binaryToCalibratedAnalogVoltage(caliInfo, ainGain, (uint8)Resolution, bytesVT, Voltage) < 0) return -1; } } } return 0; }
//Sends 1000 Feedback low-level commands to read digital IO and analog inputs. //On the first send, the following are set: DAC0 to 2.5 volts, DAC1 to 3.5 //volts, and digital IOs to inputs. int allIO(int socketFD, ue9CalibrationInfo *caliInfo) { uint8 sendBuff[34], recBuff[64]; int sendChars, recChars; int i, j; uint16 checksumTotal, bytesVoltage; int initialize; //boolean to init. DAC and digital IO settings int numIterations; long time; uint8 numChannels; //Number of AIN channels, 0-16. long ainResolution; double valueAIN[16]; int valueDIPort; uint8 settlingTime; uint16 ainMask; numIterations = 1000; initialize = 1; time = 0; numChannels = 8; ainResolution = 12; for(i = 0; i < 16; i++) valueAIN[i] = 9999.0; settlingTime = 0; ainMask = pow(2.0, numChannels) - 1; sendBuff[1] = (uint8)(0xF8); //command byte sendBuff[2] = (uint8)(0x0E); //number of data words sendBuff[3] = (uint8)(0x00); //extended command number sendBuff[6] = 255; //FIOMask : setting the mask of all FIOs sendBuff[7] = 0; //FIODir : setting all FIO directions to input sendBuff[8] = 0; //FIOState : all FIO directions are input, so // state writes do not apply sendBuff[9] = 255; //EIOMask : setting the mask of all EIOs sendBuff[10] = 0; //EIODir : setting all EIO directions to input sendBuff[11] = 0; //EIOState : all EIO directions are input, so // state writes do not apply sendBuff[12] = 15; //CIOMask : setting the mask of all CIOs sendBuff[13] = 0; //CIODirState : setting all CIO directions to input, // state writes do not apply sendBuff[14] = 7; //MIOMask : setting the mask of all MIOs sendBuff[15] = 0; //MIODirState : setting all MIO directions to input, // state writes do not apply //getting binary DAC0 value of 2.5 volts if(analogToCalibratedBinaryVoltage(caliInfo, 0, 2.500, &bytesVoltage) < 0) return -1; //setting the voltage of DAC0 to 2.5 sendBuff[16] = (uint8)(bytesVoltage & 255); //low bits of DAC0 sendBuff[17] = (uint8)(bytesVoltage/256) + 192; //high bits of DAC0 //(bit 7 : Enable, //bit 6: Update) //getting binary DAC1 value of 3.5 volts if(analogToCalibratedBinaryVoltage(caliInfo, 1, 3.500, &bytesVoltage) < 0) return -1; //setting the voltage of DAC1 to 3.5 volts sendBuff[18] = (uint8)(bytesVoltage & 255); //low bits of DAC1 sendBuff[19] = (uint8)(bytesVoltage/256) + 192; //high bits of DAC1 //(bit 7 : Enable, //bit 6: Update) //AINMask - reading the number of AINs specified by numChannels sendBuff[20] = ainMask & 255; //AINMask (low byte) sendBuff[21] = ainMask/256; //AINMask (high byte) sendBuff[22] = 14; //AIN14ChannelNumber : setting to channel 14 sendBuff[23] = 15; //AIN15ChannelNumber : setting to channel 15 sendBuff[24] = ainResolution; //Resolution : Resolution specified by // ainResolution sendBuff[25] = settlingTime; //SettlingTime //setting all BipGains (Gain = 1, Bipolar = 1) for(i = 26; i < 34; i++) sendBuff[i] = (uint8)(0x00); extendedChecksum(sendBuff, 34); time = getTickCount(); for(i = 0; i < numIterations; i++) { //Sending command to UE9 sendChars = send(socketFD, sendBuff, 34, 0); if(sendChars < 34) { if(sendChars == 0) printf("Feedback error (Iteration %d) : send failed\n", i); else printf("Feedback error (Iteration %d) : did not send all of the buffer\n", i); return -1; } //Reading response from UE9 recChars = recv(socketFD, recBuff, 64, 0); if(recChars < 64) { if(recChars == 0) printf("Feedback error (Iteration %d) : rcv failed\n", i); else printf("Feedback error (Iteration %d) : did not rcv all of the buffer\n", i); return -1; } checksumTotal = extendedChecksum16(recBuff, 64); if( (uint8)((checksumTotal / 256) & 0xff) != recBuff[5]) { printf("Feedback error (Iteration %d) : read buffer has bad checksum16(MSB)\n", i); return -1; } if( (uint8)(checksumTotal & 255) != recBuff[4]) { printf("Feedback error (Iteration %d) : read buffer has bad checksum16(LBS)\n", i); return -1; } if( extendedChecksum8(recBuff) != recBuff[0]) { printf("Feedback error (Iteration %d) : read buffer has bad checksum8\n", i); return -1; } if(recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x1D) || recBuff[3] != (uint8)(0x00)) { printf("Feedback error (Iteration %d) : read buffer has wrong command bytes\n", i); return -1; } for(j = 0; j < numChannels && j < 16; j++) binaryToCalibratedAnalogVoltage(caliInfo, 0x00, ainResolution, recBuff[12 + j*2] + recBuff[13 + j*2]*256, &valueAIN[j]); valueDIPort = recBuff[7] + recBuff[9]*256 + (recBuff[10] & 15)*65536 + (recBuff[11] & 7)*1048576; if(initialize == 1) { //unsetting digital IO bit masks since we only want to read states now sendBuff[6] = 0; //FIOMask sendBuff[9] = 0; //EIOMask sendBuff[12] = 0; //CIOMask sendBuff[14] = 0; //MIOMask //turning off Update bit of DACs sendBuff[17] = sendBuff[17] - 64; //high bits of DAC0 sendBuff[19] = sendBuff[19] - 64; //high bits of DAC1 extendedChecksum(sendBuff, 34); initialize = 0; } } time = getTickCount() - time; printf("Milleseconds per iteration = %.3f\n", (double)time / (double)numIterations); printf("\nDigital Input (FIO0-7, EIO0-7, CIO0-3, MIO0-2) = %d\n",valueDIPort); printf("\nAIN readings from last iteration:\n"); for( j = 0; j < numChannels; j++) printf("%.6f\n", valueAIN[j]); return 0; }
long eAIN(HANDLE Handle, u3CalibrationInfo *CalibrationInfo, long ConfigIO, long *DAC1Enable, long ChannelP, long ChannelN, double *Voltage, long Range, long Resolution, long Settling, long Binary, long Reserved1, long Reserved2) { uint8 sendDataBuff[3], recDataBuff[2]; uint8 FIOAnalog, EIOAnalog, curFIOAnalog, curEIOAnalog, curTCConfig; uint8 settling, quicksample, Errorcode, ErrorFrame; uint8 outDAC1Enable; uint16 bytesVT; long error; double hwver; int hv; if (isCalibrationInfoValid(CalibrationInfo) != 1) { printf("eAIN error: calibration information is required"); return -1; } hwver = CalibrationInfo->hardwareVersion; hv = CalibrationInfo->highVoltage; if (ChannelP < 0 || (ChannelP > 15 && ChannelP != 30 && ChannelP != 31)) { printf("eAIN error: Invalid positive channel\n"); return -1; } if (ChannelN < 0 || (ChannelN > 15 && ChannelN != 30 && ChannelN != 31) || (hwver >= 1.30 && hv == 1 && ((ChannelP < 4 && ChannelN != 31) || ChannelN < 4))) { printf("eAIN error: Invalid negative channel\n"); return -1; } if (hwver >= 1.30 && hv == 1 && ChannelP < 4) {} else if (ConfigIO != 0) { FIOAnalog = 0; EIOAnalog = 0; //Setting ChannelP and ChannelN channels to analog using //FIOAnalog and EIOAnalog if (ChannelP <= 7) FIOAnalog = pow(2, ChannelP); else if (ChannelP <= 15) EIOAnalog = pow(2, (ChannelP - 8)); if (ChannelN <= 7) FIOAnalog = FIOAnalog | (int)pow(2, ChannelN); else if (ChannelN <= 15) EIOAnalog = EIOAnalog | (int)pow(2, (ChannelN - 8)); //Using ConfigIO to get current FIOAnalog and EIOAnalog settings if ((error = ehConfigIO(Handle, 0, 0, 0, 0, 0, &curTCConfig, &outDAC1Enable, &curFIOAnalog, &curEIOAnalog)) != 0) return error; *DAC1Enable = outDAC1Enable; if ( !(FIOAnalog == curFIOAnalog && EIOAnalog == curEIOAnalog) ) { //Creating new FIOAnalog and EIOAnalog settings FIOAnalog = FIOAnalog | curFIOAnalog; EIOAnalog = EIOAnalog | curEIOAnalog; //Using ConfigIO to set new FIOAnalog and EIOAnalog settings if ((error = ehConfigIO(Handle, 12, curTCConfig, 0, FIOAnalog, EIOAnalog, NULL, NULL, &curFIOAnalog, &curEIOAnalog)) != 0) return error; } } /* Setting up Feedback command to read analog input */ sendDataBuff[0] = 1; //IOType is AIN settling = (Settling != 0) ? 1 : 0; quicksample = (Resolution != 0) ? 1 : 0; sendDataBuff[1] = (uint8)ChannelP + settling*64 + quicksample*128; //Positive channel (bits 0-4), LongSettling (bit 6) //QuickSample (bit 7) sendDataBuff[2] = (uint8)ChannelN; //Negative channel if (ehFeedback(Handle, sendDataBuff, 3, &Errorcode, &ErrorFrame, recDataBuff, 2) < 0) return -1; if (Errorcode) return (long)Errorcode; bytesVT = recDataBuff[0] + recDataBuff[1]*256; if (Binary != 0) { *Voltage = (double)bytesVT; } else { if (ChannelP == 30) { if (binaryToCalibratedAnalogTemperature(CalibrationInfo, bytesVT, Voltage) < 0) return -1; } else { if (hwver < 1.30) error = binaryToCalibratedAnalogVoltage(CalibrationInfo, (int)(*DAC1Enable), ChannelN, bytesVT, Voltage); else error = binaryToCalibratedAnalogVoltage_hw130(CalibrationInfo, ChannelP, ChannelN, bytesVT, Voltage); if (error < 0) 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(int socketFDA, int socketFDB, ue9CalibrationInfo *caliInfo) { uint8 *recBuff; double **voltages; int recChars, backLog, overflow, totalScans, ret; int i, k, m, packetCounter, currChannel, scanNumber; int totalPackets; //The total number of StreamData responses read uint16 voltageBytes, checksumTotal; int numDisplay; //Number of times to display streaming information int readSizeMultiplier; //Multiplier for the StreamData receive buffer size long startTime, endTime; packetCounter = 0; currChannel = 0; scanNumber = 0; totalPackets = 0; recChars = 0; numDisplay = 6; readSizeMultiplier = 120; ret = 0; /* Each StreamData response contains (16/NumChannels) * readSizeMultiplier * samples for each channel. * Total number of scans = (16 / NumChannels) * readSizeMultiplier * numDisplay */ totalScans = (16/NumChannels)*readSizeMultiplier*numDisplay; voltages = malloc(sizeof(double)*totalScans); for(i = 0; i < totalScans; i++) voltages[i] = malloc(sizeof(double)*NumChannels); recBuff = malloc(sizeof(uint8)*46*readSizeMultiplier); printf("Reading Samples...\n"); startTime = getTickCount(); for (i = 0; i < numDisplay; i++) { /* You can read the multiple StreamData responses of 46 bytes to help * improve throughput. In this example this multiple is adjusted by the * readSizeMultiplier variable. We may not read 46 * readSizeMultiplier * bytes per each recv call, but we will continue reading until we read * 46 * readSizeMultiplier bytes total. */ recChars = 0; for(k = 0; k < 46*readSizeMultiplier; k += recChars) { //Reading response from UE9 recChars = recv(socketFDB, recBuff + k, 46*readSizeMultiplier - k, 0); if(recChars == 0) { printf("Error : read failed (StreamData).\n"); ret = -1; goto cleanmem; } } overflow = 0; //Checking for errors and getting data out of each StreamData response for (m = 0; m < readSizeMultiplier; m++) { totalPackets++; checksumTotal = extendedChecksum16(recBuff + m*46, 46); if( (uint8)((checksumTotal / 256) & 0xff) != recBuff[m*46 + 5]) { printf("Error : read buffer has bad checksum16(MSB) (StreamData).\n"); ret = -1; goto cleanmem; } if( (uint8)(checksumTotal & 0xff) != recBuff[m*46 + 4]) { printf("Error : read buffer has bad checksum16(LBS) (StreamData).\n"); ret = -1; goto cleanmem; } checksumTotal = extendedChecksum8(recBuff + m*46); if( checksumTotal != recBuff[m*46]) { printf("Error : read buffer has bad checksum8 (StreamData).\n"); ret = -1; goto cleanmem; } if( recBuff[m*46 + 1] != (uint8)(0xF9) || recBuff[m*46 + 2] != (uint8)(0x14) || recBuff[m*46 + 3] != (uint8)(0xC0) ) { printf("Error : read buffer has wrong command bytes (StreamData).\n"); ret = -1; goto cleanmem; } if(recBuff[m*46 + 11] != 0) { printf("Errorcode # %d from StreamData read.\n", (unsigned int)recBuff[11]); ret = -1; goto cleanmem; } if(packetCounter != (int)recBuff[m*46 + 10]) { printf("PacketCounter (%d) does not match with with current packet count (%d) (StreamData).\n", packetCounter, (int)recBuff[m*46 + 10]); ret = -1; goto cleanmem; } backLog = recBuff[m*46 + 45] & 0x7F; //Checking MSB for Comm buffer overflow if( (recBuff[m*46 + 45] & 128) == 128) { printf("\nComm buffer overflow detected in packet %d\n", totalPackets); printf("Current Comm backlog: %d\n", recBuff[m*46 + 45] & 0x7F); overflow = 1; } for(k = 12; k < 43; k += 2) { voltageBytes = (uint16)recBuff[m*46 + k] + (uint16)recBuff[m*46 + k+1] * 256; binaryToCalibratedAnalogVoltage(caliInfo, (uint8)(0x00), ainResolution, voltageBytes, &(voltages[scanNumber][currChannel])); currChannel++; if(currChannel > 3) { currChannel = 0; scanNumber++; } } if(packetCounter >= 255) packetCounter = 0; else packetCounter++; //Handle Comm buffer overflow by stopping, flushing and restarting stream if(overflow == 1) { printf("\nRestarting stream...\n"); doFlush(socketFDA); closeTCPConnection(socketFDB); if( (socketFDB = openTCPConnection(ipAddress, ue9_portB)) < 0) goto cleanmem; if(StreamConfig_example(socketFDA) != 0) { printf("Error restarting StreamConfig.\n"); ret = -1; goto cleanmem; } if(StreamStart(socketFDA) != 0) { printf("Error restarting StreamStart.\n"); ret = -1; goto cleanmem; } packetCounter = 0; break; } } 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 Comm backlog: %d\n", backLog); for(k = 0; k < 4; 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)); cleanmem: free(recBuff); recBuff = NULL; for(i = 0; i < totalScans; i++) { free(voltages[i]); voltages[i] = NULL; } free(voltages); voltages = NULL; return ret; }