Shop OBEX P1 Docs P2 Docs Learn Events
Baffled by Prop-2 Quadrature Encoder — Parallax Forums

Baffled by Prop-2 Quadrature Encoder

JonTitusJonTitus Posts: 193
edited 2020-05-31 04:07 in Propeller 2
I have tried to write a short assembly-language program to collect a quadrature-encoder count over 2 seconds as an example to help update the Smart-Pin documentation. I have LEDs on eight pins as a testing device:
'Example Quadrature Encoder Rev. 1.  05-30-2020
COM
               
dat
         org	 0               
	 mov dira, ##$FF			'Set P15..P8 as outputs for LEDs
         mov outa, ##$AA			'test pattern for 8 LEDs, they light properly
               
        dirl     #32				'Setup Smart-Pin at P32
       	wrpin    QuadEnc_Config,    #32		'Set configuration for Quad-Encoder mode
       	wxpin    X_RegData,         #32		'Set operating condition for period
       	dirh     #32				'Finished setup       
		 nop				'short delay
		 nop

.myloop		nop
.wait_here	testp #32 WC			'Test carry at Smart-Pin P32
		nop
     if_nc	jmp #.wait_here			'No carry? Loop
		rqpin QuadEnc_data, #32 	'Get total counts
		nop
		
		mov 	outa, QuadEnc_data	'send to LEDs			
		jmp	#.myloop		'Program waits forever

QuadEnc_Config	long	%0000_0001_000_00010_00000000_01_01011_0  'Quad encoder mode, sets B as pin 32+1 (33)	
X_RegData	long	$02FA_F080				  'Set 2-sec  sample period (25 MHz clock)
QuadEnc_data	long	$0

Obviously I have not set up the pins properly and don't know how to. I have a P2 EVAL board. Pin P32 receives one encoder output, P33 receives the other. The encoder's common connection goes to EVAL ground. The encoder is fine. I can see the proper signals when operated as a stand-alone device. The P32 and P33 connections have external 1K-ohm pullup resistors. I have used a scope to monitor the P32 and P33 signals (see attached image.) When I start the program and rotate the shaft, I can see the proper pulses on the P33 input. The P32 input, though, drops to a logic-0 at the proper time, but it stays at logic 0 for as long as the program runs. If I take another scope image as the program continues to run, P32 remains "locked" at logic 0.
Feel free to offer a different simple program or to modify mine. All assembly language, please. Thank you. --Jon


Comments

  • JonnyMacJonnyMac Posts: 8,924
    edited 2020-05-31 04:11
    Sorry, not assembly, but might still be helpful. I have tested this on the P2 Eval board.
  • You are setting pin 32 as an output.
    Remove the %01 from the %TT bits
    	QuadEnc_Config	long	%0000_0001_000_00010_00000000_00_01011_0
    
  • evanhevanh Posts: 15,187
    The set bit in the middle isn't useful either.
    QuadEnc_Config	long	%0000_0001_000_0000000000000_00_01011_0
    
  • Thank you all for your help. I missed the TT bits. --Jon
  • Thanks again for the info about the mode-configuration bits. A slight problem, though. The Smart Pin circuit counts each edge of the two signals from the encoder. So, one click to the next detent produces a count of 4. I can watch the LEDs show an increasing count, 1, 2, 3, 4, as I slowly rotate the shaft from one detent to the next. (I can see the four signal edges appear on my scope, too, at 5 sec/div). This is odd behavior for a quadrature-encoder "decoder" circuit. I have never run into this type of pulse decoding. Has anyone else? Is this standard? I've used encoders with circuits and software but it was always one pair of pulses, one increment. --Jon
  • JonnyMacJonnyMac Posts: 8,924
    edited 2020-05-31 20:20
    It's a mechanical thing in the encoder -- I have commentary about that in my object and a setting that deals with it. I have run into this many times, hence the feature to accommodate encoders that behave in his manner.
    Dealing with it in code:
      result := (rdpin(apin) sar mod4x) + offset
    
    If it's an encoder that delivers four counts per detent, setting mod4x to 2 will fix things so that each "click" gives a single count (mod4x is 0 otherwise).
  • Thanks, Jon. Another question for the group... The information about the quadrature-encoder instructions that state:
    If a non-zero value is used for the period, quadrature steps will be counted for that many clock cycles and then the result will
    be placed in Z while the accumulator will be set to the 0/1/-1 value that would have otherwise been added into it. This way, all
    quadrature steps get counted across measurements. At the end of each period, IN will be raised and RDPIN/RQPIN can be
    used to retrieve the last 32-bit measurement.

    Where is the accumulator and how do programs access it?
  • evanhevanh Posts: 15,187
    That is the correct way encoders are meant to work. Anything less is just nerf'ing them.

    The accumulator is internal to the smartpin. Z gets a direct copy if X = 0, otherwise Z gets the delta of the accumulator for the prior X period.

  • Thanks, evanh. I never knew that about incremental encoders!

    I understand the Z=0 case for continuous tracking. But I still don't understand the accumulator. In the statement from the documentation, when X is set for a period, say 2 seconds, at the end of that period, Z holds the count result. How can Z also hold the +1 / 0 / -1 information for any transitions that need to get added to the count? How do I get the +1 / 0 / -1 information?
  • evanhevanh Posts: 15,187
    That +-1 is talking about a very precise detail at the exact sysclock of when Z is loaded with the delta when X > 0. Normally the accumulator will reset to zero, but if an encoder edge comes in on the same sysclock as the delta is placed in Z then the accumulator will immediately become plus or minus one, depending on which A/B edge has stepped.

  • evanhevanh Posts: 15,187
    edited 2020-06-01 04:06
    It's the accumulator, not Z, that is receiving this treatment. ... Oh, that then becomes part of the subsequent delta. In your case, two seconds later.

  • cgraceycgracey Posts: 14,133
    edited 2020-06-01 04:14
    Thanks for explaining that so well, Evanh.

    If someone didn't want the two LSBs of the encoder count, they could just divide by 4 or do a "SAR reg,#2".
  • Again, thanks for the good explanations. I thought software would need to get the plus-minus data and then add it to the result from the Z register. Got it! This is an excellent group for assistance. --Jon
  • Is there a mechanism for handling the encoder Index pulse? For the best possible precision, it is usually gated with the A&B channels. Or do we rely on an input as a high-speed latch?
  • evanhevanh Posts: 15,187
    Not in hardware. But any homing routine will be perfectly okay, to the exact count, done in software at low velocity. And any gear-locking only wants a synchronised latch per axis, which can be done in hardware.

  • The low velocity thing is really irritating. Some of the high-end commercial motion controllers only look at the feedback during the servo sample which is commonly 1KHz. Following the Nyquist recommendation, this means a homing velocity of 500 quad counts/sec. In my case, this is 1.6mm/sec. With my P1 solution, I can grab a snap-shot at any velocity.
  • jmgjmg Posts: 15,145
    JonTitus wrote: »

    "If a non-zero value is used for the period, quadrature steps will be counted for that many clock cycles and then the result will
    be placed in Z while the accumulator will be set to the 0/1/-1 value that would have otherwise been added into it. This way, all
    quadrature steps get counted across measurements. At the end of each period, IN will be raised and RDPIN/RQPIN can be
    used to retrieve the last 32-bit measurement."



    I understand the Z=0 case for continuous tracking. But I still don't understand the accumulator. In the statement from the documentation, when X is set for a period, say 2 seconds, at the end of that period, Z holds the count result. How can Z also hold the +1 / 0 / -1 information for any transitions that need to get added to the count? How do I get the +1 / 0 / -1 information?

    That a just complicated way of describing the details of P2's ability to do Capture-and-clear on the counters, in a lossless manner.

    If you do design Capture-and-Clear, there is an aperture that needs manage, of what happens if on the same SysCLK, the counter is being asked to clear and inc/dec ? (rare, but possible)
    In that case, you need to not clear to 0, but to include the count (+1, -1) that would have occurred on that SysCLK.

    You do not need to read that clear value, it is just there, as a correct residual & ready for the next capture.

    All this means you can sample a frequency counter at 10x a second for rapid updates, and run another 10s or 100s background average, that you know has no missed edges.

    In a quad context, you could run two smart pin cells, one as a Quad total displacement, and another for velocity.

    Or, you can continually sum those velocity captures (every X) and get both velocity and displacement with a little SW, and just a single smart pin cell.
    When doing that continual sum in SW, it is important to know you never miss a single quadrature edge event.

  • That a just complicated way of describing the details of P2's ability to do Capture-and-clear on the counters, in a lossless manner.

    Thanks, JMG, that description works... unless you don't know what "capture-and-clear" means. I try to keep explanations easy to understand for people new to the Propeller. These explanations might seem wordy to experts, but I hope they help beginners--like me. --Jon
  • jmgjmg Posts: 15,145
    JonTitus wrote: »
    That a just complicated way of describing the details of P2's ability to do Capture-and-clear on the counters, in a lossless manner.

    Thanks, JMG, that description works... unless you don't know what "capture-and-clear" means. I try to keep explanations easy to understand for people new to the Propeller. These explanations might seem wordy to experts, but I hope they help beginners--like me. --Jon

    Most MCUs have a capture ability on their counters, even 8 bit ones. That takes a snapshot of the HW value, for later inspection by slower SW.
    A small subset of MCUs can optionally clear the counter when they capture.
    If there is no clear, the user can take a difference in software, to determine change since last capture.
    The P2 has that capture-and-clear feature, done in a careful way.
  • evanhevanh Posts: 15,187
    It's a cheap way to produce deltas without loss.
  • evanhevanh Posts: 15,187
    Mickster wrote: »
    The low velocity thing is really irritating. Some of the high-end commercial motion controllers only look at the feedback during the servo sample which is commonly 1KHz. Following the Nyquist recommendation, this means a homing velocity of 500 quad counts/sec. In my case, this is 1.6mm/sec. With my P1 solution, I can grab a snap-shot at any velocity.
    Software triggering on the prop2 can be very precise. You can throw a whole cog at it for something like homing, before all the real action gets going. Although a basic interrupt from an index pulse should be perfectly adequate. The live hardware counter can be read at any time when X=0.
  • 1.6mm/sec is indeed irritating. On a large machine it is like watching paint dry.

    So if the current position is lost and the device needs to run to a home point with whatever end stop it usually crawls along with low velocity to avoid damage at the mechanical(?) endpoint?

    Shouldn't it be possible to get some ruff estimate of the current position (say I am in the 3 eights of available distance) with some second simple encoder or even switches?

    Thus at least running some of the distance at full velocity?

    just asking...

    Mike
  • evanhevanh Posts: 15,187
    edited 2020-06-05 23:06
    Come on guys. The home sensor is not the encoder index pulse. The slow crawl to the home has nothing to do with accuracy of detection. There's a number of options for how to get to the home sensor, including use of the end-of-travel limits, but once there then confidence is restored. This motion doesn't have to be particularly slow, but many are.

    The encoder index, if used at all, is searched for after the home sensor is found. This will normally be a very short distance and the motion can be slow and still hardly noticed.

    If using just the home sensor as the reference then a slow return motion back off the home sensor can be used instead of searching for an encoder index.

    PS: An end-of-travel sensor can double up as the home position.

  • jmgjmg Posts: 15,145
    msrobots wrote: »
    Shouldn't it be possible to get some ruff estimate of the current position (say I am in the 3 eights of available distance) with some second simple encoder or even switches?
    Sure, that's what absolute encoders are for :)
    Quad counters are simpler, but power failure means you are never sure where you are...

  • evanhevanh Posts: 15,187
    edited 2020-06-06 08:19
    evanh wrote: »
    This motion doesn't have to be particularly slow, but many are.
    If encountering end-of-travel is possible during the initial search then the machine has to be able to quickly decelerate and reverse up without hitting the over-travel cut-outs. The distance between the two and the deceleration parameter dictates the maximum velocity. But I doubt such calculations are actually applied to a homing velocity. They'll just use a conservative round number instead because it's not consider worth spending any effort on.

    Another factor maybe obstacles. In the case of CNC equipment the machine doesn't know anything about the materials that might still be loaded when doing initial referencing. Extra slow movement gives time for the operator to intervene before tooling gets broken.

  • evanh wrote: »
    Another factor maybe obstacles. In the case of CNC equipment the machine doesn't know anything about the materials that might still be loaded when doing initial referencing. Extra slow movement gives time for the operator to intervene before tooling gets broken.

    The common strategy is to always lift the vertical axis first to retract the tool out of the workpiece. This avoids collisions in almost all cases. Only if you use a T-slot cutter or a tap you have bad luck...

    If you don't have absolute encoders you could use a low-cost switch that is ideally mounted half a screw revolution before the index pulse of the encoder. You can do the first aproach move with relatively high speed. You just need to make sure that the distance from the switch trigger point to the hard stop is longer than the braking distance.

    You can include something like this in your loop:
    if INA & IndexPinMask
      indexPos:= posCounter
    
    That provides a capture where the last index impulse was detected. When the servo comes to a halt after the home switch search you can read the indexPos variable and there are 3 possible cases:
    • no index was captured. In this case you have to move further with slow speed until an index is found.
    • the last index was less than one revolution behind the trigger point of the switch. This is the desired hom position.
    • the last index is more than one revolution away from the trigger point. You have to add the number of revolutions to get the desired home position.
  • evanhevanh Posts: 15,187
    ManAtWork wrote: »
    [*] the last index is more than one revolution away from the trigger point. You have to add the number of revolutions to get the desired home position.
    Shortens the low velocity search at least. :) That one applies to linear encoders (aka linear scales).

    Lots of possibilities.

Sign In or Register to comment.