NEW 102 $VER = "1.37" REM ========================================================================== REM PRINTMASTER REM REM Written by: Stephen J. Friedl REM Software Consultant REM 5/31/1995 REM REM This is the BASIC code for our Printmaster controller whose job it is REM to process encoder input and generate proper print-go signals to the REM Codebox. We will eventually be also talking to the motor controller REM too. REM REM HISTORY REM REM 1.37 (6/14/95) - now use PWM to generate a 25msec pulse REM REM 1.36 (6/12/95) - stretched the print-go timing a bit REM REM 1.35 - added proper reset handling for keypad resets, software reset REM does the same thing. Also show *RESET* on the display and disable REM interrupts so ONTICK and ONITR won't interfere. REM REM --------------------------------------------------------------------- REM TODO items: REM - consider gathering average temperature at ontick time (or at least) REM at IDLE time. REM - need a "print inhibit" signal that temporarily shuts down the motor REM and all that. REM REM --------------------------------------------------------------------- REM REM The Impresor software on the PC talks to this device via a protocol REM just like that of the Codebox, which makes the PC stuff easier. The REM format of this packet is: REM REM cmd {data...} REM REM where "cmd" is a single byte of data (usually a letter) and the data REM is in the printable ASCII character set. The data are optional if REM the command code describes everything useful. REM REM A x set print acks (0=no 1=yes) REM A ? query print ack status REM REM B 1 backlight on REM B 0 backlight off REM B ? backlight query REM REM C #### set encoder pulses per unit REM C ? query encoder pulses per unit REM REM D #### load value into counter REM D ? show current count REM REM E #### set limit feet REM E ? query current limit REM REM F #### set current feet displayed REM F ? show current foot count REM REM G go to tight loop - tests WDOG timer REM (no response to host) REM REM H xx set unit of measure (usually "ft" or "m") REM h ? query unit of measure REM REM I # after reaching limit, do what: 0=stop 1=repeat REM I ? REM REM J # issue print go at all? 1=yes 0=no REM J ? REM REM Spontaneous responses: REM REM a system has been reset REM b #### just issued print-go for unitmarker #### REM REM Negative Acknowlegements REM ------------------------ REM REM The NAK codes should not overlap those of the Codebox, but it is REM hard to predict what they will do. The normal format of these REM packets is ### where ### are three digits. We pick NAK REM codes in the range 100-199 which do not overlap with those of the REM Codebox. REM REM 100 got with no command REM 101 got non-printable characters in command REM 102 buffer overflow REM 103 timeout during packet assembly REM 104 bogus command code REM 105 bad value to backlight command REM 106 bad print/finish ack character REM 107 command packet too small or large REM 108 bad value of some kind REM ------------------------------------------------------------------------- REM Movement detection: we need to know when the thing is not moving REM by noting that the quadrature counter has not moved for some (small) REM period of time. The way we do this is to keep a record of the quad REM counter and see if it's the same as it was last time we looked. If REM so, increment a counter. If this counter reaches some preset limit REM (say, a value representing two seconds) then we assume things are REM not moving - we may want to stop the motor in this case. REM REM The counter is reset every time we get an ONITR tick because this REM is clearly movement. REM REM V1 value of quadrature counter last time we checked REM V2 non-movement tick counter (counts up on no movement). REM V3 whether we're idle or not REM V9 currently displayed idle or not REM V0 limit of V2 REM REM ------------------------------------------------------------------------- REM Print-Go Generation: we use one of the output lines (L6) to generate the REM print-go for the Codebox, and this high-going signal is routed to an REM open collector transistor in the head box. We use the PWM command REM to generate this signal because we can pick a nice even multiple REM of 5 milliseconds. Recall that this output (L6) goes through an REM inverter. REM REM ------------------------------------------------------------------------- REM Visible Heartbeat: we want to let the user know that things are working REM internally, so we keep a small heartbeat ticking. REM REM H0 heartbeat downcounter reload value REM H1 heartbeat downcounter REM H2 display value of the heartbeat (toggles) REM H9 heartbeat value currently on the display REM REM ------------------------------------------------------------------------- REM Serial I/O: we use a handshake similar to that used by the Codebox, with REM all input packets being cmd {data...} , and responses being REM either in this form, an , or a with three digits following. REM REM S1 serial input state REM 0 - not cranking serial (command in process) REM 1 - idle - waiting for ESCAPE REM 2 - got an ESC, waiting for cmd (timer is running) REM 3 - got cmd, collecting data (timer is running) REM S2 cmd we received REM S3 # of bytes in the buffer $IBUF REM S4 downcounter for timeout (only if S1 > 1) REM S8 limit of packet length REM S9 # of ticks for inbound timeout REM REM ------------------------------------------------------------------------- REM Feet counting: we keep track of how many feet we've printed so far, and REM we use the following variables: REM REM F1 current # of feet printed [CURRFOOT] REM F2 max feet to print [MXFOOT] REM F9 # of feet displayed on screen now [DSPFOOT] REM REM REM ------------------------------------------------------------------------- REM Print Acknowledgements: we want to tell the Impresor software every REM time we print a foot/meter, but we don't to put the code to format REM a packet in the ONITR interrupt handler -- this seems like asking for REM trouble. So, in the ONITR routine we just generate a single print ACK REM signal *for every unit* and set a flag asking that the idle handler REM send down the actual feet. REM REM This way the Impresor software gets a single byte for every foot REM (and can count it tentatively), but will for sure get resynced at REM the next idle time when the full print-unit response is sent. REM REM Note that Print Ack is either fully on or fully off, and you can't REM tune this behavior (though it is probably possible to consider REM adding this to the protocol). Also, the print ack character is REM fixed at "FS" and is not changable without modifying the code. REM REM ------------------------------------------------------------------------- REM REM P1 0=no print go at all [WANTPGO] REM 1=yes, do print go REM REM ------------------------------------------------------------------------- REM REM C9 counter value displayed now [DSPQCTR] REM REM ------------------------------------------------------------------------- REM REM A1 print acknowledgements? (1=yes 0=no) [WANTACK] REM A2 print-go issued in ONITR - might want to send ack [NEEDACK] REM REM ------------------------------------------------------------------------- REM REM Z1 do we want counter display? [WANTQCNT] REM Z2 do we want idle display? [WANTIDLE] REM REM ------------------------------------------------------------------------- REM REM T temp value used by idle handler REM T1 temp value used by ontick handler REM Tx other random temp variables REM REM ------------------------------------------------------------------------- REM REM L1 status of backlight [BKLITE] REM REM ------------------------------------------------------------------------- REM REM $(0) temp string? [$TMP] REM $(1) printmaster version (0.4) [$VER] REM $(3) inbound serial buffer [$IBUF] REM $(4) outbound serial buffer [$OBUF] REM $(5) buffer for the NAK response [$NAKBUF] REM $(6) unit of measure ("ft" or "m") [$UOM] REM REM REM 1 CLEAR : GOTO 100 REM first the timing-specific parameters. These are all in terms of REM parts of a seconds, and they all get converted to a number of REM ticks. 100 STRING 206,20 :' some big strings 103 $UOM = "ft" :' reasonable default 110 T0 = 0.125 :' tick timer 115 S9 = INT(2.0/T0) :' #tics for serial timeout 120 H0 = INT(1.0/T0) :' heartbeat downcounter reload value 150 V0 = 3 :' 10 ticks = system is idle REM first the configurable parameters 1000 R1 = 39 :' reload counter 1005 MXFOOT = 9999 :' total # of feet to print 1030 EOJACTN = TRUE :' recycle on end of job 1035 WANTACK = TRUE :' default = print acks 1037 NEEDACK = FALSE :' need to send print ack 1040 WANTQCNT = TRUE :' default counter display 1041 WANTIDLE = TRUE :' default idle display 1050 S8 = 10 :' limit of serial input buffer size 1060 BKLITE = TRUE :' default backlight control 1070 WANTPGO = TRUE :' no print go by default REM initialize the housekeeping ones 1130 CURRFOOT = 0 :' number of feet actually printed 1135 DSPFOOT = -1 :' currently-displayed # of feet 1140 DSPQCTR = -1 :' current counter on screen now 1160 H1 = 1 :' heartbeat downcounter: about to fire 1165 H2 = 1 :' current heartbeat symbol 1170 H9 = -1 :' what's on the display now 1180 V1 = -1 :' quad counter last time we looked 1185 V2 = 0 :' non-movement downcounter 1190 V9 = -1 :' currently-displayed idle value 1200 S1 = 1 :' serial state (waiting) 1202 S2 = 0 :' command we received 1204 S3 = 1 :' ptr to next char 1205 S4 = 0 :' serial timeout downcounter 1300 GOSUB 5000 :' overall initialization 1310 GOSUB 6100 :' quadrature value for one foot 1320 GOSUB 6000 :' display max feet REM ---------------------------------------------------------------------- REM note that we just reset ourselves by sending a packet to the computer. REM This is a serious problem unless we are expecting it. REM 1400 $OBUF = "aPrintmaster reset" :' spontaneous reset message 1410 GOSUB 6300 :' transmit packet to other end 1499 WDOG 2 :' timeout after 2.8 seconds 1500 ONITR 3000 1510 ONTICK T0, 2000 REM hang out waiting for stuff to happen 1520 IDLE REM ------------------------------------------------------------------------ REM check the heartbeat display to see if it changed. If so, REM display the change. REM 1602 WDOG :' reset watchdog timer 1605 IF H2 = H9 THEN GOTO 1650 1608 H9 = H2 1610 IF H9 = 1 THEN $TMP = "*" ELSE $TMP = "|" 1615 DISPLAY (%HBEAT) :' move cursor to heartbeat locn 1620 DISPLAY $TMP REM handle the foot display - CURRFOOT is updated by ONITR 1650 IF CURRFOOT = DSPFOOT THEN GOTO 1675 1655 DSPFOOT = CURRFOOT :' save current foot marker 1660 DISPLAY (%CURRFOOT) : T = CURRFOOT : GOSUB REDISPLAY4 REM issue the print ack if we found one 1675 IF NEEDACK=FALSE THEN GOTO 1700 1677 NEEDACK=FALSE :' reset ack-needed 1680 N2 = CURRFOOT :' foot counter 1682 N3 = 4 :' width of what to display 1685 N4 = S2: S2 = 97 :' save cmd byte, cmdbyte = "a" 1690 GOSUB 6600 :' format & send response 1695 S2 = N4 :' restore command byte REM update the idle display if configured 1700 IF (WANTIDLE = 0) .OR. (V3 = V9) GOTO 1750 1703 V9 = V3 :' note value on display 1705 IF V3 = 1 THEN $TMP = "Idle" ELSE $TMP = "Run " 1710 DISPLAY (%IDLE) 1715 DISPLAY $TMP REM update the counter if configured 1750 IF WANTQCNT = 0 THEN GOTO 1800 1752 T = COUNT(0) 1755 IF T = DSPQCTR THEN GOTO 1800 ELSE DSPQCTR = T 1765 DISPLAY (%QCNT) : T = T+1 : GOSUB REDISPLAY4 REM look at command packet? 1800 IF S1 = 0 THEN GOSUB 9000 : S1 = 1 1999 GOTO 1520 :' back up to the IDLE REM ======================================================================= REM =============== O N T I C K ========================================== REM ======================================================================= REM This is the ontick timer. We don't do any displaying in this routine REM because we want to keep this in the main loop -- we only do the things REM that really must be done on the timer loop. REM REM --------------------------------------------------------------------- REM downcount the heartbeat counter, and if it reaches zero then we need REM to reload it and then toggle the heartbeat value itself. REM REM CLEAR TICK(0) 2000 H1 = H1 - 1 : IF H1 > 0 THEN GOTO 2050 2020 H1 = H0 :' reload the counter 2025 H2 = NOT(H2) REM --------------------------------------------------------------------- REM easy keyboard stuff: C=clear 1=add one to feet REM 2050 T1 = KEYPAD(0) : IF T1=0 THEN GOTO 2100 2055 ON T1-1 GOSUB 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96 2057 GOTO 2100 REM 1 2 3 A 81 CURRFOOT = CURRFOOT + 1 : COUNT 0,R1 : LINEB 6,1,8 : RETURN 82 RETURN 83 RETURN 84 GOTO 6750 :' TOGGLE PRINT-GO ACTION REM 4 5 6 B 85 T1 = R1 + 100 : GOTO 2060 86 T1 = R1 + 10 : GOTO 2060 87 T1 = R1 + 1 : GOTO 2060 88 IF BKLITE = 1 THEN GOTO 6500 ELSE GOTO 6501 :' backlight REM 7 8 9 C 89 T1 = R1 - 100 : GOTO 2060 90 T1 = R1 - 10 : GOTO 2060 91 T1 = R1 - 1 : GOTO 2060 92 CURRFOOT=0 : COUNT 0,R1 : LINEB 6,1,8 : RETURN REM * 0 # D 93 WDOG 1 : CLEARI : DISPLAY (%IDLE), "*RESET*" : DO : WHILE 1 94 RETURN 95 RETURN 96 GOTO 6775 :' TOGGLE EOJ ACTION (REPEAT/NO REPEAT) 2060 IF (T1 > 0) .AND. (T1 < 9999) THEN R1 = T1 : COUNT 0,R1 : GOSUB 6100 2065 RETURN REM --------------------------------------------------------------------- REM check the machine for idle. We fetch the value of the quadrature REM counter and see if it is same as it was last time. If so, we REM increment the "not-changed" value once, and when this value REM reaches a certain level (V0) then we're officially idle. This REM "not changed" value is reset when we get a foot-count, because REM this clearly is "movement". 2100 T1 = COUNT(0) 2130 IF T1 = V1 THEN V2 = V2 + 1 : GOTO 2140 2135 V2 = 0 : V1 = T1 :' zero counter,save ctr 2140 IF V2 >= V0 THEN V3 = 1 ELSE V3 = 0 :' determine idle or not REM ----------------------------------------------------------------------- REM process inbound serial I/O stuff. We are receiving commands in the same REM form as the Codebox, which is cmd ...... , and we want to REM properly handle timeouts and incomplete or overflow packets. We can REM generate a NAK on many circumstances, but we're going to make things REM simpler by short-circuiting many paths on the state machine. REM REM For instance, we should NAK all occurrences of bogus characters or REM incomplete packets, but when we see an we simply reset the REM state machine and throw away whatever might have been in the buffer REM for now. This makes the code easier but relies on the Impresor REM software handling the timeouts. REM REM To do this we fetch the count of characters on the input stream REM and process what we find. We won't process more than a small REM handful of characters at a time because we don't want to REM 2300 IF S1 = 0 THEN GOTO 2398 : REM cmd in process, no crank REM if we get no chars, we still have to look for a timeout (@2395) 2305 T = COM(0) : IF T = 0 THEN GOTO 2395 2310 IF T > 10 THEN T = 10 : REM no more than 10 at a time 2313 DO : C = GET : IF C = 0 THEN GOTO 2390 REM state cmdbyte timecnt 2315 IF C = 1BH THEN S1=2 : S2=0 : S4=S9 : GOTO 2390 2320 ON S1 GOTO 2390,2390,2330,2360 : REM dispatch state 2325 S1 = 1 : GOTO 2390 : REM bogus - reset ourselves REM state 2 - got , so process command ---------------------- REM if we get an early then we have to NAK it and loop again 2330 IF C = 04H THEN N1=100: GOSUB 6200: GOTO 2390 REM savechar newstate buf cnt next loop 2335 S2 = C : S1 = 3 : S3 = 0 : GOTO 2390 REM ----------------------------------------------------------------------- REM In state 3 we are collecting bytes just after we've seen the command REM byte. If we get an EOT then we have a complete packet received so REM we have to stop cranking the serial port to give the mainline code REM a chance to process the packet -- this is state 0. REM REM Otherwise we look at the character to make sure it is valid (i.e., REM printable ASCII) and stuff it into the buffer. REM got EOT - finished! break out of loop - no more cranking 2360 IF C=04H THEN ASC($IBUF,S3+1)=13: S4=0 : S1 = 0 : T = 0 : GOTO 2390 REM invalid characters rcvd? NAK with 101 and recycle 2365 IF (C<32) .OR. (C>126) THEN N1 = 101 : GOSUB 6200 : GOTO 2390 REM overflow? S3=count S8=maxcount 2368 IF S3 >= S8 THEN N1 = 102 : GOSUB 6200 : GOTO 2390 REM bump nextch store char in buf 2370 S3 = S3 + 1 : ASC($IBUF,S3) = C :' ASC($IBUF,S3+1)=13 REM bottom of the loop - try again 2390 T = T - 1 : WHILE T > 0 REM see if we have timed out in a collecting state - just reset REM state countdown expired? state 2395 IF S1>1 THEN S4 = S4 - 1 : IF S4 <= 0 THEN S1=1 :' PRINT "*TIMEOUT*" 2398 REM IF TICK(0) > .1 THEN PRINT "Ticks=":USING(##.###), TICK(0) 2399 RETI REM ======================================================================= REM ONITR - quadrature interrupt handler REM ======================================================================= REM this is the interrupt handler for the quadrature encoder. We get a REM tick when the counter underflows, and the first thing we have to do REM is to reset the latched interrupt and reset the we're-not-moving REM counter. REM REM Then we have to see if we've reached the end of the reel, and if so, REM whether we need to recycle printing again. In any case we have to REM generate a print-go if the user has requested this. REM REM Related variables: REM 3000 @QRESET OFF : @QRESET ON :' reset quadrature flip-flop 3010 V1 = 0 :' reset non-movement counter REM - wrap around if we past max feet, else we're done. 3015 IF CURRFOOT < MXFOOT THEN GOTO 3030 3020 IF (EOJACTN = 1) THEN CURRFOOT = 0 ELSE GOTO 3100 3030 IF WANTPGO THEN PWM 6,5,1,1 :' set the print-go 3040 CURRFOOT = CURRFOOT + 1 :' *always* increment foot count 3050 IF WANTACK THEN NEEDACK=TRUE: PRINT CHR(1CH), 3100 RETI REM ======================================================================= REM initialization REM ======================================================================= REM we have to pause after a display, so do this first and then do other REM stuff (counter I/O) while waiting for it to settle. REM set the backlight 5000 IF BKLITE = 1 THEN GOSUB 6501 ELSE GOSUB 6500 5005 CONFIG DISPLAY 0 5010 CLEAR DISPLAY REM reset physical I/O lines 5015 @QRESET OFF 5020 @QRESET ON :' P6.L7 is normally high 5025 @PRTGO ON :' print-go is off (active low) 5028 @BKLITE ON :' turn on backlight REM ===TODO turn off the motor! REM initialize counter 5030 LINEB 6,1,0+32 :' MCR master reset of counter 5040 LINEB 6,1,192+1 :' QR set quadrature into X1 mode 5050 LINEB 6,1,128+4 :' OCCR divide by N 5060 COUNT 0,R1 :' MCR set PR to counter value 5070 LINEB 6,1,0+8 :' MCR transfer PR to CNTR 5080 LINEB 6,1,64+8 :' ICR enable inputs 5100 DISPLAY (3,0,OFF), "* ***************** Printmaster v",$VER," *" 5105 PRINT "******************* v", $VER REM 5107 DISPLAY (%VER), "v", $VER 5110 DISPLAY (0,27), "Currcnt:" 5115 DISPLAY (1,0), "Printed:" 5118 DISPLAY (1,17), "OF" 5120 DISPLAY (1,27), "Cnts/" REM - this is not only a fall-through display, but also an entry REM - point for a subroutine. 5125 DISPLAY (%FTUOM), $UOM, " " :' unit of measure in "feet printed" 5135 DISPLAY (%CNTUOM),$UOM,": " :' unit of measure in counts/unit 5140 GOSUB 6700 5145 RETURN REM ======================================================================= REM various subroutines REM ======================================================================= REM show max feet to print (look in MXFOOT value) 6000 T = MXFOOT : DISPLAY (%MXFOOT) : GOTO REDISPLAY4 REM ----------------------------------------------------------------------- REM given R1, display on screen and reload new encoder preload value. REM 6100 T= R1 + 1 : DISPLAY (%RELOAD) : GOTO REDISPLAY4 REM --------------------------------------------------------------------- REM Display the value in T but show **** if the number is out of REM range. This assumes that the display is already positioned in the REM proper place. REM REM ** REDISPLAY4: *** 6900 IF (T<0).OR.(T>9999) THEN $TMP="*****" ELSE T=STR(10,$TMP,040H,T) 6910 DISPLAY $TMP 6920 RETURN REM ------------------------------------------------------------------------- REM given nak code in N1, send a NAK to the other end. We also reset our REM state machine so that we're ready to receive another packet and don't REM require that we do additional cleanup. REM REM ===NOTE: this can be called from the ONTICK routine or from REM processing the commands. 6200 T2 = STR(10, $NAKBUF, 30H, N1) :' 3 digits + leading space 6210 ASC($NAKBUF,1) = 15H :' replace space with NAK 6220 PRINT $NAKBUF, 6240 RETURN REM ------------------------------------------------------------------------- REM given a user response in $OBUF, send it to the Impresor controller with REM proper framing. Note that the caller is responsible for that first REM command byte... 6300 PRINT CHR(1BH),$OBUF,CHR(04H), 6320 $OBUF = "" 6330 RETURN REM ------------------------------------------------------------------------- REM respond with ACK and reset state machine REM 6400 PRINT CHR(06H), 6420 RETURN REM ------------------------------------------------------------------------- REM backlight control REM 6500 BKLITE = FALSE : @BKLITE FALSE : RETURN 6501 BKLITE = TRUE : @BKLITE TRUE : RETURN REM ------------------------------------------------------------------------- REM Given N2 (a value) and N3 (a width), format the number into the output REM buffer and send it back. S2 is the command byte that gets stuff into REM the first byte. REM 6600 T3 = STR(10, $OBUF, N3*16, N2) :' format to ASCII 6605 ASC($OBUF,1) = S2 :' stick in command byte 6610 T3 = STRLEN($OBUF) 6620 FOR T4 = 2 TO T3 6630 T5 = ASC($OBUF,T4) 6640 IF T5 = ' ' THEN ASC($OBUF,T4) = '0' : REM replace with 0 6650 NEXT T4 6660 GOTO 6300 REM - display print-go and stop/repeat status 6700 DISPLAY (%STATUS) 6710 IF WANTPGO=0 THEN $TMP="PRT=N" ELSE $TMP="PRT=Y" 6715 DISPLAY $TMP, " " 6720 IF EOJACTN=0 THEN $TMP="RPT=N" ELSE $TMP="RPT=Y" 6730 DISPLAY $TMP 6740 RETURN REM toggle print-go status 6750 IF WANTPGO <> FALSE THEN WANTPGO = FALSE ELSE WANTPGO = TRUE 6760 GOTO 6700 REM toggle end-of-job repeat 6775 IF EOJACTN <> FALSE THEN EOJACTN = FALSE ELSE EOJACTN = TRUE 6780 GOTO 6700 REM ======================================================================= REM process command packet. All commands start with an upper-case letter, REM and we NAK all those that aren't right. This portion of the code is REM called as a subroutine, so we can GOTO the disposition routine (ACK, REM NAK, or response) and it will return to the caller. REM REM Since all of our queries work basically the same way, we head off REM these at the start so the individual handlers don't have to worry REM about it. REM REM first make sure the packet is not totally bogus 9000 REM PRINT "COMMAND = <", CHR(S2), "> <", $IBUF, ">" REM convert command char to index and make sure it's within range 9005 T = S2 - 64 9010 IF (T < 1) .OR. (T > 10) THEN RESPOND_NAK(104) :' bad command REM null out the response buffer and compute a few of the handy REM constants used here. L is the length of the buffer, C is the REM first character of the buffer, and Q is 1 if this is a query REM packet and 0 if not. 9012 $OBUF = "" 9014 L = STRLEN($IBUF) 9015 IF L > 0 THEN C = ASC($IBUF,1) ELSE C = 0 9018 IF (L = 1) .AND. (C = 3FH) THEN Q = 1 ELSE Q = 0 9020 ON T-1 GOTO 10100,10200,10300,10400,10500,10600,10700,10800,10900,11000 REM ----------------------------------------------------------- REM A query or set print ack status REM REM These print acknowledgments are not the same as the codebox: REM these ones include the # of units printed. REM 10100 IF Q = 1 THEN RESPOND_QUERY(WANTACK,1) :' respond to user 10103 IF L <> 1 THEN GOTO 10140 :' failure 10105 T = ASC($IBUF,1) 10110 IF T='0' THEN WANTACK = 0 : RESPOND_ACK :' ACK: 0 = disabled 10115 IF T='1' THEN WANTACK = 1 : RESPOND_ACK :' ACK: 1 = enabled 10140 RESPOND_NAK(106) :' NAK: out of range REM ----------------------------------------------------------- REM B BACKLIGHT control -- query or set or unset REM 10200 IF Q THEN RESPOND_QUERY(BKLITE,1) 10230 IF C = '0' THEN GOSUB 6500 : RESPOND_ACK :' backlight off 10220 IF C = '1' THEN GOSUB 6501 : RESPOND_ACK :' backlight on 10240 RESPOND_NAK(105) :' bad backlight ctl REM ----------------------------------------------------------- REM C set or query the encoder reload REM 10300 IF Q THEN RESPOND_QUERY(R1+1,4) 10305 IF L <> 4 THEN RESPOND_NAK(107) :' bad packet size 10310 T = STRVAL($IBUF) 10320 IF T = 0 THEN RESPOND_NAK(106) :' bogus value 10330 R1 = T-1 : COUNT 0,R1 : GOSUB 6100 :' program in new value 10340 RESPOND_ACK REM ----------------------------------------------------------- REM D set or query the encoder current counter. We have to set REM the new PR value and transfer it to the count, then put REM back the counter this involves resetting the whole counter REM first... 10400 IF Q THEN RESPOND_QUERY(COUNT(0)+1,4) 10405 IF L <> 4 THEN RESPOND_NAK(107) 10410 T = STRVAL($IBUF) 10420 IF T = 0 THEN RESPOND_NAK(106) :' NAK (bad param) 10430 LINEB 6,1,64 : REM ICR - disable inputs 10435 COUNT 0,T-1 : REM MCR - set PR to this value 10440 LINEB 6,1,8 : REM MCR - transfer PR to CNTR 10445 COUNT 0,R1 : REM MCR - reset PR properly 10450 LINEB 6,1,64+8 : REM ICR - enable inputs 10460 RESPOND_ACK REM ----------------------------------------------------------- REM E set or query the limit feet (####) REM 10500 IF Q THEN RESPOND_QUERY(MXFOOT,4) 10505 IF L <> 4 THEN RESPOND_NAK(107) :' wrong packet size 10510 MXFOOT = STRVAL($IBUF) :' parse feet 10520 GOSUB 6000 :' redisplay 10540 RESPOND_ACK REM ----------------------------------------------------------- REM F set or query the *current* feet (####) REM 10600 IF Q THEN RESPOND_QUERY(CURRFOOT,4) 10605 IF L <> 4 THEN RESPOND_NAK(107) 10610 CURRFOOT = STRVAL($IBUF) :' parse feet 10640 RESPOND_ACK REM ----------------------------------------------------------- REM G simulate reset -- just hang and wait for watchdog REM 10700 GOTO 93 REM ----------------------------------------------------------- REM H xxx... - set units of measure display REM 10800 IF Q THEN GOTO 10840 10805 T = STRLEN($IBUF) : IF (T <= 0) .OR. (T > 2) THEN RESPOND_NAK(107) 10810 $UOM = $IBUF 10820 GOSUB 5125 10830 RESPOND_ACK REM -- query response 10840 ASC($OBUF, 1) = S2 :' command byte 10845 T=STRLEN($UOM) 10850 FOR I=1 TO T: ASC($OBUF,I+1) = ASC($UOM,I) : NEXT I 10860 ASC($OBUF,T+2) = 13 :' mark the end of the string 10880 GOTO 6300 REM ----------------------------------------------------------- REM I x - set/query end-of-job action. Values are REM REM 0 stop REM 1 reload and restart REM 10900 IF Q THEN RESPOND_QUERY(EOJACTN,1) 10910 IF L <> 1 THEN RESPOND_NAK(107) :' invalid packet size 10920 T = STRVAL($IBUF) 10930 IF (T <> 0).AND.(T <> 1) THEN RESPOND_NAK(108) 10940 EOJACTN = T : GOSUB 6700 : RESPOND_ACK REM ----------------------------------------------------------- REM J x - set/query print-go action. REM REM 0 don't REM 1 do REM 11000 IF Q THEN RESPOND_QUERY(WANTPGO,1) 11010 IF L <> 1 THEN RESPOND_NAK(107) :' invalid packet size 11020 T = STRVAL($IBUF) 11030 IF (T <> 0).AND.(T <> 1) THEN RESPOND_NAK(108) 11040 WANTPGO = T : GOSUB 6700 : RESPOND_ACK SAVE