#include #include /* memset */ #include /* sin */ #include #include "dac.h" #define SIZE 500 static const int DAC = 1; static const int DAC_LOWER = -2048; static const int DAC_HIGHER = 2047; static const int DAC_WARNING = 256; static const int ADC = 1; static const int TIME_LOWER = 40; /* us */ static const int ITER_LOWER = 1; static const char *DATA = "experiment.data"; static const char *GNUP = "experiment.gnu"; static const char *GNU = "gnuplot -persist"; int plot() { FILE *fp_gnup; FILE *gnu; /* open .gnu */ if(!(fp_gnup = fopen(GNUP, "w"))) { perror(GNUP); return 0; } fprintf(fp_gnup, "set xlabel 'Time (s)'\n"); fprintf(fp_gnup, "set ylabel 'Volts (V)'\n"); fprintf(fp_gnup, "plot \\\n"); fprintf(fp_gnup, "'%s' using 1:3 title 'Output' with points\n", DATA); /* close .gnu */ if(!(fclose(fp_gnup))) { perror(GNUP); } /* open gnuplot */ if(!(gnu = popen(GNU, "w"))) { perror(GNU); return 0; } fprintf(gnu, "load '%s'\n", GNUP); /* close gnuplot */ if(!(fclose(gnu))) { perror(GNU); } return -1; } int main(int argc, char **argv) { int i, iter; int T = 100, iterations = 8; int out[SIZE]; double in[SIZE], adc; FILE *fp_data; /* command line: period */ if(argc > 1) sscanf(argv[1], "%d", &T); if(T < TIME_LOWER) { fprintf(stderr, "Period lower bound: %d us corrected to %d us.\n", T, TIME_LOWER); T = TIME_LOWER; } /* command line: iterations */ if(argc > 2) sscanf(argv[2], "%d", &iterations); if(iterations < ITER_LOWER) { fprintf(stderr, "Iterations lower bound: %d corrected to %d.\n", iterations, ITER_LOWER); iterations = ITER_LOWER; } /* open .data */ if(!(fp_data = fopen(DATA, "w"))) { perror(DATA); return 1; } /* set up LUT */ /* for(i = 0; i < SIZE; i++) out[i] = (i & 1) ? DAC_LOWER : DAC_HIGHER; */ for(i = 0; i < SIZE; i++) out[i] = ((double)(256 + 128) * sin((i / (double)SIZE) * 2 * M_PI)) - 570; fprintf(stderr, "Initalising LabMaster!\n"); labmaster_initialize(); fprintf(stderr, "Writing %dus to the timeout function.\n", T); write_am9513_command(DISARM_COUNTERS | COUNTER_5); mode_D(5, SOURCE_F1, OUTPUT_TC_PULSE_HIGH, COUNT_DOWN); write_counter_load(5, T); write_am9513_command(LOAD_AND_ARM_COUNTERS | COUNTER_5); fprintf(stderr, "ADC enabling external start.\n"); adc_enable_external_start(); /* the DAC lags when starting up one, maybe two times, no idea why */ fprintf(stderr, "Clearing the DAC.\n"); for(iter = 0; iter < 4; iter++) { out_dac(DAC, out[0]); adc = in_adc(ADC); } fprintf(stderr, "Doing experiment %d times: <", iterations); for(iter = 0; iter < iterations; iter++) { fprintf(stderr, "|"); /* clear */ for(i = 0; i < SIZE; i++) { out_dac(DAC, out[i]); adc = in_adc(ADC); /* DEBUG: crash and burn */ /* actually, we do'n't really care where it came from */ /* if(out[i] < adc - DAC_WARNING || out[i] > adc + DAC_WARNING) fprintf(stderr, "%d: %g (%d) ", i, adc, out[i]); */ in[i] = in[i] * (iter / (double)(iter + 1)) + adc * (1 / (double)(iter + 1)); } } fprintf(stderr, ">.\n"); fprintf(stderr, "ADC disabling external start.\n"); adc_disable_external_start(); fprintf(stderr, "Terminating LabMaster.\n"); labmaster_terminate(); /* open .data */ if(!(fp_data = fopen(DATA, "w"))) { perror(DATA); return 1; } fprintf(fp_data, "# Caibration of DAC/ADC\n"); fprintf(fp_data, "# * = %dus, iterations %d\n", SIZE, T, SIZE * T, iterations); fprintf(fp_data, "# time (s)\tout (V)\tin (s)\n"); for(i = 0; i < SIZE; i++) fprintf(fp_data, "%g\t%g\t%g\n", i * T * 1e-6, a[1] + b[1] * (double)out[i], a[1] + b[1] * in[i]); /* close .data */ if(!fclose(fp_data)) { perror(DATA); } plot(); return 0; }