Subversion Repositories f9daq

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "../include/vxi11_x86_64/vxi11_user.h"
  6. #include "../include/daqscope.h"
  7. #include "../include/workstation.h"
  8.  
  9. CLINK *clink;
  10. char *savedIP;
  11. const char *allChans[8] = {"CH1","CH2","CH3","CH4","MATH1","MATH2","MATH3","MATH4"};
  12. const char *measType[11] = {"AMP","ARE","DEL","FALL","FREQ","MAX","MEAN","MINI","PK2P","PWI","RIS"};
  13. char *bbq;
  14.  
  15. // Query and command functions to simplify analysis --------------
  16. int vxi11_query(CLINK *clink, const char *mycmd)
  17. {
  18.    char buf[WAVE_LEN];
  19.    memset(buf, 0, WAVE_LEN);
  20.    vxi11_send(clink, mycmd);
  21.    int bytes_returned = vxi11_receive(clink, buf, WAVE_LEN);
  22.    if (bytes_returned > 0)
  23.    {
  24.       printf("%s\n", buf);
  25.    }
  26.    else if (bytes_returned == -15)
  27.       printf("*** [ NOTHING RECEIVED ] ***\n");
  28.  
  29.    return 0;
  30. }
  31.  
  32. void vxi11_command(CLINK *clink,char *mycmd)
  33. {
  34.    char buf[WAVE_LEN];
  35.    memset(buf, 0, WAVE_LEN);
  36.    vxi11_send(clink, mycmd);
  37. }
  38. // ---------------------------------------------------------------
  39.  
  40. // Tektronix unit conversion -------------------------------------
  41. double daqscope::tekunit(char *prefix)
  42. {
  43.    if (strcmp(prefix,"m")==0) return 0.001;
  44.    else if (strcmp(prefix,"u")==0) return 0.000001;
  45.    else if (strcmp(prefix,"n")==0) return 0.000000001;
  46.    else return 1;
  47. }
  48. // ---------------------------------------------------------------
  49.  
  50. // Connect to a scope through IP address IPaddr ------------------
  51. int daqscope::connect(char *IPaddr)
  52. {
  53.    int iTemp;
  54.    char buf[WAVE_LEN];
  55.    printf("daqscope::connect(%s)\n", IPaddr);
  56.    clink = new CLINK;
  57.    iTemp = vxi11_open_device(IPaddr, clink);
  58.    if(iTemp == 0)
  59.    {
  60.       vxi11_send(clink, "*IDN?");
  61.       vxi11_receive(clink, buf, WAVE_LEN);
  62.       printf("Connected to device (%s): %s\n", IPaddr, buf);
  63.       savedIP = IPaddr;
  64.       return iTemp;
  65.    }
  66.    else
  67.       return iTemp;
  68. }
  69. // ---------------------------------------------------------------
  70.  
  71. // Disconnect from scope with IP address IPaddr ------------------
  72. int daqscope::disconnect(char *IPaddr)
  73. {
  74.    int iTemp;
  75.    printf("daqscope::disconnect(%s)\n", IPaddr);
  76.    iTemp = vxi11_close_device(IPaddr, clink);
  77.    if(iTemp == 0)
  78.    {
  79.       printf("Disconnected from device (%s).\n", IPaddr);
  80.       delete clink;
  81.    }
  82.    return iTemp;
  83. }
  84. // ---------------------------------------------------------------
  85.  
  86. // Initialize the scope for waveform or measurement --------------
  87. int daqscope::init()
  88. {
  89.    int iTemp;
  90.    char cmd[512];
  91.    char cTemp[256];
  92.    printf("daqscope::init()\n");
  93.  
  94.    printf("Measurement type is: %d\n", scopeUseType);
  95.  
  96.    // For measurements, only one channel can be used (rise, fall, period,...)
  97.    if(scopeUseType == 2) scopeChanNr = 1;
  98.    printf("Nr. of channels selected: %d\n", scopeChanNr);
  99.  
  100.    // Only use scope if measurement is different than 0
  101.    if(scopeUseType == 0)
  102.       return 0;
  103.    else
  104.    {
  105.       // Combine all selected channels into a comma separated string
  106.       for(int i = 0; i < scopeChanNr; i++)
  107.       {
  108.          if(i == scopeChanNr-1)
  109.          {
  110.             if(i == 0) sprintf(scopeChanstring, "%s", allChans[scopeChans[i]]);
  111.             else sprintf(cTemp, "%s", allChans[scopeChans[i]]);
  112.          }
  113.          else
  114.          {
  115.             if(i == 0) sprintf(scopeChanstring, "%s,", allChans[scopeChans[i]]);
  116.             else sprintf(cTemp, "%s,", allChans[scopeChans[i]]);
  117.          }
  118.          if(i > 0)
  119.             strcat(scopeChanstring, cTemp);
  120.       }
  121.       printf("Selected channels: %s\n", scopeChanstring);
  122.  
  123.       // Check scope ID and turn the header display on
  124. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  125.       vxi11_query(clink, "*IDN?");
  126.       vxi11_command(clink,(char*)"HEADER ON");
  127. #else
  128.       printf("Identify Tek (*IDN?, HEADER ON)\n");
  129. #endif
  130.  
  131.       // Set the scope data sources
  132.       sprintf(cmd, "DATA:SOURCE %s", scopeChanstring);
  133. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  134.       vxi11_command(clink,cmd);
  135. #else
  136.       printf("Set data source (DATA:SOURCE): %s\n", cmd);
  137. #endif
  138.  
  139.       // Set to fast acquisition and set encoding
  140. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  141.       vxi11_command(clink,(char*)"FASTACQ:STATE 0");
  142.       vxi11_command(clink,(char*)"DATA:ENCDG SRIBINARY");
  143.       vxi11_command(clink,(char*)"WFMO:BYT_N 2");
  144.  
  145.       // Set gating (currently not used)
  146.       vxi11_command(clink,(char*)"GAT OFF");
  147. #else
  148.       printf("Set fastacq, encoding and gating (FASTACQ:STATE 0, DATA:ENCDG SRIBINARY, WFMO:BYT_N 2, MEASU:GAT OFF).\n");
  149. #endif
  150.  
  151.       // Check scale on each of selected channels (is this even needed?)
  152.       bbq = strtok(scopeChanstring,",");
  153.       while(bbq != NULL)
  154.       {
  155.          sprintf(cmd,"%s:SCALE?",bbq);
  156. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  157.          vxi11_query(clink,cmd);
  158. #else
  159.          printf("Return the scale of channel: %s\n", cmd);
  160. #endif
  161.          bbq = strtok(NULL, ",");
  162.       }
  163.  
  164.       // Check waveform and data options/settings
  165.       char buf[WAVE_LEN];
  166.       memset(buf, 0, WAVE_LEN);
  167. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  168.       vxi11_send(clink, "WFMO:WFID?");
  169.       iTemp = vxi11_receive(clink, buf, WAVE_LEN);
  170.       printf("Init out (length = %d): %s\n", iTemp, buf);
  171. #else
  172.       printf("Get acquisition parameters (WFMOUTPRE:WFID?).\n");
  173.       sprintf(buf, ":WFMOUTPRE:WFID \"Ch1, DC coupling, 20.0mV/div, 10.0ns/div, 500 points, Sample mode\"");
  174.       iTemp = strlen(buf);
  175. #endif
  176.       if (iTemp == -15)
  177.          printf("\n*** [ NOTHING RECEIVED ] ***\n");
  178.       else
  179.       {
  180.          bbq = strtok(buf,","); // break WFID out into substrings
  181.          for (int k = 0; k < 5; k++)
  182.          {
  183.             // info on voltage per division setting
  184.             if (k == 2)
  185.             {
  186.                memcpy(cTemp, &bbq[1], 5);
  187.                cTemp[5] = 0;
  188.                bbq[7] = 0;
  189.                tekvolt = atoi(cTemp)*tekunit(&bbq[6]);
  190.                printf("Voltage per division: %lf\n", tekvolt);
  191.             }
  192.             // info on time per division setting
  193.             if (k == 3)
  194.             {
  195.                memcpy(cTemp, &bbq[1], 5);
  196.                cTemp[5] = 0;
  197.                bbq[7] = 0;
  198.                tektime = atoi(cTemp)*tekunit(&bbq[6]);
  199.                printf("Time per division: %lf\n", tektime);
  200.             }
  201.             // info on last point to be transfered by CURVE?
  202.             if (k == 4)
  203.             {
  204.                bbq[strlen(bbq)-7] = 0;
  205.                sprintf(cmd, "DATA:STOP %d", atoi(bbq));
  206. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  207.                vxi11_command(clink, cmd);
  208. #else
  209.                printf("Stop data collection (DATA:STOP): %s\n", cmd);
  210. #endif
  211.             }
  212. //          printf("bbq = %s\n",bbq);
  213.             bbq = strtok (NULL, ",");
  214.          }
  215.       }
  216.  
  217.       // Recheck waveform and data options/settings, turn off header
  218. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  219.       vxi11_query(clink,"WFMO:WFID?");
  220.       vxi11_query(clink,"DATA?");
  221.       vxi11_command(clink,(char*)"HEADER OFF");
  222. #else
  223.       printf("Data format query (WFMOUTPRE:WFID?, DATA?, HEADER OFF).\n");
  224. #endif
  225.  
  226.       // Get the channel y-axis offset (only for one CH so far)
  227.       char posoff[WAVE_LEN];
  228. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  229.       sprintf(cmd, "%s:POS?", allChans[scopeChans[0]]);
  230.       vxi11_command(clink, cmd);
  231.       vxi11_receive(clink, posoff, WAVE_LEN);
  232.       choffset = (double)atof(posoff);
  233. #else
  234.       sprintf(posoff, "Just some temporary string info.");
  235.       printf("Check for channel position offset (CHx:POS?)\n");
  236. #endif
  237.  
  238.       // If measurements are to be performed
  239.       if(scopeUseType == 2)
  240.       {
  241.          sprintf(cmd, "MEASU:IMM:SOURCE1 %s", scopeChanstring);
  242. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  243.          vxi11_command(clink, cmd);
  244. #else
  245.          printf("Set immediate measurement source (MEASU:IMM:SOURCE1): %s\n", cmd);
  246. #endif
  247.  
  248.          sprintf(cmd, "MEASU:IMM:TYP %s", measType[scopeMeasSel]);
  249. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  250.          vxi11_command(clink, cmd);
  251. #else
  252.          printf("Set immediate measurement type (MEASU:IMM:TYP): %s\n", cmd);
  253. #endif
  254.       }
  255.  
  256.       return 0;
  257.    }
  258. }
  259. // ---------------------------------------------------------------
  260.  
  261. // Send a custom command to the scope ----------------------------
  262. int daqscope::customCommand(char *command, bool query, char *sReturn)
  263. {
  264.    if(query)
  265.    {
  266.       char buf[WAVE_LEN];
  267.       memset(buf, 0, WAVE_LEN);
  268.       vxi11_send(clink, command);
  269.       int bytes_returned = vxi11_receive(clink, buf, WAVE_LEN);
  270.       if (bytes_returned > 0)
  271.       {
  272.          printf("%s\n", buf);
  273.          sprintf(sReturn, "%s", buf);
  274.  
  275.          // For testing purposes
  276. /*       if( strcmp(command, "CURVE?") == 0 )
  277.          {
  278.             FILE *fp;
  279.             char tst[2];
  280.             fp = fopen("./curve_return.txt","w");
  281.             for(int i = 6; i < bytes_returned; i++)
  282.             {
  283.                if(i%2 == 1)
  284.                {
  285.                   tst[0] = buf[i];
  286.                   tst[1] = buf[i-1];
  287.                   fprintf(fp, "bytes returned = %d\tbyte %d = %d\treturn = %s\n", bytes_returned, i, buf[i], tst);
  288.                }
  289.                else
  290.                   fprintf(fp, "bytes returned = %d\tbyte %d = %d\n", bytes_returned, i, buf[i]);
  291.             }
  292.             fclose(fp);
  293.          }*/
  294.       }
  295.       else if (bytes_returned == -15)
  296.       {
  297.          printf("*** [ NOTHING RECEIVED ] ***\n");
  298.          sprintf(sReturn, "*** [ NOTHING RECEIVED ] ***");
  299.       }
  300.    }
  301.    else
  302.    {
  303.       vxi11_command(clink, command);
  304.       sprintf(sReturn, "*** [ COMMAND NOT QUERY - NO RETURN ] ***");
  305.    }
  306.  
  307.    return 0;
  308. }
  309. // ---------------------------------------------------------------
  310.  
  311. // Get a measuring event (either waveform or measure) ------------
  312. int daqscope::lockunlock(bool lockit)
  313. {
  314.    // Lock the scope front panel for measurements
  315.    if(lockit)
  316.    {
  317. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  318.       vxi11_command(clink,(char*)"LOCK ALL");
  319.       return 0;
  320. #else
  321. //      printf("Locking the front panel (LOCK ALL).\n");
  322.       return -1;
  323. #endif
  324.    }
  325.    // Unlock the scope front panel after measurements
  326.    else
  327.    {
  328. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  329.       vxi11_command(clink,(char*)"LOCK NONE");
  330.       return 0;
  331. #else
  332. //      printf("Unlocking the front panel (LOCK ALL).\n");
  333.       return -1;
  334. #endif
  335.    }
  336. }
  337. // ---------------------------------------------------------------
  338.  
  339. // Get a measuring event (either waveform or measure) ------------
  340. int daqscope::event()
  341. {
  342.    int bytes_returned;
  343.  
  344.    if(scopeUseType == 0)
  345.       return -1;
  346.    else if(scopeUseType == 1)
  347.    {
  348. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  349.       memset(eventbuf, 0, WAVE_LEN);
  350.       vxi11_send(clink, "CURVE?");
  351.       bytes_returned = vxi11_receive(clink, eventbuf, WAVE_LEN);
  352. #else
  353.       printf("Ask to return the waveform (CURVE?)\n");
  354.       bytes_returned = 0;
  355. #endif
  356.  
  357.       if(bytes_returned > 0) return 0;
  358.       else return -1;
  359.    }
  360.    else if(scopeUseType == 2)
  361.    {
  362. #if WORKSTAT == 'I' || WORKSTAT == 'S'
  363.       char buf[WAVE_LEN];
  364.       memset(buf, 0, WAVE_LEN);
  365.       vxi11_send(clink, "MEASU:IMMED:VALUE?");
  366.       bytes_returned = vxi11_receive(clink, buf, WAVE_LEN);
  367.       measubuf = (double)atof(buf);
  368. #else
  369. //      printf("Ask to return the measurement (MEASU:IMMED:VALUE?)\n");
  370.       bytes_returned = 0;
  371.       measubuf = (double)rand()/(double)RAND_MAX;
  372. #endif
  373.  
  374.       if(bytes_returned > 0) return 0;
  375.       else return -1;
  376.    }
  377.    else
  378.       return -1;
  379. }
  380. // ---------------------------------------------------------------
  381.  
  382. // daqscope class constructor and destructor ---------------------
  383. daqscope::daqscope() {
  384.    fStop=0;
  385. }
  386.  
  387. daqscope::~daqscope() {
  388.    disconnect(savedIP);
  389. }
  390. // ---------------------------------------------------------------
  391.