Rotary encoder usage

vertigo

Member
Hello,
I have purchased the 2-bit rotary encoders described in this thread, but I could not find a correct way of using them in the forum (I am sorry if I have missed some threads) : None of the code examples posted, that I have tried, gave me a usable result.
So, after some tests, I finally wrote this small piece of code that works perfectly with the above rotary encoders. The program has been written on a 08M, but should run on any Picaxe. In this example, the program detects the rotation direction and increment or decrement a counter.
I hope this will help.

Code:
'picaxe 08M
'
'           +V 1 U 8 0V
'    GND - 10K 2   7 (0) OUT
' I/O/ADC4 (4) 3   6 (1) I/O/ADC1 --- rotary encoder
'   IN3    (3) 4   5 (2) I/O/ADC2 --- rotary encoder
'
' b1  b0 b3  b2 b5  b4 b7  b6 b9  b8 b11 b10 b13 b12
' --w0-- --w1-- --w2-- --w3-- --w4-- --w5--- --w6---

'b0 = bit7  : bit6  : bit5  : bit4  : bit3  : bit2  : bit1 : bit0
'b1 = bit15 : bit14 : bit13 : bit12 : bit11 : bit10 : bit9 : bit8

#rem

Rotary encoder connection:

   0V
   |
  4.7K
   |
o--.---- pin1 (phys 6)
o--330-- +5V
o--.---- pin2 (phys 5)
   |
  4.7K
   |
   0V

Encoder result (early detection):
pin1 pin2
  1    0  one direction
  0    1  other direction
  0    0  init and final (= "detent") status

One direction: pin1 goes high before pin2
         ___     ___
pin1 ___|   |___|   |___
           ___     ___
pin2 _____|   |___|   |___

Other direction: pin2 goes high before pin1
           ___     ___
pin1 _____|   |___|   |___
         ___     ___
pin2 ___|   |___|   |___

#endrem

'           Used bits                                          xxxx   xxxx
symbol getBits   = b0 'b0 = bit7 : bit6 : bit5 : bit4 : bit3 : bit2 : bit1 : bit0
symbol dir       = b1
symbol counter   = b3

setint %00000010,%00000010 'interrupt on pin1 high only

main:
  do
   sertxd("Main loop - Counter=",#b3,13,10)
   pause 1000
  loop
  
interrupt:
 bit2 = pin2: bit1 = pin1       'save rotary encoder pins status
 getBits = getBits & %000000110 'isolate rotary encoder pins
 if getBits <> 0 then           'if both pins are low, the direction is undetermined: discard
  dir = bit2 * 2                'direction: if bit2=low then dir=0; if bit2=high then dir=2
  counter = counter - 1 + dir   'change counter variable accordingly
  do while getBits <> 0         'wait for the encoder to go to the next "detent" position
   getBits = pins & %000000110
  loop
 endif
 setint %00000010,%00000010     'restore interrupt on pin1 high
 return
Regards,

Christophe
 

westaust55

Moderator
Thanks for sharing your code.

There have been past threads from time to time, usually with questions.
Your code will be helpful for others seeking to use many 2 channel (quadrature) incremental rotary encoders in the future.
 

MPep

Senior Member
Can you please repost in the Finished Projects section, Code Snippets.
It will be easier for future reference. Give it a good descriptive title.

Thanks for sharing.
 

vertigo

Member
Thank you for your comments. I have created a new thread in the code snippets section (with little modifications in the comments, not in the code itself).
But I don't know if I have (nor how) to remove this one : please forgive me for the multiple posts.

Regards,
Christophe
 

LFLekx

Member
Thanks for sharing your code.
Your code will be helpful for others seeking to use many 2 channel (quadrature) incremental rotary encoders in the future.
I was actually about to look for such a code segment... I've been thinking about starting the design on a project that could use a rotary encoder.

One question - do you think that the code will work on an 18X device...? (Although - since this *is* a new project, I can maybe use one of the newer chips rather than one I have already... :) )
 

Haku

Senior Member
Yes it'll work on the 18X, I wrote my own rotary encoder program from scratch on an 18X, partly for the challenge and partly because it could be useful in the future for a dimmer setup.
 

manie

Senior Member
Vertigo: Hope you don't wire your chips "from on high" looking at the user name.....

thanks, that is usefull code and I can understand what you are doing, well commented and a fine effort.
 

vertigo

Member
@LFLekx: Yes, the code should work with any Picaxe. Just take care of the pins you use, and adjust the code accordingly (interrupt pin and encoder pins status).
@manie: In fact my username is a reference to this great movie. ;-)

Christophe
 

alistairsam

Senior Member
Hi,
I need to build a quadrature encoder to read the position of my telescope's axis, but I also wanted to output the values in deg, min and sec through a serial interface.
one rotation of the shaft is divided to 360 deg, each deg into 60 minutes, and each minute into 60 seconds.
so needed to get an output such as 160d 37m 42s
can the code in this thread be modified to increment three counters and display them?
what sort of display would I need to look for?
i'm using a 14M
thanks
 

SAborn

Senior Member
alistairsam

Using a 14m you might be best with a serial lcd, to leave enough pins for the encoder and what ever else you need.

I would think you be better off with a 18m2 or 18x so you can add a real time clock via I2C to give the timing, as you quote seconds and minutes needed and the picaxe internal clock might not be accurate enough.
Then the displaying of data as you requested could be easy done.

One problem with encoders is at program startup there is no way of knowing what position they are in and for your application you would need to reset zero degrees each time the picaxe fired up.

If you dont need 360 degrees travel a pot could be better as the resistance can be read at startup and the location calculated in program.
This way the program will know what position it was parked in last time.
 

russbow

Senior Member
I would think you be better off with a 18m2 or 18x so you can add a real time clock via I2C to give the timing, as you quote seconds and minutes needed and the picaxe internal clock might not be accurate enough.
I think Alistair is referring to mins and secs as parts of a degree of a circle, not time.
 

Jeremy Leach

Senior Member
alistairsam - great idea, but 360*60*60 seconds in a revolution, that will need an amazing rotary encoder if you want to get an immediate output from that shaft , down to the resolution of seconds :)

It would be better to try to have the rotary encoder on one of the positioning adjustment knobs/wheels/whatever that rotate many times to make a small movement of the Telescope itself. Got to be realistic about the accuracy though - there is going to be a fair amount of mechanical play in the mechanism which means you are never going to be able to get a resolution down to a few seconds. I've got a telescope too and even walking by it makes it vary by quite a few seconds !
 

alistairsam

Senior Member
hi
thats correct, i was referring to amount travelled in deg, min, sec, not time.

jeremy, the way to get around an accurate encoder would be to use a low res encder with gearing at the scope shaft, as long as there is no play between the shaft and the encoder, position would be fairly accurate.
the bartels software uses mice encoders with gearing and a custom slot wheel to get around 10000 ticks in quadrature per rev, and the position is calculated in software in the pc.
i'm trying to do the same with the picaxe and a digital readout, so no need for a pc.

the trick would be knowing how many pulses lead to 360 * 60 * 60 for the readout. that would define resolution of the system.

i was thinking of setting that as a variable in the program and then using that to calculate position.
360 * 60 * 60 is 1296000
with gearing and a 1080 slot wheel ( can be printed using the encoder wheel program in this forum), we can get around 64800 cpr ( 1080 slot wheel * 15 gear multiplication * 4 quadrature)
need to relate that to 1296000, so i need to increment the counter by that factor to get position.
1296000 / 64800 = 20
the resolution would therefore be 20 arc secs which is not great but sufficient to get the object in your eyepiece if you know the co-ordinates with a star program like stellarium

storing the position is not needed, as it would need to be reset when the scope is mounted.

so for every leading edge of the pulse and trailing edge, the counters would need to increment by the resolution factor.
the way to reset it would be to point the scope to a known star in the southern hemisphere that does'nt change, and by pulling a pin high, set the counters to the stars position. eg, if it is meant to be at 60d 42m 30s, by pressing a button, the counters would be set to that value instead of zeroes.

david's ek box does this with a pic and his program.
thought it should be possible with a 28x2.
 
Last edited:

alistairsam

Senior Member
I know nothing about telescopes, but,
what is

David's ek box ??


e
hi sorry about that. habituated to posting in astronomy forums.
its actually david ek's box,
he's designed a pic based program that reads output from an encoder and translates that to position info serially to a pc, he's developed his own drivers so the position information can be ported to compatible software.
the result is that software will then know where your scope is pointing and can move the motors to where you want it.

http://eksfiles.net/digital-setting-circles/circuit-description/
http://eksfiles.net/digital-setting-circles/

while i don't intend to do all that, i just needed a "pc free" solution of reading and displaying my position on a handheld box.
 

boriz

Senior Member
Should be fairly easy to hack an old ‘ball’ mouse for its encoders. Just dremel the relevant parts out of the mouse, retaining (or subsequently reproducing) their mechanical arrangement. Then use a belt (or elastic band) from your telescope axis to the thin shaft of the slotted code wheel. Should be able to get great resolution. When using belt drive, there will inevitably be some drift, but if, as you say, the co-ordinates will be calibrated frequently, that shouldn’t be a problem.

A Picaxe might not be fast enough to count the quadrature if you move it quickly though (high rez = fast code wheel). Should be easy enough to lash up a test rig. Basic Picaxe quadrature reading code here: http://www.picaxeforum.co.uk/showthread.php?t=15803
 

alistairsam

Senior Member
hi
thanks. was testing with mice sensors and a pulley system to the slotted wheels.

for the code, if i define a variable at the start which specifies the resolution, eg. 12000, this is to define that 12000 counts make 360 deg, how can i break this up into deg min and sec.

eg, if 3600 pulses have been received, 3600 / 12000 * 360 should give the relative angle, but I need to convert it to deg min and sec with the relationship
360 deg = 360 * 60 * 60

not sure if I should increment / decrement the deg min sec variables linearly or increment / decrement after the division as above.

will try to rationalize the approach first.
 

boriz

Senior Member
If you want resolution to one second, then that’s your base unit. Do all your calculations in seconds. Unfortunately Picaxe variables are limited to 65535 maximum (16 bits) and you need to count up to 1296000 which is about 20 times too much. So, the easy way is to use 20 seconds as your base unit, and all calculations are based upon that. EG: 1 minute = 3 units. 1 degree = 180 units.

Now all you need to do is establish the axis-to-encoder shaft gear ratio. If we stick with 1 click per unit (one slot passes the encoder detector for each 20 degree unit), then the required axis-to-encoder gear ratio should be 65535/n, where n=number of slots on coder wheel. (I think. Maths is not my strong suit.)

You can expect some small rounding errors, but they can be ironed out a number of ways.

You could go the not so easy route and write some 24bit maths routines, or use an external maths coprocessor, for resolution down to 1 second. In fact a coprocessor would probably be handy for all sorts of astronomical calculations. But for a quick lash-up test rig, I’d go for the 20 second unit.
 

alistairsam

Senior Member
If you want resolution to one second, then that’s your base unit. Do all your calculations in seconds. Unfortunately Picaxe variables are limited to 65535 maximum (16 bits) and you need to count up to 1296000 which is about 20 times too much. So, the easy way is to use 20 seconds as your base unit, and all calculations are based upon that. EG: 1 minute = 3 units. 1 degree = 180 units.
Thanks Boriz,
The limiting factor is not actually the math, but the resultant encoder resolution after encoder gearing.
its next to impossible to have 1296000 ticks per revolution even with quadrature (would require over 3000 lines and very high gear ratio), so the realistic resolution would be 20 arc seconds.
so basically one pin state change would increment or decrement the counter by 20 arc seconds. and I can't use 1 minute = 3 units as above, as the shaft would have gone through actual 20 arc seconds, so 1 minute would be 60 arc seconds and 1 degree would still be 60 minutes.

if i have a simple counter to count upto the resolution, eg 20000, i have to figure out a way to somehow translate that into deg min and secs most probably mathematically or in binary or somehow update three variables like a cascade counter, only they flip and reset at 60.

not sure if I'd need a math co processor, as the seconds don't exceed 60, so do minutes, and degrees don't exceed 360.
the true resolution also won't exceed 65535. it would be more likely between 20000 and 50000 depending on slits/lines and gearing.
 

alistairsam

Senior Member
just did a search on converting decimals to deg, min, secs and this is the formula

40.3472 degrees.
to express that in units of degrees, minutes, and seconds?

there are 40 full degrees. That leaves 0.3472 degrees.

how many minutes is 0.3472 degrees?
60 * 0.3472 = 20.832
thats 20 mins

remainder is 0.832 secs
thats 60 * 0.832 = 49.92 secs

so 40.3472 deg = 40 deg 20 mins 49 secs

theory is that if I set the encoder resolution in the begining to say 20000, then I can increment or decrement the counter, and then take that value and convert to deg min secs with the following formula

current counter value * 360 / resolution

eg.
2432 * 360 / 20000

or 2432 * 36 / 2000 (provided resolution is over 9999 which it will be)

this results in 43.776 which has to be converted to deg min secs as above.

can this be done with a math co processor?


else, other approach would be to increment 3 counters instead of a linear counter which might be easier.
 

alistairsam

Senior Member
tried the 3 counter approach with this code. it works fine, except for two issues
at the start, when sec is 0, and direction is ccw, it deducts 1 from 0 to give 255, where it should deduct 1 from 0 and get to 60.
other issue is that christophe's code waits for both pins to get to 00 before getting pin status. whereeas the actual truth table of the pins is
01
00
10
11
in the forward direction.
and for quadrature, both leading and trailing edges of both pins have to be accounted for.



Code:
symbol getBits   = b0 
symbol dir       = b1
symbol counter   = b3
symbol secd = b4
symbol mint = b5
symbol degr = b6
counter = 1
secd = 1
mint = 1


setint %00000010,%00000010 'interrupt on pin1 high only

main:
  do
   pause 10
  loop
  
interrupt:
 bit2 = pin2: bit1 = pin1       
 getBits = getBits & %000000110 
 if getBits <> 0 then           
  dir = bit2 * 2                
  counter = counter + dir - 1   
  gosub incrmnt
  do while getBits <> 0         
   getBits = pins & %000000110
  loop
 endif
 setint %00000010,%00000010     
 return
 

incrmnt:
second:
  if secd=60 then goto minute 
 secd = secd + dir - 1
   sertxd ("deg",#b6," ","min",#b5," ","sec",#b4)
  return

  minute:
  let secd = 0
  if mint = 60 then goto degree
  mint= mint + dir - 1
  sertxd ("deg",#b6," ","min",#b5," ","sec",#b4)
  return
  
  
  degree:
  let mint = 0
  if degr = 360 then let degr = 0
  Endif
  degr= degr + dir - 1
  sertxd ("deg",#b6," ","min",#b5," ","sec",#b4)
   return
 

Jeremy Leach

Senior Member
I really think the limitation is going to be with the execution speed. I think you need to strip everything down to the minimum. The fastest possible code I can think of is based on a lookup table of OLD and NEW encoder values (using Gray code) :
Code:
[FONT=Courier New]OLD NEW| DIRECTION[/FONT]
[FONT=Courier New]-------'----------[/FONT]
[FONT=Courier New]00 10  | -1 [/FONT]
[FONT=Courier New]00 00  | 0[/FONT]
[FONT=Courier New]00 01  | +1[/FONT]
[FONT=Courier New]01 00  | -1[/FONT]
[FONT=Courier New]01 01  | 0[/FONT]
[FONT=Courier New]01 11  | +1[/FONT]
[FONT=Courier New]11 01  | -1[/FONT]
[FONT=Courier New]11 11  | 0[/FONT]
[FONT=Courier New]11 10  | +1[/FONT]
[FONT=Courier New]10 11  | -1[/FONT]
[FONT=Courier New]10 10  | 0[/FONT]
[FONT=Courier New]10 00  | +1[/FONT]
We can re-sort this table so that the combined OLD and NEW values represent an address in EEPROM, and the DIRECTION value is the value held in EEPROM (replacing -1 with 255)

Code:
EEPROM
ADDRESS    | DIRECTION VALUE
-------------------------------
0000          | 0
0001          | 1
0010          | 255
0100          | 255
0101          | 0
0111          | 1
1000          | 1
1010          | 0
1011          | 255
1101          | 255
1110          | 1
1111          | 0
Notice there are gaps in the address (but that doesn't matter, we are only using 12 out of the 16 addresses).

Bung this data into EEPROM.

Forget dealing with Degrees/Mins/Seconds as your counter. Instead, work with a Word value, and accept that your best resolution is 65535 counts per revolution = (360*60*60) /65535 seconds = 19 seconds

Have the encoder bits directly coupled to input pins on the PICAXE. Then your code can reduce to:

Code:
Symbol Counter = W0
Symbol Direction = B2
 
Main:
Read Pins, Direction
Counter = Counter + Direction 
 
Goto Main
Then have a translator that translates a Word Value to Degrees/Mins/Seconds as needed (but only as needed so it won't slow down the core routine).

EDIT: Sorry, this won't work. The 255 value can't be used as '-1' because the calculations are 16bit. 65535 is '-1'.
So instead, it would be better to offset the direction values by +1 (ie -1 = 0, 0 = 1, +1 = 2)
Then the code would be:
Code:
Counter = Counter + Direction - 1
 
Last edited:

alistairsam

Senior Member
Hi Jeremy,
will try, but the whole objective is to display every state change, that means that the translator will have to be invoked at every cycle to read the new counter value, convert that to deg min secs which involves additional calculation.

so the cycle would be,
read pins, update direction
update counter with counter + direction
translate counter value to deg min sec
display
return

one factor is that the rate of pulses won't be too high as the rotation is very slow, one rotation would take atleast 10 full seconds.
I'm not coupling the encoder to the motor shaft, but am coupling to the main telescope shaft, there will be gearing , but won't be high.

if the picaxe is running at 64Mhz, would you still think there would be an issue with execution delay? is there any difference between a 28X2 and 40X2 at max clock speed in terms of execution, as I don't have to stick to the lower end.

the actual resolution i'd be using would be 40000 at most.

other issue is with the math to convert the word to deg min sec, it involves decimals, would it be easier with a co-processor ?

will test this with some mice encoders tonight if i can and post results.
but I don't have a display, will lookup how to send serial data to the pc port.
 

Jeremy Leach

Senior Member
Unfortunately I think you're running into trouble here. One rotation in 3 seconds. That's 65535 counts in 3 seconds or 1 count in 3/65535 seconds (0.045ms). I really don't think this will be acheivable I'm afraid.

One option would be to have separate electronics for the encoder, which holds the counter value, then read this value into the PICAXE. This would be a project in itself to make one though.

I think you might need a re-think about your design.

If it was me, I'd work backwards. I'd time the code loop that I've given (or if you insist, the degrees/mins/seconds code), then you know the maximum rate at which the PICAXE can process the incoming encoder information.

Then from that, you can work out the maximum resolution, based on one rotation in 3 seconds, that your PICAXE system will be capable of working to.

Oh, and remember, that 'Any' hops out of the core routine to other routines while the shaft is turning will result in missed counts - which could be a serious problem !! It might be an idea to have a separate PICAXE dedicated to working out the Counter value form the incoming encoder data. It's sole job would be to do this, then perhaps output the count values at regular intervals (Serout?) to another PICAXE.
 
Last edited:

alistairsam

Senior Member
Unfortunately I think you're running into trouble here. One rotation in 3 seconds. That's 65535 counts in 3 seconds or 1 count in 3/65535 seconds (0.045ms). I really don't think this will be acheivable I'm afraid.
Hi jeremy,
I had a read through and the realistic resolution would be 22000 counts per revolution, but as telescope slew speeds are not high, it would take between 50 and 90 secs for full 360 deg. There are mounts faster than that, but with all the load, its better to keep slew speed low.

that given,
1 rotation in 60 secs
22000 pulses in 60 secs, thats 1 pulse every 2.7msecs. its bound to be lower than that, but I'd say that'd be the highest rate of pulses.

found some timing info here
http://www.picaxeforum.co.uk/showthread.php?t=618

if the 28x2 is run at max clock speed of 64M, would you say it'd still be inadequate to process 1 pulse every 2.7msecs?

I guess I'll truly know only if I test it, I should be able to in a day or two.
will try both approaches, your eprom table, and the 3 variable approach.

could mpep's code below be used for direction similar to your eprom table? not sure which would be faster , i don't understand the reason behind the XOR though.

Code:
do
        b1=b0
        b0=pins & %11
    loop until b0<>b1
    b1=b1&%10/2^b0&%1
    if b1=1 then
        'encoder rotated one click clockwise
    else
        'encoder rotated one click anti-clockwise
    endif
loop
 

Jeremy Leach

Senior Member
That's coming into the realms of possibility, but I'm still not convinced.

What you've got to realise here is that using a PICAXE to try to keep track of code wheel counts is EXTREMELY intensive processing - requiring uninterrupted, fully focussed, attention from the PICAXE.

So, the key to your design must be to ensure that the PICAXE is left alone to focus on this task as much as possible - otherwise there will be errors.

So I suggest having one PICAXE dedicated to this task as a 'slave' to a master PICAXE. The slave mindlessly sending regular updates of counter value to the Master. But even this presents a problem - because this transmission to the Master will take time.

So what's the quickest way to transmit to the Master (from the Slave's point of view)? Well this is just a guess, but maybe by using the output pins on the slave as a parallel connection to the master. i.e set the pins all in one go from the slave, then the Master reads these pins at it's leisure. Depends on the number of output pins of course, and there would be issues with the master reading potentially changing values - but it might be possible to overcome these issues.

Basically you need the slave executing as least code as possible, with no branches off to do anything else.

This is just an idea for what could be the quickest Slave code. It sends the different bytes of the Counter value alternately to the 8 output pins of the PICAXE. It's then up to the Master to decipher this - but I think it would be possible. I've deliberately written the code in a repeated way without putting the repeating element in a subroutine, because this will be fastest - and that's what matters here.

Code:
Symbol EncoderValue  = b0 
Symbol Direction   = b1
Symbol Counter   = w1
Symbol CounterLSB  = b2
Symbol CounterMSB  = b3
Do
 'Calculate new Count value and transmit CounterLSB to Master
 EncoderValue = pins
 Read EncoderValue,Direction
 Counter = Counter + Direction - 1
 pins = CounterLSB
 
 'Calculate new Count value and transmit CounterMSB to Master
 EncoderValue = pins
 Read EncoderValue,Direction
 Counter = Counter + Direction - 1
 pins = CounterMSB
Loop
 
Last edited:

alistairsam

Senior Member
Thanks Jeremy, will try your suggestion.
i want to test some code with actual sensors and slow pulses at first, and then try and reach the upper limit to see what speeds it skips counts at.
Tarzan, did'nt really understand what the chip does or how it would help by changing pulses to clock pulses. not sure how the chip would reduce processing as the picaxe would need to read the counter value and display it the moment there is a change in encoder signals.

Would Evan and hippy's finite state machine code be realistic for this application as I read its meant to speed up execution times.
http://www.picaxeforum.co.uk/showthread.php?t=5380
 
Last edited:

hippy

Technical Support
Staff member
The advantage of the decoders are that they handle all the transition detections and delivers just two inputs the PICAXE has to act upon; an up or down increment ( or change plus direction ). That takes all the 'state processing' out of the PICAXE so should speed things up tremendously.
 

Jeremy Leach

Senior Member
Good idea on the testing.

I haven't got my PICAXEs set up at the moment, but if I did have I'd run my last code outputting 255 and 0 alternately (ie hack the lines that output the MSB and LSB bytes of the Counter variable). This should give a square wave output, and then use a scope to measure the width of this square wave and then work out the execution speed and the maximum possible sampling rate (count rate). Or, you could use another PICAXE to pick up this square wave output, and use the 'Count' command to record how many counts in a second and work it out without a scope.

I can't think of any way of making the code faster - the state machine idea is very good and I've used it myself, but it will slow it down. Unless I'm missing something.
 

boriz

Senior Member
...could mpep's code below be used for direction similar to your eprom table? not sure which would be faster , i don't understand the reason behind the XOR though.

Code:
do
        b1=b0
        b0=pins & %11
    loop until b0<>b1
    b1=b1&%10/2^b0&%1
    if b1=1 then
        'encoder rotated one click clockwise
    else
        'encoder rotated one click anti-clockwise
    endif
loop
Hey, that's my code. How did you get the impression it was Mpep’s?. And there's a missing DO command before b1=b0. XOR is how the direction is determined. It’s the fastest way I have found so far to decode quadrature, Jeremy’s lookup might be faster though (bugger).
 

boriz

Senior Member
I rememberd hearing (long long time ago) about hardware XOR logic gates being used for quadrature decoding and when I (recently) wrote this code I did some Googling to get a better understanding of the method. Quadrature has two outputs, A and B. Direction is determined by XORing the new B with the old A

&#8220;I had a read through and the realistic resolution would be 22000 counts per revolution&#8221; How did you arrive at that?

Here&#8217;s another approach:

You can get 1 arcsecond resolution by separating the variables. Say one variable for degrees and one for arcseconds, ignoring arcminutes for the moment. That&#8217;s 3600 arcseconds = 1 degree. So you can have something like this:

Code:
&#8216;pseudo code
Do
   Read quadrature
   Increment seconds
   If overflow, reset seconds and increment degrees
Loop
But then we come back to the speed problem. 360 degrees = 1296000 arc seconds = at least 1296000 quadrature pulses. If it takes 60 seconds (time) to rotate the axis 360 degrees, then that&#8217;s 1296000 pulses in 60 seconds (time) = 21600 pulses per second (time) = approximately one pulse every 42 microseconds (time).

That&#8217;s not much time. Certainly far less time than is required to update a display. Maybe a 64MHz Picaxe could do it? I don&#8217;t know, you&#8217;ll need to ask Hippy.

You could compromise and work to 10 arcseconds resolution, then everything is ten times easier and you&#8217;d get 420 microseconds (time) per pulse. Probably still not enough time to update a display and remain synchronised though.

I honestly can&#8217;t think of a solution that does not require either a significant compromise on speed/resolution or some external logic, such as the device suggested by Tarzan plus some counter ICs. Maybe you can slow down the telescope drive?
 

hippy

Technical Support
Staff member
XOR is used in quadrature detection and other signal edge detection - The output of a single bit 'x XOR y' will be 0 when x = y and 1 when x <> y so it's a quick means of telling if 'now' (x) has changed compared to 'last' (y).
 

alistairsam

Senior Member
&#8220;I had a read through and the realistic resolution would be 22000 counts per revolution&#8221; How did you arrive at that?
Hi,
calculated as below

1080 line quadrature pattern printed using the encoder generator I found on this forum,
1080 line should yield 1080 * 4 pulses = 4320 pulses (not very sure if this is correct or it should be 2160)

4320 * 5 (gear multiplication (pulley)from scope shaft to encoder shaft) = 21600 pulses.

21600 pulses every 60 seconds, 1 pulse every 2.7 msecs

again, in reality, the resolution required would be half that.
computer controlled scopes work well with the 10000 cpr encoders from USdigital.

i'll start looking out for the chip that tarzan mentioned and it might make things a lot easier, so the picaxe would just need to take care of counting and displaying.
i'll try both approaches, converting an integer to deg min sec and displaying or updating 2 variables as you mentioned and displaying as 3 values.

would it be faster if I used 7 segment displays instead of serial ones?
I will need to use LED and not LCD as it will be used in the dark most of the time, unless I can get an LCD with red illumination (can't use other colours, need to maintain the eye's dark adaption at dark sky sites)

will post results in a day or two.

just to reconfirm, can I get the picaxe to output counter values to my PC using the programming cable and sertxd for testing? just till I get the LED/LCD module.
 
Last edited:

alistairsam

Senior Member
I found a pretty interesting IR detector that has a monolithic quadrature IC built in and does all the state logic internally in one package.
it has two outputs, one is a tachometer, so pulses every time there is a change, and the other is direction, high when one direction, low when another,
this might simplify the whole design.

I could have my counter increment on the tachometer pulses and direction pin is high, and decrement on pulses and when direction pin is low.

http://uk.rs-online.com/web/search/searchBrowseAction.html?method=searchProducts&searchTerm=HLC2705-001&x=8&y=15

http://docs-asia.origin.electrocomponents.com/webdocs/0028/0900766b80028701.pdf
 

Jeremy Leach

Senior Member
Good investigation there, but when you think about it unless the external chip holds a counter value and does the counter calculation internally, the PICAXE still has to do pretty much the same (or actually more) intensive work.

If you get a tacho pulse and direction indicator, you still need the code to handle this and manipulate a counter value. I can't really see how this is going to be faster than a lookup table that takes the 'raw' encoder values and immediately delivers the result.

Do you just want the Deg/Mins/Sec value for the LED display? Is that the only reason?

Oh and another point re my code example: I'm not sure about the EEPROM read time versus RAM read time, but if RAM is any quicker then you could always have an initialisation routine to dump the table from EEPROM to RAM, then replace the Read statements with Peek in the code.
 

alistairsam

Senior Member
I will try both Jeremy, I think the detector would make detection a bit cleaner, the thread with the finite state code was talking about jitter.
worth a try though.
good point about the RAM and ROM. I will lookup how to dump it into RAM and that might be faster, thats with the normal detector approach.

i know its not straightforward but can we make a guess of the execution time required for a simple counter as in your code? we can then add delay for sertxd which I think is 33ms from another post.
In the end, if I keep the resolution low enough, it should be able to handle counting and displaying.
what would your recommendation be on running at max clock speed, if I use an external resonator to get 64Mhz, will it make a difference if I use the 28X2 or the 40X2?
end objective is to keep missed pulses to a minimum and get the deg/min/sec display as instantaneous as possible.
i'll test your code tonight with eeprom and also with RAM with normal detectors and see how fast it is.

i'm very keen on getting this working along with the display so will keep testing and tuning.

will serial LCD be significantly slower than a 7 segment display?
 
Top