home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 26 / CD_ASCQ_26_1295.iso / vrac / fluke13.zip / FLUKECOM.ASP < prev    next >
Text File  |  1995-08-31  |  34KB  |  1,417 lines

  1. ; Simple program to allow one to take control of the Fluke Scopemeter 97.
  2. ; This source and all associated files are Copyright 1995 of John L. Groezinger.
  3. ; Comments may be sent to jlgroezinger@mmm.com
  4.  
  5. ; V1.0, 5/24/95, jlg, original version
  6.  
  7. ; V1.1, 6/22/95, jlg 
  8. ; added much more information in flukecom.hlp file
  9. ; added default of *.* to dir command
  10. ; fixed null write file problem when sending strings to a disk file with
  11. ; the fputs command to write binary data to disk.  Used the fwrite command.
  12. ; fixed a missing error message in makecsv to indicated if the .dat file
  13. ; did not have enough data in it. Added the init command. Moved the 
  14. ; version string to the header file.
  15.  
  16. ; V1.2, 6/30/95, jlg 
  17. ; fixed type in help file
  18. ; changed version string
  19. ; removed extraneous code from getmeter in flukeint.asp
  20. ; speeded up the autobaud procedure significantly
  21. ; added optional parameter to timestamp command to timestamp to a file
  22. ; added additional documentation to makecsv
  23. ; changed error returns in makecsv to 1 for error, 0 for ok
  24. ; put some minor tweaks in getmeter to (hopefully) inmprove speed (sub'd
  25. ; key2ascii for strfmt)
  26. ; added the get/put <filename> command to get/save current configuration
  27. ; added the profile.mac feature
  28.  
  29. ; V1.3, 8/30/95, jlg
  30. ; found bug in the get_array routine, would not operate correctly if data
  31. ; was null.
  32.  
  33. ; Notes for future improvements:
  34. ;
  35. ; 1) Could do further attempts at serial connections including additional
  36. ; baud rates, attempts with nonzero ack connection, parity enabled, and
  37. ; 7 data bits, xon/xoff.
  38. ;
  39. ; 2) Add features to store currently used values which have been modified
  40. ; as part of the initialization sequence. Guess again, if we have space
  41. ; this requires the use of storing the variables and using this to send
  42. ; the commands, you cannot just use the variables as part of the setup
  43. ; sequence,     if (init_aspdebug)
  44. ;            set aspdebug on
  45. ;        else
  46. ;            set aspdebug off
  47. ;        endif
  48. ; Create a read and write file function which would allow you to save and
  49. ; restore the current settings of pcplus to a file and then use a case
  50. ; switch statement to parse out the resulting savings to restore the 
  51. ; current configuration.
  52. ;
  53. ; 3) Should increase error checking on number of parameters, for instance
  54. ; additional parameters on copy command are simply ignored, should be parsed
  55. ; and complained about.  But then again, this is handy for comments....
  56. ;
  57. ; 4) Add setup and restore setup functions to meter much more gracefully
  58. ; than the current numeric.
  59. ;
  60. ; 5) A filename which is entered which is too long is simply truncated
  61. ; with no error indication
  62. ; 6) The check_range routine can easily be fooled by putting in any
  63. ; nonnumeric value, it will return zero.  This is also true about the ifgoto
  64. ; command which will use a non-numeric or non-present value as zero
  65. ;
  66. ; 7) Break script up into several subscripts which use up less at a time
  67. ; 9) one could envision several extensions to this which would include
  68. ; a more sophisticated loop capability (additional loops or labels) and
  69. ; shell variables.  We'll see.....
  70. ;
  71. ; 10) if a disk write error occurs and disk logging is occuring, then 
  72. ; the user will get two write errors, once for the command and a second for 
  73. ; the disk log.
  74. ;
  75. ; 11) Look into ways to reduce the time to read from meter to PC
  76. ;
  77. ; 12) Put common routines in a header file.  However, when I tried this,
  78. ; I got runtime errors.
  79.  
  80. ; globals
  81.  
  82. string    bigresp1        ; all the waveform response strings
  83. string    bigresp2,bigresp3,bigresp4,bigresp5,bigresp6,bigresp7
  84. integer    bigpointer        ; pointer into string
  85. integer    bigstring        ; which string
  86.  
  87. integer    macroflag        ; indicates if in macro mode or not
  88. long    macropos        ; current location in macro file for loop
  89. integer    logflag            ; is logging on?
  90.  
  91. ; values from meter structure
  92. string id,yunit,xunit        ; channel name, x and y units
  93. float yzero,xzero,ydelta,xdelta ; scale information
  94. integer ylevel,xsample        ; number points and resolution
  95.  
  96. ; user string is left here in parsed out form
  97. string cmd1,cmd2,cmd3,cmd4
  98.  
  99. include "flukecom.h"
  100.  
  101. proc main
  102.     integer reterror
  103.     string retstr
  104.     string tmpstr
  105.     integer tmplen        ; temp variable 
  106.     integer hourwait, minwait ; for clock function
  107.     float readvalue        ; value from last read operation
  108.     float mingoto, maxgoto    ; current tests for ifgoto command
  109.     long looppos        ; location to loop back to for loop 
  110.     long loopcount        ; current count in loop
  111.     long tmplong        ; used for whatever
  112.     integer retack, terminator ; used for "put" command
  113.  
  114.     looppos = 0        ; always start loop at zero
  115.     readvalue = 0.0        ; read is at zero
  116.     macroflag = 0
  117.     logflag = 0        ; no logging
  118.     loopcount = 1        ; set loop counter at zero
  119.  
  120.     ; look for profile.asp
  121.     fopen macroindex "profile.mac" "rb"
  122.     if success
  123.         macroflag = 1
  124.     endif
  125.     
  126.     while forever
  127.         call get_cmd
  128.         switch cmd1
  129.  
  130.         ; commands with 1 second pause
  131.         case "default"
  132.             tmpstr = "ds"
  133.             goto jump1here
  134.         case "autosetup"
  135.             tmpstr = "as"
  136.             call send2meter with tmpstr,&reterror,longtimeout
  137.             goto jump2here
  138.         case "reset"
  139.             tmpstr = "ri"
  140.     jump1here:
  141.             call send2meter with tmpstr,&reterror,normal
  142.     jump2here:
  143.             if reterror
  144.                 call write_user with "ERROR: reset not done"
  145.                 loopwhile
  146.             endif
  147.             pause 1
  148.         endcase
  149.  
  150.         ; file logging commands
  151.         case "logon"
  152.             fopen logindex cmd2 "wb"
  153.             if failure
  154.                 strfmt tmpstr "ERROR: cannot write %s" cmd2
  155.                 call write_user with tmpstr
  156.                 loopwhile
  157.             endif
  158.             logflag = 1
  159.         endcase
  160.         case "logoff"
  161.             fclose logindex
  162.             logflag = 0
  163.         endcase
  164.  
  165.         ; generic single line commands
  166.         case "local"
  167.             tmpstr = "gl"
  168.             goto jumphere
  169.         case "remote"
  170.             tmpstr = "gr"
  171.             goto jumphere
  172.         case "lockout"
  173.             tmpstr = "ll"
  174.             goto jumphere
  175.         case "trigger"
  176.             tmpstr = "ta"
  177.             goto jumphere
  178.         case "arm"
  179.             tmpstr = "at"
  180.             goto jumphere
  181.         case "recall"
  182.             strfmt tmpstr "rs %s" cmd2
  183.             goto jumphere
  184.         case "save"
  185.             strfmt tmpstr "ss %s" cmd2
  186.     jumphere:
  187.             call send2meter with tmpstr,&reterror,normal
  188.             if reterror
  189.                 call write_user with "ERROR: meter not ready"
  190.             endif
  191.         endcase
  192.  
  193.         case "loop"
  194.             looppos = macropos
  195.         endcase
  196.  
  197.         case ":"
  198.         endcase
  199.  
  200.         case "put"
  201.             ; open up the file
  202.             fopen readindex cmd2 "rb"
  203.             if failure
  204.                 strfmt tmpstr "ERROR: cannot open %s" cmd2
  205.                 call write_user with tmpstr
  206.                 loopwhile
  207.             endif
  208.  
  209.             ; the following is a modified version  of send2meter
  210.             rflush        ; clean up anything that has been 
  211.                     ; received
  212.             transmit "ps"
  213.  
  214.             ; send the data string
  215.             fgets readindex tmpstr
  216.             eof readindex tmplen
  217.  
  218.             while !tmplen
  219.                 transmit tmpstr
  220.                 fgets readindex tmpstr
  221.                 eof readindex tmplen
  222.             endwhile
  223.  
  224.             ; close up the file
  225.             fclose readindex
  226.  
  227.             ; send the terminator
  228.             computc cret
  229.  
  230.             ; get the acknowledge
  231.             comgetcd retack
  232.             if retack == -1        ; timeout!
  233.                 call write_user with "ERROR: meter not ready"
  234.                 loopwhile
  235.             endif
  236.             comgetcd terminator    ; pitch the terminator
  237.             if terminator != cret    ; sync up problem or timeout
  238.                 call write_user with "ERROR: meter not ready"
  239.                 loopwhile
  240.             endif
  241.             if retack != '0'        ; check the ack code
  242.                 call write_user with "ERROR: meter not ready"
  243.                 loopwhile
  244.             endif
  245.         endcase
  246.  
  247.         case "get"
  248.             call send2meter with "qs",&reterror,normal
  249.             if reterror
  250.                 call write_user with "ERROR: meter not ready"
  251.                 loopwhile
  252.             endif
  253.  
  254.             ; open up the file
  255.             fopen readindex cmd2 "wb"
  256.             if failure
  257.                 strfmt tmpstr "ERROR: cannot open %s" cmd2
  258.                 call write_user with tmpstr
  259.                 loopwhile
  260.             endif
  261.  
  262.             ; get the first string and see if additional ones 
  263.             call getmeter with &retstr,&reterror,normal
  264.             fputs readindex retstr
  265.  
  266.             ; look for the extended strings
  267.             while (reterror == 1)
  268.                 call getmeter with &retstr,&reterror,normal
  269.                 fputs readindex retstr
  270.             endwhile
  271.  
  272.             ; close up the file
  273.             fputs readindex "`r`n"
  274.             fclose readindex
  275.         endcase
  276.  
  277.         case "read"
  278.             strfmt tmpstr "qm %s,v" cmd2
  279.             call send2meter with tmpstr,&reterror,normal
  280.             if reterror
  281.                 call write_user with "ERROR: meter not ready"
  282.                 loopwhile
  283.             endif
  284.             call getmeter with &retstr,&reterror,normal
  285.             if (reterror)
  286.                 call write_user with "ERROR: can't get measurement"
  287.                 loopwhile
  288.             endif
  289.             call write_user with retstr
  290.  
  291.             ; store the readvalue in a nonvolatile place
  292.             atof retstr readvalue
  293.  
  294.             ; if optional filename is present
  295.             strlen cmd3 tmplen
  296.             if (tmplen)
  297.                 fopen readindex cmd3 "ab"
  298.                 if failure
  299.                     strfmt tmpstr "ERROR: cannot open %s" cmd3
  300.                     call write_user with tmpstr
  301.                     loopwhile
  302.                 endif
  303.                 strfmt tmpstr "%s,%s,%e`r`n" $date $time1 readvalue
  304.                 fputs readindex tmpstr
  305.                 if (failure)
  306.                     call write_user with "ERROR: cannot write disk"
  307.                 endif
  308.                 fclose readindex
  309.             endif
  310.         endcase
  311.             
  312.         ; macro related commands
  313.         case "beep"
  314.             sound 1000 50
  315.         endcase
  316.         case "dir"
  317.             strlen cmd2 tmplen
  318.             if (!tmplen)
  319.                 cmd2 = "*.*"
  320.             endif
  321.             dir cmd2
  322.         endcase
  323.         case "shell"
  324.             shell
  325.         endcase
  326.         case "del"
  327.             delete cmd2
  328.             if failure
  329.                 strfmt tmpstr "ERROR: can't delete %s" cmd2
  330.                 call write_user with tmpstr
  331.             endif
  332.         endcase
  333.         case "ren"
  334.             rename cmd2 cmd3
  335.             if failure
  336.                 strfmt tmpstr "ERROR: can't rename %s to %s" cmd2 cmd3
  337.                 call write_user with tmpstr
  338.             endif
  339.         endcase
  340.         case "cd"
  341.             getfattr cmd2 tmpstr
  342.             if failure
  343.                 strfmt tmpstr "ERROR: no directory %s" cmd2
  344.                 call write_user with tmpstr
  345.                 loopwhile
  346.             endif
  347.             find tmpstr "D"
  348.             if not found
  349.                 strfmt tmpstr "ERROR: no directory %s" cmd2
  350.                 call write_user with tmpstr
  351.                 loopwhile
  352.             endif
  353.             chdir cmd2
  354.         endcase
  355.         case "type"
  356.             type cmd2
  357.         endcase
  358.         case "edit"
  359.             strfmt tmpstr "edit %s" cmd2
  360.             run tmpstr
  361.         endcase
  362.         case "rmdir"
  363.             rmdir cmd2
  364.             if failure
  365.                 call write_user with "ERROR: can't remove directory"
  366.             endif
  367.         endcase
  368.         case "mkdir"
  369.             mkdir cmd2
  370.             if failure
  371.                 call write_user with "ERROR: can't create directory"
  372.             endif
  373.         endcase
  374.         case "pwd"
  375.             getdir 0 tmpstr
  376.             call write_user with tmpstr
  377.         endcase
  378.         case "?"
  379.             type "flukecom.hlp"
  380.         endcase
  381.         case "play"
  382.             loopcount = 1
  383.             looppos = 0
  384.             strlen cmd2 tmplen
  385.             if (tmplen == 0)
  386.                 call write_user with "ERROR: no macro file"
  387.                 loopwhile
  388.             endif
  389.             fopen macroindex cmd2 "rb"
  390.             if failure
  391.                 strfmt tmpstr "ERROR: no macro file %s" cmd2
  392.                 call write_user with tmpstr
  393.                 loopwhile
  394.             endif
  395.             macroflag = 1
  396.         endcase
  397.         case "zero"
  398.             loopcount = 1
  399.         endcase
  400.         case "ifgoto"
  401.             atof cmd2 mingoto
  402.             atof cmd3 maxgoto
  403.             atol cmd4 tmplong
  404.             
  405.             ; check to see if inside limits
  406.             if (readvalue >= mingoto) && (readvalue <= maxgoto) && (macroflag) && ((loopcount < tmplong) || (tmplong <= 0))
  407.                 if (tmplong >= 0)
  408.                     loopcount++
  409.                 endif
  410.                 fseek macroindex looppos 0
  411.             endif
  412.         endcase
  413.         case "ifnotgoto"
  414.             atof cmd2 mingoto
  415.             atof cmd3 maxgoto
  416.             atol cmd4 tmplong
  417.             
  418.             ; check to see if inside limits
  419.             if ((readvalue < mingoto) || (readvalue > maxgoto)) && (macroflag) && ((loopcount < tmplong) || (tmplong <= 0))
  420.                 if (tmplong >= 0)
  421.                     loopcount++
  422.                 endif
  423.                 fseek macroindex looppos 0
  424.             endif
  425.         endcase
  426.         case "timestamp"
  427.             strfmt tmpstr "%s %s" $date $time1
  428.             call write_user with tmpstr
  429.  
  430.             ; if optional filename is present
  431.             strlen cmd2 tmplen
  432.             if (tmplen)
  433.                 fopen readindex cmd2 "ab"
  434.                 if failure
  435.                     strfmt tmpstr "ERROR: cannot open %s" cmd3
  436.                     call write_user with tmpstr
  437.                     loopwhile
  438.                 endif
  439.                 strfmt tmpstr "%s,%s`r`n" $date $time1 readvalue
  440.                 fputs readindex tmpstr
  441.                 if (failure)
  442.                     call write_user with "ERROR: cannot write disk"
  443.                 endif
  444.                 fclose readindex
  445.             endif
  446.         endcase
  447.         case "pause"
  448.             strlen cmd2 tmplen
  449.             if (tmplen == 0)
  450.                 call write_user with "ERROR: no delay"
  451.                 loopwhile
  452.             endif
  453.             atoi cmd2 tmplen
  454.             if (tmplen == 0)
  455.                 call write_user with "ERROR: illegal delay"
  456.                 loopwhile
  457.             endif
  458.             pause tmplen
  459.             if failure
  460.                 call write_user with "WARNING: aborted"
  461.             endif
  462.         endcase
  463.         case "clock+"
  464.             atoi cmd2 tmplen    ; get the user hour
  465.             time tmpstr 1        ; get the current time
  466.             atoi tmpstr hourwait    ; find the hour
  467.             hourwait = hourwait + tmplen
  468.             atoi cmd3 tmplen    ; get the user minute
  469.             substr retstr tmpstr 3 2
  470.             atoi retstr minwait
  471.             minwait = minwait + tmplen
  472.  
  473.             ; check for clock rollover
  474.             if (minwait >= 60)
  475.                 minwait = 0
  476.                 hourwait++
  477.             endif
  478.             if (hourwait >= 24)
  479.                 hourwait = 0
  480.             endif
  481.             suspend until hourwait minwait
  482.             if failure
  483.                 call write_user with "WARNING: aborted"
  484.             endif
  485.         endcase
  486.         case "clock"
  487.             call check_range with cmd2, 0, 23, &hourwait, &reterror
  488.             if reterror
  489.                 call write_user with "ERROR: illegal delay"
  490.                 loopwhile
  491.             endif
  492.             call check_range with cmd3, 0, 59, &minwait, &reterror
  493.             if reterror
  494.                 call write_user with "ERROR: illegal delay"
  495.                 loopwhile
  496.             endif
  497.             suspend until hourwait minwait
  498.             if failure
  499.                 call write_user with "WARNING: aborted"
  500.             endif
  501.         endcase
  502.         case "init"
  503.             if (logflag)
  504.                 fclose logindex
  505.                 logflag = 0
  506.             endif
  507.             execute "flukeint"
  508.         endcase
  509.         case "quit"
  510.             exitwhile
  511.         endcase
  512.  
  513.         case "version"
  514.             call write_user with versionstr
  515.             call send2meter with "id",&reterror,normal
  516.             if reterror
  517.                 call write_user with "ERROR: meter not ready"
  518.                 loopwhile
  519.             endif
  520.             call getmeter with &retstr,&reterror,normal
  521.             if (reterror)
  522.                 call write_user with "ERROR: can't get id from meter"
  523.                 loopwhile
  524.             endif
  525.             call write_user with retstr
  526.         endcase
  527.  
  528.         case "copy"
  529.             call copy_cmd
  530.         endcase
  531.  
  532.         case ""
  533.         endcase
  534.  
  535.         default
  536.             strfmt tmpstr "ERROR: command %s" cmd1
  537.             call write_user with tmpstr
  538.         endcase
  539.         endswitch
  540.     endwhile
  541.     execute "flukexit"
  542. endproc
  543.  
  544. ; for copy command from above, all parameters are handled with globals
  545. ; yeah, I know, live with it...
  546.  
  547. proc copy_cmd
  548.     integer wavenum, dwavenum
  549.     integer reterror
  550.  
  551.     ; for file naming
  552.     string basename, dbasename
  553.     string tmpstr
  554.  
  555.     ; look at the command string and figure out what to do
  556.     call wave_number with cmd2,&wavenum
  557.     call wave_number with cmd3,&dwavenum
  558.  
  559.     ; check for existence of command strings
  560.     strlen cmd2 reterror
  561.     if (!reterror)
  562.         call write_user with "ERROR: no source"
  563.         return
  564.     endif
  565.  
  566.     ; assume that this is a basename
  567.     basename = cmd2
  568.  
  569.     strlen cmd3 reterror
  570.     if (!reterror)
  571.         call write_user with "ERROR: no destination"
  572.         return
  573.     endif
  574.  
  575.     ; check for special case of datestamp
  576.  
  577.     strcmp cmd3 "datestamp"
  578.     if success
  579.         call make_date with &dbasename
  580.     else
  581.         dbasename = cmd3
  582.     endif
  583.  
  584.     ; please note that the basename and dbasename variables
  585.     ; are always set to the cmd2 and cmd3 respectively, regardless
  586.     ; of the actual operation.  For example, even if a keyword is
  587.     ; found as a source or destination, the cmd2 or cmd3 will
  588.     ; be used to set the value of basename/dbasename.  The only
  589.     ; exception to this is in the case of datestamp.  The wavenum
  590.     ; and dwavenum vars should be used to key the operation.  This
  591.     ; is a bit of a hack but most of this is.
  592.  
  593.     ; copy from meter to specified file
  594.     if (wavenum) && (!dwavenum)
  595.         call get_waveform with wavenum,&reterror
  596.         if (reterror)
  597.             call write_user with "ERROR: can't get meter data"
  598.             return
  599.         endif
  600.         call write_waveform with dbasename,&reterror
  601.         if (reterror)
  602.             call write_user with "ERROR: can't write to disk"
  603.             return
  604.         endif
  605.     endif
  606.  
  607.     ; copy from specified file to meter
  608.     if (!wavenum) && (dwavenum)
  609.         call read_waveform with basename,&reterror
  610.         if (reterror)
  611.             strfmt tmpstr "ERROR: can't read disk file %s" basename
  612.             call write_user with tmpstr
  613.             return
  614.         endif
  615.         call send_waveform with dwavenum,&reterror
  616.         if (reterror)
  617.             call write_user with "ERROR: can't write to meter"
  618.             return
  619.         endif
  620.     endif
  621.  
  622.     ; copy from meter to meter
  623.     if (wavenum) && (dwavenum)
  624.         call get_waveform with wavenum,&reterror
  625.         if (reterror)
  626.             call write_user with "ERROR: can't get meter data"
  627.             return
  628.         endif
  629.         call send_waveform with dwavenum,&reterror
  630.         if (reterror)
  631.             call write_user with "ERROR: can't write to meter"
  632.             return
  633.         endif
  634.     endif
  635.  
  636.     ; copy from file to file
  637.     if (!wavenum) && (!dwavenum)
  638.         call read_waveform with basename,&reterror
  639.         if (reterror)
  640.             strfmt tmpstr "ERROR: can't read disk file %s" basename
  641.             call write_user with tmpstr
  642.             return
  643.         endif
  644.         call write_waveform with dbasename,&reterror
  645.         if (reterror)
  646.             call write_user with "ERROR: can't write to disk"
  647.             return
  648.         endif
  649.     endif
  650. endproc
  651.  
  652. ; reads data from disk and pulls it into bigresp
  653. ; returns zero if ok, 2 if error
  654.  
  655. proc read_waveform
  656.     strparm basename    ; source basename
  657.     intparm restatus
  658.  
  659.     string tmpstr
  660.     integer reterror    ; std error return
  661.     
  662.     tmpstr = basename
  663.     strcat tmpstr ".dat"    ; get the binary data
  664.     fopen srcindex tmpstr "rb"
  665.     if failure
  666.         restatus = 2
  667.         return
  668.     endif
  669.     fread srcindex bigresp1 maxstrlen reterror
  670.     fread srcindex bigresp2 maxstrlen reterror
  671.     fread srcindex bigresp3 maxstrlen reterror
  672.     fread srcindex bigresp4 maxstrlen reterror
  673.     fread srcindex bigresp5 maxstrlen reterror
  674.     fread srcindex bigresp6 maxstrlen reterror
  675.     fread srcindex bigresp7 shortstrlen reterror
  676.     if (reterror != shortstrlen)
  677.         restatus = 2
  678.         return
  679.     endif
  680.  
  681.     ; get the header data
  682.     tmpstr = basename
  683.     strcat tmpstr ".hdr"    ; get the binary data
  684.     fopen srcindex tmpstr "rb"
  685.     if failure
  686.         restatus = 2
  687.         return
  688.     endif
  689.     fgets srcindex id
  690.     fgets srcindex xunit
  691.     fgets srcindex yunit
  692.     fgets srcindex tmpstr
  693.     atof tmpstr xzero
  694.     fgets srcindex tmpstr
  695.     atof tmpstr yzero
  696.     fgets srcindex tmpstr
  697.     atof tmpstr xdelta
  698.     fgets srcindex tmpstr
  699.     atof tmpstr ydelta
  700.     fgets srcindex tmpstr
  701.     atoi tmpstr xsample
  702.     fgets srcindex tmpstr
  703.     atoi tmpstr ylevel
  704.     fclose srcindex
  705.     restatus = 0
  706. endproc
  707.  
  708. ; takes data from bigresp variables and writes disk files
  709. ; returns zero if ok, 2 if error
  710.  
  711. proc write_waveform
  712.     strparm dbasename    ; destination basename
  713.     intparm restatus    ; return status
  714.  
  715.     string tmpstr
  716. comment
  717. ; this stuff is commented out because the csv file is created by an
  718. ; external c file
  719.     integer counter        ; pointer into arrays
  720.     integer reterror    ; return status from routines
  721.  
  722.     ; for calculations
  723.     float realx,realy
  724. endcomment
  725.  
  726.     ; make up the binary file
  727.     tmpstr = dbasename
  728.     strcat tmpstr ".dat"
  729.     fopen destindex tmpstr "wb"
  730.     if failure
  731.         restatus = 2
  732.         return
  733.     endif
  734.  
  735.     ; write all this binary stuff out
  736.     fwrite destindex bigresp1 maxstrlen
  737.     fwrite destindex bigresp2 maxstrlen
  738.     fwrite destindex bigresp3 maxstrlen
  739.     fwrite destindex bigresp4 maxstrlen
  740.     fwrite destindex bigresp5 maxstrlen
  741.     fwrite destindex bigresp6 maxstrlen
  742.     fwrite destindex bigresp7 shortstrlen
  743.     if failure
  744.         call write_user with "ERROR: cannot write disk"
  745.     endif
  746.     fclose destindex
  747.  
  748.     ; make up the hdr file
  749.     tmpstr = dbasename
  750.     strcat tmpstr ".hdr"
  751.     fopen destindex tmpstr "wb"
  752.     if failure
  753.         restatus = 2
  754.         return
  755.     endif
  756.     fstrfmt destindex "%s`r`n" id
  757.     fstrfmt destindex "%s`r`n" xunit
  758.     fstrfmt destindex "%s`r`n" yunit
  759.     fstrfmt destindex "%e Xzero`r`n" xzero
  760.     fstrfmt destindex "%e Yzero`r`n" yzero
  761.     fstrfmt destindex "%e Xdelta`r`n" xdelta
  762.     fstrfmt destindex "%e Ydelta`r`n" ydelta
  763.     fstrfmt destindex "%d Xsample`r`n" xsample
  764.     fstrfmt destindex "%d Ylevel`r`n" ylevel
  765.     if failure
  766.         call write_user with "ERROR: cannot write to disk"
  767.     endif
  768.     fclose destindex
  769.  
  770. comment
  771. ; all of this stuff is commented out since this runs way to slow
  772.     ; make up the csv file
  773.     tmpstr = dbasename
  774.     strcat tmpstr ".csv"
  775.     fopen destindex tmpstr "wb"
  776.     if failure
  777.         restatus = 2
  778.         return
  779.     endif
  780.  
  781.     ; create the csv strings
  782.     fstrfmt destindex "%s`r`n" dbasename
  783.     fstrfmt destindex "%s,%s`r`n" xunit yunit
  784.  
  785.     ; initialize the array fetching
  786.     call zero_array
  787.     counter = 0
  788.     call get_array with &reterror
  789.     while (reterror != -1)
  790.         realx = (counter * xdelta) + xzero
  791.         realy = ((reterror - 128) * ydelta) - yzero
  792.         fstrfmt destindex "%e,%e`r`n" realx realy
  793.         counter++
  794.         call get_array with &reterror
  795.     endwhile
  796.     fclose destindex
  797. endcomment
  798.     strfmt tmpstr "makecsv %s" dbasename
  799.     run tmpstr NOCLEAR
  800.     restatus = 0
  801. endproc
  802.  
  803. ; get data from bigresp variables and sends to meter
  804. ; returns zero if ok, 2 if error
  805.  
  806. proc send_waveform
  807.     intparm dwavenum
  808.     intparm restatus
  809.  
  810.     string tmpstr
  811.     integer reterror
  812.  
  813.     strfmt tmpstr "pw%d" dwavenum
  814.     call send2meter with tmpstr,&reterror,extended
  815.     if (reterror)
  816.         restatus = 2
  817.         return
  818.     endif
  819.     restatus = 0
  820. endproc
  821.  
  822. ; gets data from meter and puts into the bigresp variables
  823. ; returns zero if ok, 2 if error
  824.  
  825. proc get_waveform
  826.     intparm wavenum        ; keycode for waveform
  827.     intparm restatus    ; return code from operation
  828.  
  829.     integer counter        ; for parsing
  830.     string tmpstr
  831.     string retstr        ; return string from get operation
  832.     integer reterror    ; return from send2meter
  833.  
  834.     strfmt tmpstr "qw%d" wavenum
  835.     call send2meter with tmpstr,&reterror,normal
  836.     if (reterror)
  837.         restatus = 2
  838.         return
  839.     endif
  840.     call getmeter with &retstr,&reterror,extended
  841.     if (reterror)
  842.         restatus = 2
  843.         return
  844.     endif
  845.  
  846.     ; get the values from the response string
  847.     counter = 0
  848.     call parse_str with retstr,&id,&counter,commachar
  849.     call parse_str with retstr,&yunit,&counter,commachar
  850.     call parse_str with retstr,&xunit,&counter,commachar
  851.     call parse_str with retstr,&tmpstr,&counter,commachar
  852.     atof tmpstr yzero
  853.     call parse_str with retstr,&tmpstr,&counter,commachar
  854.     atof tmpstr xzero
  855.     call parse_str with retstr,&tmpstr,&counter,commachar
  856.     atof tmpstr ydelta
  857.     call parse_str with retstr,&tmpstr,&counter,commachar
  858.     atof tmpstr xdelta
  859.     call parse_str with retstr,&tmpstr,&counter,commachar
  860.     atoi tmpstr ylevel
  861.     call parse_str with retstr,&tmpstr,&counter,commachar
  862.     atoi tmpstr xsample
  863.     restatus = 0
  864. endproc
  865.  
  866. ; zero pointers into array
  867.  
  868. proc zero_array
  869.     bigpointer = 0
  870.     bigstring = 1
  871. endproc
  872.  
  873. ; gets value from array
  874.  
  875. proc get_array
  876.     intparm reterror
  877.  
  878.     integer    biglength        ; length of current string
  879.  
  880.     switch bigstring
  881.     case 1
  882.         strpeek bigresp1 bigpointer reterror
  883.         biglength = maxstrlen
  884.     endcase
  885.     case 2
  886.         strpeek bigresp2 bigpointer reterror
  887.         biglength = maxstrlen
  888.     endcase
  889.     case 3
  890.         strpeek bigresp3 bigpointer reterror
  891.         biglength = maxstrlen
  892.     endcase
  893.     case 4
  894.         strpeek bigresp4 bigpointer reterror
  895.         biglength = maxstrlen
  896.     endcase
  897.     case 5
  898.         strpeek bigresp5 bigpointer reterror
  899.         biglength = maxstrlen
  900.     endcase
  901.     case 6
  902.         strpeek bigresp6 bigpointer reterror
  903.         biglength = maxstrlen
  904.     endcase
  905.     case 7
  906.         strpeek bigresp7 bigpointer reterror
  907.         biglength = shortstrlen
  908.     endcase
  909.     default
  910.         reterror = -1
  911.         return
  912.     endcase
  913.     endswitch
  914.  
  915.     ; point to next item in array
  916.     bigpointer++
  917.  
  918.     ; clean up if necessary
  919.     if (bigpointer >= biglength)
  920.         bigpointer = 0
  921.         bigstring++ 
  922.     endif
  923. endproc
  924.  
  925. ; checks correct range of numeric value
  926. ; minval is lowest ok value 
  927. ; maxval is highest ok value
  928. ; returns value in integer,
  929. ; 0 error return indicates, ok, 2 indicates error
  930.  
  931. proc check_range
  932.     strparm instr
  933.     intparm minval, maxval
  934.     intparm value
  935.     intparm reterror
  936.  
  937.     integer strlength
  938.  
  939.     ; check for zero length string
  940.     strlen instr strlength
  941.     if (!strlength)
  942.         reterror = 2
  943.         return
  944.     endif
  945.  
  946.     ; convert the string
  947.     atoi instr value
  948.     if (value >= minval) && (value <= maxval)
  949.         reterror = 0
  950.         return
  951.     endif
  952.     reterror = 2
  953. endproc
  954.  
  955. ; create a string with date code
  956.  
  957. proc make_date
  958.     strparm outstr
  959.  
  960.     string tmpstr
  961.     string datestr
  962.     string timestr
  963.  
  964.     outstr = ""
  965.     date datestr                ; get appropo strings
  966.     time timestr 1    
  967.     substr tmpstr datestr 3 2        ; get the day
  968.     strcat outstr tmpstr
  969.     substr tmpstr timestr 0 2        ; get the hour
  970.     strcat outstr tmpstr
  971.     substr tmpstr timestr 3 2        ; get the minute
  972.     strcat outstr tmpstr
  973.     substr tmpstr timestr 6 2        ; get the second
  974.     strcat outstr tmpstr
  975. endproc
  976.  
  977. proc write_user
  978.     strparm outstr
  979.  
  980.     string tmpstr
  981.  
  982.     strfmt tmpstr "%s`r`n" outstr
  983.     message tmpstr
  984.     if (logflag)
  985.         fputs logindex tmpstr 
  986.         if failure
  987.             message "ERROR: cannot write to disk`r`n"
  988.         endif
  989.     endif
  990. endproc
  991.  
  992. proc nocr_write_user
  993.     strparm outstr
  994.  
  995.     message outstr
  996.     if (logflag)
  997.         fputs logindex outstr 
  998.         if failure
  999.             message "ERROR: cannot write to disk`r`n"
  1000.         endif
  1001.     endif
  1002. endproc
  1003.  
  1004. ; this routine is a general token parser which is intended to
  1005. ; look for the parsechar and return the current token from the
  1006. ; current location in the string up but not including the separator
  1007. ; It will return the token found into the string which is passed,
  1008. ; a null string is returned if no token is found or if end of the string
  1009. ; The variable pointer is used to offset from the beginning of the string
  1010. ; where to start the search and it is left at pointer at the first character
  1011. ; beyound the end of the string (string length)
  1012. ; or the first whitespace following the current token
  1013. ; Strings are based at 0 start
  1014. ; parsechar is used to determine the character to parse on
  1015.  
  1016. proc parse_str
  1017.     strparm    instr
  1018.     strparm outstr
  1019.     intparm pointer
  1020.     intparm parsechar
  1021.  
  1022.     integer lastchar
  1023.     integer currchar
  1024.     string currcharstr
  1025.  
  1026.     outstr = ""
  1027.  
  1028.     ; get the length of the string
  1029.     strlen instr lastchar
  1030.     if (!lastchar)
  1031.         return
  1032.     endif
  1033.  
  1034.     ; check if pointer is beyond end of string
  1035.     if (pointer >= lastchar)
  1036.         return
  1037.     endif
  1038.         
  1039.     strpeek instr pointer currchar
  1040.  
  1041.     ; strip off leading whitespace
  1042.     while (currchar == parsechar)
  1043.         pointer++
  1044.         if (pointer == lastchar)
  1045.             return
  1046.         endif
  1047.         strpeek instr pointer currchar
  1048.     endwhile
  1049.  
  1050.     ; find the next whitespace, this is token
  1051.     while (currchar != parsechar)
  1052.         key2ascii currchar currcharstr
  1053.         strcat outstr currcharstr
  1054.         pointer++
  1055.         if (pointer == lastchar)
  1056.             return
  1057.         endif
  1058.         strpeek instr pointer currchar
  1059.     endwhile
  1060. endproc
  1061.  
  1062. ; return error code
  1063. ; of 1 indicates an ack error existed on the receive
  1064. ; this is a warning that the ack code is incorrect
  1065. ; of 2 indicates a sync problem existed on the receive (or timeout)
  1066. ; this is a fatal
  1067. ; Response string must be handled separately.
  1068.  
  1069. proc send2meter
  1070.     strparm instr
  1071.     intparm reterror
  1072.     intparm    opcode
  1073.  
  1074.     string tmpstr
  1075.     integer retack            ; acknowledge byte
  1076.     integer terminator
  1077.     integer checksum
  1078.     integer counter            ; for long timeout tries
  1079.  
  1080.     rflush                ; clean up anything that has been 
  1081.                     ; received
  1082.     strfmt tmpstr "%s`r" instr    ; format up the data to send
  1083.     transmit tmpstr
  1084.  
  1085.     counter = 0
  1086.     comgetcd retack
  1087.     if (opcode == longtimeout) && (counter < longtimetries) && (retack == -1)
  1088.         comgetcd retack
  1089.         counter++
  1090.     endif
  1091.     if retack == -1            ; timeout!
  1092.         reterror = 2
  1093.         return
  1094.     endif
  1095.     comgetcd terminator        ; pitch the terminator
  1096.     if terminator != cret        ; sync up problem or timeout
  1097.         reterror = 2
  1098.         return
  1099.     endif
  1100.     if retack != '0'        ; check the ack code
  1101.         reterror = 1
  1102.         return
  1103.     endif
  1104.     ; is this an extended waveform operation
  1105.     if (opcode == extended)
  1106.         checksum = 0
  1107.         call zero_array
  1108.         call get_array with &retack
  1109.         while (retack != -1)
  1110.             checksum = checksum + retack
  1111.             computc retack
  1112.             call get_array with &retack
  1113.         endwhile
  1114.         checksum = checksum & 255
  1115.         computc checksum
  1116.  
  1117.         ; wait for the acknowledge byte
  1118.         comgetcd retack
  1119.         if retack == -1            ; timeout!
  1120.             reterror = 2
  1121.             return
  1122.         endif
  1123.         comgetcd terminator        ; pitch the terminator
  1124.         if terminator != cret        ; sync up problem or timeout
  1125.             reterror = 2
  1126.             return
  1127.         endif
  1128.         if retack != '0'        ; check the ack code
  1129.             reterror = 2
  1130.             return
  1131.         endif
  1132.     endif
  1133.     reterror = 0
  1134. endproc
  1135.  
  1136. ; this routine checks the input string and reduces it to the correct
  1137. ; waveform number
  1138. ; It requires the string to be sent with the ascii descripter and it
  1139. ; returns a value for the waveform number, 0 if not recognized.
  1140.  
  1141. proc wave_number
  1142.     strparm instr
  1143.     intparm reterror
  1144.  
  1145.     switch instr
  1146.     case "a"
  1147.         reterror = 101
  1148.     endcase
  1149.     case "b"
  1150.         reterror = 102
  1151.     endcase
  1152.     case "ab"
  1153.         reterror = 103
  1154.     endcase
  1155.     case "temp1"
  1156.         reterror = 104
  1157.     endcase
  1158.     case "temp2"
  1159.         reterror = 105
  1160.     endcase
  1161.     case "temp3"
  1162.         reterror = 106
  1163.     endcase
  1164.     case "memory4"
  1165.         reterror = 107
  1166.     endcase
  1167.     case "memory5"
  1168.         reterror = 108
  1169.     endcase
  1170.     case "memory6"
  1171.         reterror = 109
  1172.     endcase
  1173.     case "memory7"
  1174.         reterror = 110
  1175.     endcase
  1176.     case "memory8"
  1177.         reterror = 111
  1178.     endcase
  1179.     default
  1180.         reterror = 0
  1181.     endcase
  1182.     endswitch
  1183. endproc
  1184.  
  1185. ; get the next command
  1186.  
  1187. proc get_cmd
  1188.     string tmpstr            ; response string from get
  1189.     integer counter            ; position in string
  1190.  
  1191.     call nocr_write_user with "flukecom> "
  1192.  
  1193.     ; see if an esc or abort key was hit during operation
  1194.     if (hitkey)
  1195.         kflush
  1196.         if (macroflag)
  1197.             macroflag = 0
  1198.             fclose macroindex
  1199.         endif
  1200.     endif
  1201.     if (macroflag)
  1202.  
  1203.         ; get input from macro file
  1204.         fgets macroindex tmpstr
  1205.         ftell macroindex macropos    ; get pointer where to
  1206.                         ; starting from
  1207.         if success
  1208.  
  1209.             ; check for eof
  1210.             if eof macroindex
  1211.                 fclose macroindex
  1212.                 macroflag = 0
  1213.                 get tmpstr
  1214.                 ; aborted out with esc key
  1215.                 if (failure)
  1216.                     tmpstr = ""
  1217.                 endif
  1218.                 if (logflag)
  1219.                     fputs logindex tmpstr
  1220.                     if failure
  1221.                         call write_user with "ERROR: cannot write to disk"
  1222.                     endif
  1223.                 endif
  1224.                 call write_user with ""
  1225.             else
  1226.                 ; got the string ok
  1227.                 call write_user with tmpstr
  1228.             endif
  1229.         else
  1230.             ; end of file, clean up
  1231.             ; need some error indication here
  1232.             fclose macroindex
  1233.             macroflag = 0
  1234.             get tmpstr
  1235.             ; aborted out with esc key
  1236.             if (failure)
  1237.                 tmpstr = ""
  1238.             endif
  1239.             if (logflag)
  1240.                 fputs logindex tmpstr
  1241.                 if failure
  1242.                     call write_user with "ERROR: cannot write to disk"
  1243.                 endif
  1244.             endif
  1245.             call write_user with ""
  1246.         endif
  1247.     else
  1248.         ; normal user input
  1249.         get tmpstr
  1250.         ; aborted out with esc key
  1251.         if (failure)
  1252.             tmpstr = ""
  1253.         endif
  1254.         if (logflag)
  1255.             fputs logindex tmpstr
  1256.             if failure
  1257.                 call write_user with "ERROR: cannot write to disk"
  1258.             endif
  1259.         endif
  1260.         call write_user with ""
  1261.     endif
  1262.     strlwr tmpstr            ; convert to lower case
  1263.     counter = 0
  1264.     call parse_str with tmpstr,&cmd1,&counter,spacechar
  1265.     call parse_str with tmpstr,&cmd2,&counter,spacechar
  1266.     call parse_str with tmpstr,&cmd3,&counter,spacechar
  1267.     call parse_str with tmpstr,&cmd4,&counter,spacechar
  1268. endproc
  1269.  
  1270. ; this routine is an internally called routine from above
  1271. ; that is used to basically minimize the amount of recalled code
  1272. ;
  1273. ; It requires the user pass a string to concatenate onto
  1274. ; a pointer for the checksum integer
  1275. ; a value for the maximum number of characters to fetch
  1276. ; a pointer to an error return which will be 0 if success or 2 if not
  1277. ; Please note that the error return is checked, if an error value is
  1278. ; passed in, then the routine will abort
  1279.  
  1280. proc suck_em_up
  1281.     strparm outstr
  1282.     intparm checksum
  1283.     intparm maxget
  1284.     intparm reterror
  1285.  
  1286.     integer pointcount
  1287.     string tmpstr
  1288.     integer newchar
  1289.  
  1290.     ; check the error return
  1291.     if (reterror)
  1292.         return
  1293.     endif
  1294.  
  1295.     ; initialize the string and counter
  1296.     outstr = ""
  1297.     pointcount = 1
  1298.  
  1299.     ; get the first character
  1300.     comgetcd newchar
  1301.  
  1302.     while (newchar != -1)
  1303.         key2ascii newchar tmpstr    ; convert char to string
  1304.         strcat outstr tmpstr
  1305.         checksum = checksum + newchar
  1306.         pointcount++
  1307.         if (pointcount > maxget)
  1308.             reterror = 0
  1309.             return
  1310.         endif
  1311.         comgetcd newchar
  1312.     endwhile
  1313.  
  1314.     ; timeout condition
  1315.     reterror = 2
  1316. endproc
  1317.  
  1318. ; this routine gets the response string from the meter
  1319. ; If the response was succesful, then a string is returned and
  1320. ; of 0 indicates successful
  1321. ; of 1 indicates a continuation packet is pending
  1322. ; of 2 indicates a failure
  1323. ; NOTE THIS ROUTINE IS LIMITED TO 80 characters per string
  1324. ;
  1325. ; input parameter longgrab is normally set to zero for cret acquisition
  1326. ; If set to extended, then the routine will look for 8 commas, switch to the
  1327. ; getmeter_long routine to grab the samples, and verify the checksum
  1328.  
  1329. proc getmeter
  1330.     strparm outstr            ; string to return
  1331.     intparm reterror        ; error code to return
  1332.     intparm longgrab        ; operation code per above
  1333.  
  1334.     integer newchar            ; the latest character acquired
  1335.     string newcharstr        ; string version of the above
  1336.     integer    counter            ; length of the string to check for 
  1337.                     ; overflow of string
  1338.     integer commacount        ; number of commas in current string
  1339.                     ; used if longgrab = 1
  1340.  
  1341.     outstr = ""
  1342.     commacount = 0
  1343.     counter = 0
  1344.     comgetcd newchar
  1345.     while (newchar != -1) && (newchar != cret) && (commacount < maxcomma)
  1346.         key2ascii newchar newcharstr
  1347.         strcat outstr newcharstr
  1348.         counter++
  1349.  
  1350.         ; test to see if this is a implicit continuation string
  1351.         ; should never happen except when getting meter configuration
  1352.         if (counter >= maxstrlen)
  1353.             reterror = 1
  1354.             return
  1355.         endif
  1356.         if (newchar == ',') && (longgrab == extended)
  1357.             commacount++
  1358.         endif
  1359.         if (commacount != maxcomma)
  1360.             comgetcd newchar
  1361.         endif
  1362.     endwhile
  1363.     if (newchar == cret) && (longgrab == normal)
  1364.         reterror = 0
  1365.         return
  1366.     endif
  1367.     if (newchar == ',') && (longgrab == extended)
  1368.         ; call the long response handler
  1369.         call getmeter_long with &reterror
  1370.         return
  1371.     endif
  1372.     reterror = 2
  1373. endproc
  1374.  
  1375. ; this routine gets the waveform response
  1376. ; If the response was succesful, then a string is placed in the globals and
  1377. ; of 0 indicates successful
  1378. ; of 2 indicates a failure
  1379. ; NOTE THIS ROUTINE IS LIMITED TO 80 characters per string
  1380.  
  1381. proc getmeter_long
  1382.     intparm reterror        ; return error code
  1383.  
  1384.     integer newchar            ; current character being worked on
  1385.     integer checksum        ; calculated checksum
  1386.  
  1387.     ; initialize the checksum
  1388.     checksum = 0
  1389.     call suck_em_up with &bigresp1,&checksum,maxstrlen,&reterror
  1390.     call suck_em_up with &bigresp2,&checksum,maxstrlen,&reterror
  1391.     call suck_em_up with &bigresp3,&checksum,maxstrlen,&reterror
  1392.     call suck_em_up with &bigresp4,&checksum,maxstrlen,&reterror
  1393.     call suck_em_up with &bigresp5,&checksum,maxstrlen,&reterror
  1394.     call suck_em_up with &bigresp6,&checksum,maxstrlen,&reterror
  1395.     call suck_em_up with &bigresp7,&checksum,shortstrlen,&reterror
  1396.  
  1397.     if (reterror)
  1398.         return
  1399.     endif
  1400.  
  1401.     ; mask the checksum
  1402.     checksum = checksum & 255        
  1403.  
  1404.     ; check checksum
  1405.     comgetcd newchar
  1406.     if (newchar != checksum)
  1407.         reterror = 2
  1408.         return
  1409.     endif
  1410.  
  1411.     ; all ok
  1412.     reterror = 0
  1413. endproc
  1414.