Compensating for multiple index pulses per spindle rotation

More
23 Nov 2022 01:30 #257414 by gardonvariety
I'm working on a little Taig CNC lathe and for some reason I thought it was a good idea to put a 2:1 belt reduction between the spindle and encoder, so I'm getting 2 index pulses per rotation of the spindle. As a result, there's a 50% chance that each thread I cut lines up with the previous pass.

Is there a good way to compensate in software? I thought about writing a little module to count index pulses and emit one pulse for every two it sees, but that seems hacky and I was hoping there was a better option.

I found this thread: forum.linuxcnc.org/49-basic-configuration/40459-config-dump where @PCW mentioned the index mask as being used when an encoder is generating multiple pulses per revolution, but I'm not sure how to use it or if the MESA 7i96s supports such configuration out of the box.

Please Log in or Create an account to join the conversation.

  • tommylight
  • tommylight's Avatar
  • Away
  • Moderator
  • Moderator
More
23 Nov 2022 02:00 #257419 by tommylight
Should be easily doable in HAL using a flipflop with one output feeding back to one input.
That should make a divide-by-two counter.
The following user(s) said Thank You: gardonvariety

Please Log in or Create an account to join the conversation.

More
23 Nov 2022 03:17 - 23 Nov 2022 03:29 #257422 by gardonvariety
Ha! Thank you, that was exactly the tip I needed. Ended up being a super simple fix.

For anyone finding this thread in the future, here's what I did:

Set up a flipflop:
loadrt flipflop names=flipflop.spindle-index
addf flipflop.spindle-index   servo-thread


Then replace the existing connection with a detour through the flipflop:
#net spindle-index-enable     <=>  hm2_7i96s.0.encoder.00.index-enable

net flip_flopper <= flipflop.spindle-index.out-not
net flip_flopper => flipflop.spindle-index.data
net flip_clocker <=  hm2_7i96s.0.encoder.00.input-index
net flip_clocker =>  flipflop.spindle-index.clk
net spindle-index-enable     <=>  flipflop.spindle-index.out
 

Hooray! Now my threads will have a predictable number of starts.

Thanks tommylight!
Last edit: 23 Nov 2022 03:29 by gardonvariety. Reason: Fix formatting.

Please Log in or Create an account to join the conversation.

More
23 Nov 2022 03:30 - 23 Nov 2022 03:35 #257423 by gardonvariety
Wait a minute. That didn't work at at. Hmm I think trying to use input-index was probably a mistake.
Last edit: 23 Nov 2022 03:35 by gardonvariety.

Please Log in or Create an account to join the conversation.

More
23 Nov 2022 06:35 - 23 Nov 2022 06:38 #257430 by gardonvariety
Well that took way too long to figure out. I don't know if I could have done it with a flip flop in the end because I believe I needed to store 2 bits of state, but the flipflop was confusing me to no end, so I just wrote a new component for n clear deduplication:

component flag_clr_dedup "A module to match a single set of a flag to N clears of the flag.";

param rw signed clears_per_set = 1 "The number of times the flag must be cleared per time it is set";

pin io bit setter "Set by external input";
pin io bit clearer "Cleared N times by external input";

pin out signed clear_count;
pin out bit flag_set;

function _ nofp;
license "GPL";
;;

FUNCTION(_) {
  if (!setter) {
    clear_count = 0;
    flag_set = 0;
    clearer = 0;
    return;
  }

  if (flag_set && !clearer) {
    clear_count++;

    if (clear_count == clears_per_set) {
      clear_count = 0;
      flag_set = 0;
      setter = 0;
      return;
    }
  }

  flag_set = 1;
  clearer = 1;
}


and then linked it up thusly:
loadrt flag_clr_dedup names=flag_clr_dedup.spindle-index
addf flag_clr_dedup.spindle-index servo-thread
setp flag_clr_dedup.spindle-index.clears-per-set 2

net spindle-index-enable <=> flag_clr_dedup.spindle-index.setter
net spindle-index-enable-clear <=> flag_clr_dedup.spindle-index.clearer
net spindle-index-enable-clear <=> hm2_7i96s.0.encoder.00.index-enable

I don't know if this is the most idiomatic way to do this, so I'd love feedback, but it appears to work.[/code]
Last edit: 23 Nov 2022 06:38 by gardonvariety. Reason: Formatting

Please Log in or Create an account to join the conversation.

  • tommylight
  • tommylight's Avatar
  • Away
  • Moderator
  • Moderator
More
23 Nov 2022 11:36 #257453 by tommylight
You were on the right track....
If i remember correctly, the Q- should be wired to D, clock to index from encoder and Q output to LinuxCNC index.
Do check that, misty on everything lately.
Also use "show hal configuration" from the machine menu to watch the pins.

Please Log in or Create an account to join the conversation.

More
23 Nov 2022 20:34 #257507 by gardonvariety
I think that would have worked if the servo thread was running fast enough to catch the encoder index pulse, but the pulses output by my encoder are so narrow that it pretty much always misses them. As a result I had to use the encoder's input enable interface which just added a lot of complexity.

Please Log in or Create an account to join the conversation.

More
30 Nov 2022 04:06 #258088 by gardonvariety
I tried threading a part again today and got an accidental double start again, so the solution I posted clearly did not solve my problem. The issue I'm realizing now was that I was counting one index pulse for every two that came in, but only once the spindle component had it's index-enable pin set. That meant that I could start counting to 2 on either the 0 degree or 180 degree pulse. 

In order to avoid that issue, I think I'd need my component to be setting the index enable pin on every half rotation, which isn't going to happen if there are 6K index pulses per second.

So I just ordered a bigger pulley. Oh well.
 

Please Log in or Create an account to join the conversation.

Time to create page: 0.061 seconds
Powered by Kunena Forum