You may have a timer in counter mode in background; so you can do things in foreground while it counts in background.
You may have a timer in counter mode in background; so you can do things in foreground while it counts in background.
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
I tried to start it at all, even at slow speeds, and looked forum for rotary encoder debug code. Most examples have things like this in it:
OLDR = PORTB & $30 and similar, current hardware config limiting code.
Is there a way to have "universal" rotary encoder code, which will work, if say one pin is going to PORTD.4 and another to PORTA.2 ? I'm not sure how all this XORing and ANDs can be performed across the various ports.
Do you have hardware already on which this has to run? If that's the case then please tell us what that is which PIC and which pins are available.
Having the encoder pins spread across two different port register will slow it down and is not ideal, two adjacent pins on the same port is prefferable. If those pins have IOC capabilities that's one way to skin it.
You say the encoder have 60 pulses, is that 60 pulses per channel (240 edges per cm) or 15 pulses per channel (60 edges)? If it's the former and you're fine with 60 Counts per cm that makes it easier since it's just a mater of sampling channel B on the Rising edge of channel A. No qudrature decoding needed.
I take it you've already figured out how to talk to the AD9833 or is that going to be the follow up question?
I have not went with AD9833 yet, because if I can't run encoder, then there is no need for DDS. And by the way, some DDS code I see around the forum, so I think I can re-use it. For the encoder, this is simple encoder from inkjet printer, HEDS-9730. The ribbon has plain strips, 60 per centimeter (I've counted it under microscope). Before going with this encoder, I want to have some code running with simple, rotary, 3 pin, incremental encoder. My prototyping system has PIC16F886 on it now, and while now I can connect both pins to same port - say PORTA.1 and PORTA.2, if doing own code, I'd like to have a code, which will not be limited by same port.
If on different port, then you will spend time on transferring the data to a temp variable and do the XOR/AND on that temp byte.
Ioannis
While I know how XOR AND and other logical operations work, I can't get idea, how they are used over time based domain, as in case of encoder. I mean, where is that component, which defines the frequency of readout and pulse width and so on.
I came up with this code idea (have not tested it yet)
Code:STATE: 'WAIT FOR ENCODER TO BE MOVED (STATE CHANGE) X=PORTB.1 Y=PORTB.2 PAUSE 10 X1=PORTB.1 Y1=PORTB.2 IF X<>X1 OR Y<>Y1 THEN GOTO NEXTSTEP GOTO STATE NEXTSTEP: SOMELOOP: 'COUNTER LOOP FOR PULSE LENGTH COUNTING IF PORTB.1=1 THEN XIN=XIN+1 'X INCREMENT IF PORTB.2=1 THEN YIN=YIN+1 'Y INCREMENT IF PORTB.1=0 OR PORTB.2=0 THEN GOTO ANALYZE 'EXIT AND COMPARE LENGTHS GOTO SOMELOOP ANALYZE: 'DETERMINE DIRECTION AND INCREMENT CORRESPONDING VARIABLE IF XIN>YIN THEN CCW=CCW+1 ELSE CW=CW+1 ENDIF XIN=0 'RESET VARIABLES YIN=0 GOTO STATE
Check out https://www.microchip.com/wwwproducts/en/PIC18F4431 this series has a hardware quadrature encoder feedback module that runs on it's own in the back ground.
For optical encoder I use this:
Code:; PIC18F4520 DEFINE OSC 4 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts TRISA = %00000000 ' Make all PortA pins output TRISB = %11001000 Define LCD_DREG PORTA Define LCD_DBIT 0 Define LCD_RSREG PORTA define LCD_RSBIT 4 define LCD_EREG PORTA define LCD_EBIT 6 define LCD_BITS 4 define LCD_LINES 2 define LCD_COMMANDUS 2000 define LCD_DATAUS 50 ; encoder ch A PortB.6 ; encoder ch B PortB.7 wsave VAR BYTE $70 SYSTEM ; alternate save location for W enc_new VAR BYTE bank0 enc_old VAR BYTE bank0 enc_counter VAR word bank0 Flag var BYTE bank0 asm INT_LIST macro ; IntSource, Label, Type, Resetflag? INT_Handler RBC_INT, _enc, ASM, yes endm INT_CREATE ; Creates the interrupt processor endasm ; Set variable value @ startup enc_new = 0 enc_old= 0 enc_counter = 0 Flag = 0 @ INT_ENABLE RBC_INT ; enable external (INT) interrupts Main_Loop: Lcdout $fe, 1 lcdout Dec enc_counter goto Main_Loop enc: asm ;Read latest input from PORTB & put the value in _enc_new. MOVE?CB 1,_Flag movf PORTB,W movwf _enc_new ;Strip off all but the 2 MSBs in _enc_new. movlw B'11000000' ;Create bit mask (bits 7 & 6). andwf _enc_new,F ;Zero bits 5 thru 0. ;Determine the direction of the Rotary encoder. rlcf _enc_old,F ;left shift it into _enc_old to align bit 6 of ;_enc_old with bit 7 of _enc_new. movf _enc_new,W ;Move the contents of _enc_new to W in order to XOR. xorwf _enc_old,F ;XOR previous inputs (in _enc_old) with latest ;inputs (in W) to determine CW or CCW. btfsc _enc_old,7 ;Test bit 7 of result (in _enc_old). Skip next line ;if it is 0 (direction is CCW). goto Up ;Bit is 1 (direction is CW). Go around Down ;and increment counter. Down ;Decrements _enc_counter because the rotary encoder moved CCW. ;Decrements _enc_counter (16 bit value), sets Z on exit. decf _enc_counter,F ; Decrement low byte incfsz _enc_counter,W ; Check for underflow incf _enc_counter+1,F ; Update decf _enc_counter+1,F ; Fixup movf _enc_counter,W iorwf _enc_counter+1,W ; Set Z bit ;Add here code for the CCW LED if needed. goto Continue ;Branch around UP. Up ;Increments _enc_counter because the rotary encoder moved CW. ;Increments _enc_counter (16 bit value), sets Z on exit. incfsz _enc_counter,W ; Add one to low byte decf _enc_counter+1,F ; No carry (negates next step) incf _enc_counter+1,F ; Add one to high byte movwf _enc_counter ; Store updated low byte back. iorwf _enc_counter+1,W ; Set Z flag ;Add here code for the CW LED if needed. Continue ;Assign the latest encoder inputs (in _enc_new) to _enc_old. movf _enc_new,W movwf _enc_old INT_RETURN ;============ END OF THE ROTARY ENCODER CODE ===== endasm
Yes I checked that PIC datasheet already, but I don't see any ways to implement it in PBP, we don't have statement for encoder reading, like we have for LCDOUT or OWIN.
Bookmarks