Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Quadratic Encoder

Status
Not open for further replies.

VBguru

New Member
I am trying to hook up an external chip to my Atom (www.Basicmicro.com) and I have no idea how to interface to the chip or what the code would look like to get the data from it properly.

I basically I am using a PIC16f876 with Mbasic trying to interface to a HCTL-2001 A00 and or HCTL-2017 A00

**broken link removed**

Can anyone provide any help? I am familiar with the atom and programming it but the Decoder chip is out of my area.


Thanks!!
 
First

Thanks for your reply!

Second

Then it will be similar to connecting to an optical mouse (2061 I believe). I have some code from that. I will get the data sheets out and compare.


third

What about all of the connections from the HCTL-2001. I am not sure how to connect it to the pic. This is my main hold up at the moment. I don’t want to mess anything up.
 
Just out of curiosity, what are you using it for? If you are doing simple, low speed quadrature, you might be better off doing it in software. quadrature in software is pretty easy.
 
I am trying to keep track of something that will be around 12 - 300 rpms. I have it hooked up to an lcd and a few switches. I have it running software right now and its missing enough to be a problem. I also tried having it on a second pic and making them talk, but it was still not up to what i need. This chip will keep track of the encoder and when you poll it for data it will not loose count.
 
At 300rpm that is only 5 revs per second. Simple polling on a 100Hz timer interrupt would keep track of it very well and leave 99% of the processing time spare.

Mike.
 
That's pretty slow. If you can't catch the transitions of the encoder, you probably will have trouble catching the pulse information from the quad chip. You will need at least 8 I/O pins for the quad chip just to read the revs but I think you would also want rst, sel, cnt and dir for 12.

I sure seems like overkill to me.

can you use interrupts in mbasic? that's the way to do it.
 
hmm... guess i should give a few more specs on my hardware....

Atom (Pic16f876)
encoder (128 resolution)
wheel
2x20 lcd
6 buttons

64 x 15 rpms = 960 pulses
128 x 15 rpms = 1920 pulses
64 x 300 rpms = 19200 pulses

I have played with different encoders and the lowest resolution i can go to get what i want is 64. I have a bunch of 128's so that is what i am trying to go with. I need to be able to turn the wheel and know exactly what is where on it at a given time and the encoder works perfect.

I also played alot with using ir leds and black strips, but it wasnt working too well.
I was using an optical mouse for a while also but ran into the acceleration problem with it.
 
Last edited:
128*300 RPM = 640 pulses per second. At this resolution an interrupt at 2000Hz will be fast enough never to miss a change. You may have problems in basic though.

Edit, thinking about the algorithm for 2 inputs A & B, isn't it simply,
Has A changed?
If yes then if A=B then inc counter else dec counter.

Mike.
 
Last edited:
Your right, Big mistake on my part it is per Second.
The program that i have for the encoder:
Gets state, gets new state makes old one oldstate
then it looks to see what direction it went.

Is there some better way of doing this?

-----------------------------------------------------
CurVal = (PortB & %00110000) >> 4 ;get current reading
OldVal = CurVal ;initialize for future change

Main
;-------------------
CurVal = (PortB & %00110000) >> 4 ;returns 0..3
If CurVal <> Oldval Then
Branch CurVal, [S0,S1,S2,S3] ;if changed look at old
EndIf
AfterBranch
S0 ;reading is 0, check if came from 1 or 2
;--------------------
If OldVal = 2 Then
GoSub ClockWise
Else
Gosub CounterClockWise
EndIf

Goto AfterBranch

S1 ;reading is 1, check if came from 0 or 3
;--------------------
If OldVal = 0 Then
GoSub ClockWise
Else
Gosub CounterClockWise
EndIf

Goto AfterBranch

S2 ;reading is 2, check if came from 3 or 0
;--------------------
If OldVal = 3 Then
GoSub ClockWise
Else
Gosub CounterClockWise
EndIf

Goto AfterBranch

S3 ;reading is 3, check if came from 1 or 2
;--------------------
If OldVal = 1 Then
GoSub ClockWise
Else
Gosub CounterClockWise
EndIf

Goto AfterBranch


ClockWise
;-------------------
OldVal = CurVal ;ready to check next input
Counter = Counter + 1 ;add one to counter value
Return

CounterClockWise
;-------------------
OldVal = CurVal ;ready to check next input
Counter = Counter - 1 ;subtract one to counter value
Return
 
Can you try,

Code:
Main
;-------------------
CurVal = (PortB & %00110000) >> 4 ;returns 0..3
A=CurVal & 1
B=CurVal >> 1
If A <> OldVal then
    if A=B then Gosub ClockWise
    if A<>B then Gosub CounterClockWise
endif
OldVal=A

Mike.
Edit, take the OldVal=CurVal out of the CW and CCW subroutines.
 
Last edited:
I just had a proper look through your code and it looks correct and will have twice the resolution of the code I posted. The only explanation I can think of is that it is not called often enough. Can you setup an interrupt at around 2000Hz and call it from that?

Mike.
 
Status
Not open for further replies.

Latest threads

Back
Top