/* Simple Read-Only example to read an 8 byte frame from the HP 3490A DVM To build use the following gcc statement (assuming you have the d2xx library in the /usr/local/lib directory). gcc -o simple main.c -L. -lftd2xx -Wl,-rpath /usr/local/lib Rev. 11-Jan-2020 The Serial Number of the ft245r on this HP-3490A is: FTC8MGZF. This version is for the HP-3490A DVM. */ #include #include #include #include #include #include #include "ftd2xx.h" int main() { /* Declare the variables and structures in this program. */ char ft_dev_SN[20] = "FTC8MGZF"; // ft245r device USB serial number unsigned char ReadBuffer[256]; DWORD dwRxSize = 0; DWORD dwBytesPerFrame = 8; DWORD dwBytesRead; FT_STATUS ftStatus; FT_HANDLE ftHandle; int queueChecks = 0; int check_for_error = 0; int usb_reset_counts = 0; int dvm_data_frame_errors = 0; int dvm_read_attempts = 0; long int timeout = 5; // timeout in seconds struct timeval run_start_time; // start of this data collection run struct timeval start_time; // start of the Queue Check Timeout struct timeval now_time; struct timeval elapsed_time; int Sample_Index = 1; int Number_of_Samples_Collected = 0; int Required_Number_of_Samples = 10; double This_DVM_Reading = 0.0; double DVM_Reads[50005]; // Maximum number of Samples in a Run. /* Declare the functions that are called by this program. */ int dumpBuffer(unsigned char *buffer, int elements); double Volts_from_Buffer(unsigned char *buffer); int Check_DVM_Frame(unsigned char *buffer); int min_max_locate(double *DVM_Reads, int Required_Number_of_Samples); int calc_DC_and_RMSs(double *DVM_Reads, int Required_Number_of_Samples); /* Zero the array that holds the DVM Samples. */ Sample_Index = 0; while (Sample_Index <= 50000) { DVM_Reads[Sample_Index] = 0.0; ++Sample_Index; } Sample_Index = 1; printf("\n The DVM Sample Storage Array has been zeroed. \n\n"); /* Ask the operator how many DVM Samples they want to collect in this run. */ printf(" Enter the number of DVM Samples, \n"); printf(" 50,000 maximum - or about 14 hrs at 1 per second, \n"); printf(" that you want to collect in this run: "); scanf( "%d", &Required_Number_of_Samples); printf("\n"); /* Advertize the USB Serial Number of the DVM's ft245r interface. */ printf("\n The USB Serial Number of the DVM's FT245R is - %s\n", ft_dev_SN); /* Open the ft245r device with the serial number = ft_dev_SN. */ if((ftStatus = FT_OpenEx(ft_dev_SN, FT_OPEN_BY_SERIAL_NUMBER, &ftHandle)) != FT_OK){ /* This can fail if the ftdi_sio driver is loaded use lsmod to check this and rmmod ftdi_sio to remove also rmmod usbserial */ printf("Error FT_OpenEx(%d)\n", (int)ftStatus); printf("Use lsmod to check if ftdi_sio (and usbserial) are present.\n"); printf("Unload them using rmmod ftdi_sio as they conflict with ftd2xx.\n"); return 1; } printf(" Opened USB Device - %s\n\n", ft_dev_SN); /* Get the time at the start of this DVM data collection run. */ gettimeofday(&run_start_time, NULL); /* Start the loop that collects the Required Number of DVM Samples */ while (Sample_Index <= Required_Number_of_Samples) { printf("\n\n Starting Read Loop Number = %d\n\n", Sample_Index); /* Check the ft245 Queue Status and wait 8 bytes */ /* of read data. Give up if this takes too long. */ Restart_Queue_Check: dwRxSize = 0; gettimeofday(&start_time, NULL); for (queueChecks = 1; dwRxSize < dwBytesPerFrame; queueChecks++) { /* Delay for 100 msec before the First check of the */ /* Queue Status and between checks of Queue Status. */ usleep(100000); ftStatus = FT_GetQueueStatus(ftHandle, &dwRxSize); if (ftStatus != FT_OK) { printf("\nFT_GetQueueStatus failed (%d).\n", (int)ftStatus); return 1; } /* Check for time-out in getting data as shown by Queue Status. */ gettimeofday(&now_time, NULL); timersub(&now_time, &start_time, &elapsed_time); if (elapsed_time.tv_sec > timeout) { /* We've waited too long. Give up. */ printf("\n\07 Queue check timed out after %ld seconds\n", elapsed_time.tv_sec); printf(" queue check count = %d \n\n", queueChecks); printf(" Bytes in Read FIFO reported by Queue Check = %d \n\n", dwRxSize); printf(" Try Close - Open the ft245r and then checking the Queue again.\n\n"); FT_Close(ftHandle); sleep(1); ftStatus = FT_OpenEx(ft_dev_SN, FT_OPEN_BY_SERIAL_NUMBER, &ftHandle); if (ftStatus != FT_OK) { printf("\n Queue error recovery by FT_Open failed - exiting now.\n\n"); return 1; } printf(" FT Close-Open has been done - Restart the Check Queue loop.\n\n"); ++usb_reset_counts; // Increment the counter of USB Resets. goto Restart_Queue_Check; } } printf(" queue check count = %d \n\n", queueChecks); /* If we get here then the above Queue Status test has */ /* derermined that there are 8 bytes in the Read Queue. */ if(ftStatus == FT_OK) { ftStatus = FT_Read(ftHandle, ReadBuffer, dwRxSize, &dwBytesRead); if (ftStatus != FT_OK) { printf("Error FT_Read(%d)\n", (int)ftStatus); return 1; } if (dwBytesRead != dwRxSize) { printf("FT_Read only read %d (of %d) bytes\n", (int)dwBytesRead, (int)dwRxSize); return 1; } ++dvm_read_attempts; printf(" FT_Read read %d bytes. Read-buffer currently holds:\n\n", (int)dwBytesRead); dumpBuffer(ReadBuffer, (int)dwBytesRead); check_for_error = Check_DVM_Frame(ReadBuffer); if (check_for_error != 0) { ++dvm_data_frame_errors; } This_DVM_Reading = Volts_from_Buffer(ReadBuffer); if (check_for_error == 0) { DVM_Reads[Sample_Index] = This_DVM_Reading; ++Sample_Index; } } } /* */ /* The required number of DVM samples have been collected. */ /* Now call the Analysis Functions */ /* */ /* Note that I'm passing to the analysis routines the */ /* actual number of samples that were collected (not the */ /* desired number that we would like to collect). */ /* */ /* Before calling the analysis routines first report */ /* how long this run actually took in seconds and how */ /* DVM samples were actually collected */ /* */ gettimeofday(&now_time, NULL); timersub(&now_time, &run_start_time, &elapsed_time); printf("\n This DVM data collection run took %ld seconds\n", elapsed_time.tv_sec); Number_of_Samples_Collected = --Sample_Index; printf(" Number of DVM samples actually collected = %d \n", Number_of_Samples_Collected); printf(" Number of DVM read attempts = %d \n", dvm_read_attempts ); printf(" Number of DVM Data Frame Errors = %d \n", dvm_data_frame_errors ); printf(" Number of USB Resets = %d \n", usb_reset_counts ); min_max_locate(DVM_Reads, Number_of_Samples_Collected); calc_DC_and_RMSs(DVM_Reads, Number_of_Samples_Collected); /* Cleanup before exiting */ FT_Close(ftHandle); printf(" Closed USB Device - %s\n\n", ft_dev_SN); return 0; /* This ends the main function */ }