Shop Learn
Rotary encoder emulation — Parallax Forums

Rotary encoder emulation

Hello All,

It has been a while since I have posted here. I am currently working on a project where I am trying to emulate a rotary encoder. There is a small dc motor that bidirectionally drives the mechanism that contains the encoder. The motor control uses a duty cycle to control the speed and direction of the motor. What I am trying to do is eliminate the whole mechanism and replace it with a propeller that fools the controller into thinking the mechanism is still present. My original plan was to watch the signal to the motor and increment a counter whenever the signal was high in the forward direction and decrement the counter whenever the signal was high in the reverse direction. The watch the counter and output the signals for the encoder whenever the counter reached the proper positions. Do you all think this is the best way to do this? I have attached a screenshot of one full rotation of the encoder, you can see when the signal starts to repeat. The normal idle state for the encoder is all three channels high. I have also attached the code I have tested and works for one part of the function but when the motor runs in reverse, that is when I start having problems.


  _XINFREQ = 5_000_000

long comm_stack[1000]
long timer

ser : "fullduplexserial"

PUB Main

    cognew(@counter_plus, @timer)
    cognew(@counter_minus, @timer)
    cognew(@io, @timer)
    cognew(comms, @comm_stack)

pub comms | i

ser.start(31, 30, 0, 1000000)

  waitcnt(clkfreq/2000 +cnt)  


org 0                

counter_plus            mov t2, par
                        mov dira, #0

:loop                   waitpeq pin_a_mask, pin_a_mask 
                        rdlong  t1, t2
                        cmp t1, #0              wz
        if_always       add t1, #1
                        wrlong t1, t2
                        jmp #:loop

pin_a_mask long 1
t1  res 1
t2  res 1
'zero long 0


org 0

counter_minus           mov t4, par
                        mov dira, #0

:loop                   waitpeq pin_b_mask, pin_b_mask 
                        rdlong  t3, t4
                        cmp t3, #0              wz
        if_always       sub t3, #1
                        wrlong t3, t4
                        jmp #:loop

pin_b_mask long 1 << 1
t3  res 1
t4  res 1 


org 0

io                      mov t5, par
                        mov dira,io_mask

:loop                   rdlong t6, t5
                        cmps time3, t6           wc
        if_c            mov outa, io_3
        if_c            jmp #:loop
        if_nc           cmps time2, t6           wc
        if_c            mov outa, io_2
        if_c            jmp #:loop
        if_nc           cmps time1, t6           wc
        if_c            mov outa, io_1
        if_c            jmp #:loop
        if_nc           mov outa, io_0
                        jmp #:loop

io_mask long  %11111111_00000000_00000000
io_0    long  %00000000_00000000_00000000 
io_1    long  %00000001_00000000_00000000
io_2    long  %00000011_00000000_00000000
io_3    long  %00000111_00000000_00000000

time1   long  15000
time2   long  50000
time3   long  86000
t5      res   1
t6      res   1
t7      res   1

Sign In or Register to comment.