'---------------------------------------------------------------------------------------- ' Name: ENC1_Demo_1_00h.TIG ' Type: Tiger-BASIC(tm) Source Code ' Purpose: Show & explain functions of Encoder Device Driver "ENC1_xxx.TDD" ' ' Including new features of V e r s 1 . 0 0 h ' ' (C) - Copyright Wilke Technology, P.O.Box 1727, D-52018 Aachen, Germany '---------------------------------------------------------------------------------------- ' ' Thank you for using BASIC Tigers in your products. If you have questions, ideas ' or special needs, please contact your next distributor or the Tiger support team ' and visit our web site: ' ' Wilke Technology GmbH ' The Tiger Support Team ' P.O.Box 1727, D-52018 Aachen, Germany ' Krefelder Str. 147, D-52070 Aachen, Germany ' ' email: support@wilke-technology.com (english) ' email: support@wilke.de (german) ' Phone: +49 (241) 918 900 Mo to Fr, 7:00 to 16:00 (GMT) ' Fax: +49 (241) 918 9068 ' ' New information, new drivers and free downloads see: ' ' www.wilke-technology.com (english) ' www.wilke.de (german) ' ' Sincerely, ' ' Your Tiger Support Team ' '---------------------------------------------------------------------------------------- ' ' This example program was compiled with TIGER-BASIC 5.01 to run with a AXI-4/4 ' BASIC Tiger module on the Plug & Play Lab. ' ' The encoder inputs chosen here are: L80 + L81 for 2 encoder phase outputs. ' ' ' G e n e r a l : ' ' The encoder device driver "ENC1_xxx.TDD" is a multi-function driver for applications ' as: ' ' - Rotating encoders used as input device for the man-machine interface. ' Through a single rotating knob (and a push button function with it) ' intuitive inputting is possible. ' ' Quasi analog input, number inputting, alphanumeric input, menue selections, ' cursor movements ... etc. are easy to use and to realize. ' ' - Rotating or linear encoders for keeping track of machine parts and ' movement sensors. ' ' ' The device drivers "ENC1_xxx.TDD" are available in these I/O input pin ' combinations: ' ' Driver-Name: Pin-0 Pin-1 ' <----------> <---> <---> ' ' ENC1_801.TDD L80 L81 ' ENC1_823.TDD L82 L83 ' ENC1_845.TDD L84 L85 ' ENC1_867.TDD L86 L87 ' ' ENC1_701.TDD L70 L71 ' ENC1_723.TDD L72 L73 ' ' ENC1_601.TDD L60 L61 ' ENC1_623.TDD L62 L63 ' ' ENC1_402.TDD L40 L42 ' ENC1_334.TDD L33 L34 ' ' ' Several ENC1 device drivers - up to a maximum of 8 - may be used simultaneously for ' multi encoder applications. Though, processing power used to control several encoders ' has to be taken into account. Using slow sampling and eventually disabling dynamic ' counting, reduces system load. ' '---------------------------------------------------------------------------------------- ' ' ENC1 drivers are used in conjunction with the TIMERA.TDD device driver as the ' clock source for sampling the 2 encoder output lines (Pin 0 and pin 1). ' Depending on the application TIMERA speed is selected: ' ' - high enough to get secure sampling of all movements ' - low enough not to consume unnecessary computing power ' ' ' : : : : : : : : : : : : : : : : : : ' Phase-0: : : : : : : : : : : : : : : : : ' -------------------!: : : : : : :!-------------------------------! : ' ; : : : !: : : : : : :! : : : : : : ! : ' : : : : !-------------------------------! : : : : : : !----- ' : : : : : : : : : : : : : : : : : : ' : : : : : : : : : : : : : : : : : : ' Phase-1: : : : : : : : : : : : : : : : : ' : : !-------------------------!: : : : : : :!----------------------- ' : : ! : : : : : !: : : : : : :! : : : : ' --------! : : : : : !-------------------------------! : : : : ' : : : : : : : : : : : : : : : : : : ' : : : : : : : : : : : : : : : : : : ' ' :<------ samping times ' ' ' The minimum requirement for proper sampling is: ' ' - Even at highest encoder speed, there must be always at least 1 sample between ' any change in the 2 encoder output lines. ' This guarantees that the encoder movement - speed and direction - is sampled ' without position loss. ' ' Also, there is no limit to proper function by a high number of samples per period. ' So, even high sampling frequency and slow encoder movements - with thousands of samples ' per encoder cycle, work fine. ' ' ' Calculation examples: ' ' Example 1: A manually operated rotating encoder delivers 24 full signal cycles per ' rotation. This means 24 x 4 = 96 phases. ' ' Supposing that the maximum operation speed is 2 rotations per second, ' we get up to 192 different phases per second. ' ' So, the minimum sampling speed would be 196 / sec. ' We decide for 700 / s what is a low Timer-A speed (in BASIC Tiger ' module type A), so proper function is guaranteed and we still operate at ' a relatively low Timer-A frequency saving computing power. ' ' In the case of a manually operated rotation encoder, we might want to ' use the dynamic counting through a settable weigth table. ' ' This allows to get 2 or 3 different behaviours of a single rotation knob, ' for example: ' ' - Single INCrements and DECrements at low rotating speeds (fine-tuning) ' - Steps of 10 to 20 for medium rotating speed ' - Steps of 100...200 for high rotating speed. ' ' So, through turning a single rotating knob, one can input intuitively and ' quickly a 4-digit number for example. ' ' < 1 2 3 4 > ' ' 1 single rotation at fast speed would give 24 x 200 = 4800 counts up or down ' in the "high gear" range and 24 x 10...20 = 240...480 in the medium gear ' and precise, single IND/DECs at low speed. ' ' In fact, through the use of a table with 256 entries, a smooth step-increase ' as a function of rotating speed is available. ' ' ' Example 2: The Encoder for checking the movement of a machine part (rotating or linear) ' delivers up to 3200 Hz signals. The encoder device driver then would be ' used to measure the EXACT position. ' ' So, only the LINEAR counting feature is needed, DYNAMIC counting would not ' make any sense. Thus dynamic counting would be disabled by the INSTALL ' parameter reducing CPU load a bit: ' ' INSTALL_DEVICE #ENC, "ENC1_801.TDD",4,0FFH ' 4=1/4 phase, FF=no dynamic counting ' ' Timer-A frequency has to be at least 4 x 3200 = 12800 Hz. ' So, a sampling speed of 14 or 15 kHz would well fit 1 sample per phase ' change. ' '---------------------------------------------------------------------------------------- ' ' The ENC1 device driver supports both - 1/2 step and 1/4 step operation of encoders. ' 1/2 or 1/4 step reflects the relation between mechanical position digitizing and ' electrical signal digitizing. ' ' Assuming a manually operated rotating encoder we could have these 2 situations: ' ' ' Rotation Direction Rotation Direction ' <--------positive-------> <----------------negative----------------> ' ' !--<0>---! !-------! !-------! !-------! !------! ' ! ! ! ! ! ! ! ! ! ! ' ! !-------! !--! !-------! !-------! !-- ' ' !--<1>---! !----------! !-------! !-------! ' ! ! ! ! ! ! ! ! ' ----! !-------! !-------! !-------! !----- ' ' 1 2 3 4 5 6 5 4 3 2 1 0 -1 -2 -3 -4 <--- Position, 1/4 step ' + + + + + + - - - - - - - - - - <--- (+)=INC, (-)=DEC ' ' ' 1 2 3 2 1 0 -1 -2 <--- Position, 1/2 step ' + + + - - - - - <--- (+)=INC, (-)=DEC ' '---------------------------------------------------------------------------------------- ' ' ' Installing the encoder device driver ' ' ' INSTALL_DEVICE #ENC, "ENC1_801.TDD", p0, p1 ' ! !! ! ! ' ! !! ! !<--- 0 = linear + dynamic counting enabled ' ! !! ! 0FFH = linear counting only, NO dynamic counting ' ! !! ! Default = 0 = linear + dynamic ' ! !! ! ' ! !! !<--- 2 = 1/2 step mode, 4 = 1/4 step mode ' ! !! Default = 2 = 1/2 step mode ' ! !! ' ! !!<--- L80 + L81 are inputs for 2 ENCODER outputs ' ! ' !<--- device number in application prog. ' ' '---------------------------------------------------------------------------------------- ' ' ' Reading Information from the encoder device driver through different secondary channels: ' ------------------------------------------------------------------------------------- ' ' GET #ENC, #0, 0, A ' Sec.addr.=0 -> read linear encoder COUNT ' GET #ENC, #1, 0, B ' Sec.addr.=1 -> read linear encoder COUNT + RESET/Reload ' GET #ENC, #2, 0, C ' Sec.addr.=2 -> read scaled encoder COUNT ' GET #ENC, #3, 0, D ' Sec.addr.=3 -> read scaled encoder COUNT + RESET/Reload ' GET #ENC, #4, 0, E ' Sec.addr.=4 -> read linear + scaled encoder COUNTs ' GET #ENC, #5, 0, F ' Sec.addr.=5 -> read linear + scaled encoder COUNTs + RESET/Reload ' GET #ENC, #6, 0, G ' Sec.addr.=6 -> read current encoder speed ' ' ' A,B,C,D,E,F,G = LONG variables ' ' ' ' Setting + starting through secondary output channels: (Sec.addr. 0...2) ' ------------------------------------------------------------------------- ' ' PUT #ENC, #0, ' Sec.addr.=0: Set RESET reload value for counter(s) and ' ' start encoder reading ' ' ' ' The RESET reload value is getting copied into the ' ' dncoder counter when reading the encoder counts ' ' through a secondary channel with RESET/reload function ' ' (see above). ' ' ' ' = signed LONG: 8000 0000h ... 7FFF FFFF ' ' Example: ' ' PUT #ENC, 1234567 ' set RESET/reload value to 1234567 and start encoder reading ' ' -------------------------------------------------------------------------------------- ' ' PUT #ENC, #1, ' Sec.addr.=1: Set the linear encoder counter to ' ' This instruction neither is starting nor stopping the ' ' encoder reading process. ' ' ' ' = signed LONG: 8000 0000h ... 7FFF FFFF ' ' ' ' NOTE: Setting the encoder counter to a new value ' ' might result in data loss, as the current ' ' encoder counter value gets O V E R W R I T T E N. ' ' -------------------------------------------------------------------------------------- ' ' PUT #ENC, #2, ' Sec.addr.=2: Set D Y N A M I C encoder counter to ' ' This instruction neither is starting nor stopping the ' ' encoder reading process. ' ' ' ' = signed LONG: 8000 0000h ... 7FFF FFFF ' ' ' ' NOTE: Setting the encoder counter to a new value ' ' might result in data loss, as the current ' ' encoder counter value gets O V E R W R I T T E N. ' '---------------------------------------------------------------------------------------- ' ' User Function Codes to set additional device driver functions: ' -------------------------------------------------------------- ' ' PUT #ENC, #0, #UFCO_WEIGHTTAB, p0$ ' Set weight factor table for dynamic count reading ' ' up to 256 bytes. Each byte gives the number of ' ' dynamic counter INCrements/DECrements at a certain ' ' encoder speed. ' ' ' ' Typically the number of INC/DECs would be higher ' ' for high speeds, and lower for slow movements. ' ' The smallest INC/DECrement is 0 (giving NO INC/DEC ' ' at all at that speed), a "1" would have the same ' ' effect as the linear (non-dynamic) counter reading, ' ' and any value between and including 1...255 (FF) ' ' would accelerate the dynamic counting, depending ' ' on the speed of encoder movement. ' ' ' ' The first bytes in WEIGHT string represent INC/DECs ' ' at fast speeds, the last of the 256 bytes represent ' ' the INC/DECs at slow speeds. ' ' PUT #ENC, #0, #UFCO_SCALEFCT, p0 ' Set time scaling factor ' ' This ' ' PUT #ENC, #0, #UFCO_ENC_STOP, p0 ' Stop encoder reading: Reduced CPU load, no ' ' change of encoder counter values ' ' PUT #ENC, #0, #UFCO_ENC_START, p0 ' (Re-)start encoder reading, without changing ' ' counter values or reset values ' ' PUT #ENC, #0, #UFCO_ENC_DIR, p0 ' Set count direction: p0: 0=pos., X=neg. ' '---------------------------------------------------------------------------------------- USER_VAR_STRICT ' Check for proper variable declaration #INCLUDE DEFINE_A.INC ' General purpose definitions #INCLUDE UFUNC3.INC ' User Function Codes TASK MAIN ' Begin task MAIN LONG dwEnc, dwEnc_DYN, SPEED_NDX ' LONG N, SPEED ' REAL SPEED_REAL ' STRING DYN_WEIGHT$ (256) ' Dynamic weight table INSTALL_DEVICE #LCD, "LCD1.TDD" ' Text LCD device driver (BASIC-Tiger) INSTALL_DEVICE #TA, "TIMERA.TDD", 3, 156 ' Timebase 1 kHz INSTALL_DEVICE #ENC, "ENC1_801.TDD", 4, 1 ' Encoder driver: Pins L80 + L81, ' 1/4 step, dynamic count ' PUT #TA, #1, 5000 ' Timer-A to 5000 Hz PUT #LCD, "<1bh>c<0><0f0h>" ' Cursor off PRINT #LCD, "<1>Encoder on L80/81" ' Clear + home + headline text ' DYN_WEIGHT$ = FILL$ ("09"%, 256) ' Alternative weight tables ' DYN_WEIGHT$ = FILL$ ("09"%, 128) ' DYN_WEIGHT$ = DYN_WEIGHT$ + FILL$ ("01"%, 128) DYN_WEIGHT$ = "& ' Initialize weight table 64 64 64 64 64 64 32 28 18 10 08 04 04 04 04 03& 03 03 03 03 03 03 02 02 02 02 02 02 02 02 02 02"% PUT #ENC, #0, #UFCO_WEIGHTTAB, DYN_WEIGHT$ ' Dynamic weight ' PUT #ENC, #0, #UFCO_ENC_DIR, 1 ' Set direction "negative" PUT #ENC, #0, #UFCO_ENC_DIR, 0 ' Set direction "positive" PUT #ENC, 7777 ' Start encoder reading, set RESET value to 7777 ' PUT #ENC, #1, 9999 ' Set counter value static to value = 9999 WHILE 0 = 0 ' <---- endless loop ---------------------------- GET #ENC, #0, 4, dwEnc ' Read linear encoder count GET #ENC, #2, 4, dwEnc_DYN ' Read DYNAMIC encoder count GET #ENC, #6, 4, SPEED_NDX ' Read encoder speed index: 00..FF SPEED_REAL = LOG (256000.0/(SPEED_NDX+1)) SPEED = INT (110*(SPEED_REAL-3)) PRINT #LCD, "<1Bh>A<0><1><0F0h>Steps:"; dwEnc; " "; PRINT #LCD, "<1Bh>A<0><2><0F0h> dyn.:"; dwEnc_DYN; " "; PRINT #LCD, "<1Bh>A<0><3><0F0h>Speed:"; SPEED; " "; WAIT_DURATION 200 ' Wait 200 ms ENDWHILE ' ----- end of endless loop --------------------> END ' End of task MAIN