ILI9341 and encoders in an Electronic Lead Screw Application

After replacing a bad wall wart power supply, I have the slow feeds working on the ELS. The power supply noise was causing false encoder impulses, which EncoderTool was dutifully counting. However, the impulses were coming in at random times and causing stepper pulses that were too fast for the motor to follow. The stepper was chattering. It sounded like mechanical rattling. Now the supply is a lot cleaner. There is no chatter anymore.

I can also cut coarse and fine threads in imperial and metric. Have designed a PCB for the Teensy and an ILI9341 display. PCB is out of fab right now, just waiting for the boards to be delivered to me. Connectors and project boxes have been ordered. Have designed a bezel for the display. Project is coming along. Overall, pleased with the progress.
 
The power supply noise was causing false encoder impulses, which EncoderTool was dutifully counting.

Do you mean that it ended up with wrong counts (shouldn't happen) or did it rapidly count up/down on the disturbances (I would expect that). Using it in countMode::Half or countMode::quarter should make it immune to this kind of noise, but, would of course reduce the resolution by a factor of 2 or 4 respectively.

Unfortunately, severe noise in the workshop with all those motors running is kind of normal. Back in the days, I tried to use shielded cables for steppers and encoders whenever possible.
 
Encoder Tool counted the noisy impulses correctly to my knowledge. My encoder cable is shielded for both the spindle encoder and the stepper motor encoder. The stepper is a closed loop type.

Tell me more about changing the mode of Encoder Tool. Can this be done at any time, or only at initialization? Say that the spindle is stopped, could I change the mode to half? I have an idea that could use this.
 
Sorry was caught in an endless meeting...

You can set the count mode in the begin function of the encoder. It defaults to countMode::quarter which is the usual setting for mechanical encoders. Changing it later would be possible technically (by changing the lib) but I'd not recommend it since it will confuse the state machine and it takes some encoder edges to resync. So, changing the mode on the fly would probably lead to a wrong count.

For an optical encoder you'd usually use countMode::full which increases/decreases on each edge. CountMode::quarter will increase the counter only if the A/B signals made a full cycle. Thus it prevents any rapid up/down counts on a bouncing mechanical encoder. This could also help for noisy signal lines of an optical encoder. Price is the reduced resolution of course.

Edit: Actually, you do not need to change the lib. You can use the public function setCountMode (see here https://github.dev/luni64/EncoderTool/blob/master/src/EncoderBase.cpp). But it was not meant to be used on the fly the above remark on the probably wrong count is still valid.
 
@luni, thank you for the explanation. If I were to change the countMode, I would zero out the counter, if that would help.

As it turns out, changing the countMode won't help me after all. Reviewing the equations for thread cutting, the only option it seems I have is to reduce the microstep size. This is the only practical way to reduce the ratio of N/D for large pitch threads. (Large pitch as compared to the pitch of the lead screw.) Unfortunately, my stepper motor driver only has physical DIP switches to change the number of microsteps per step. I could patch in an opto-coupler, but that does not sound appealing to me, at least not yet. The stepper motor driver also has some sort of serial input but the manufacturer does not want to publish the details of how to use it.

My program can cut threads from 0.2mm to 5mm pitch. I cannot do 6mm threads because N/D > 1. If you recall the formulas for N and D are:

N = thread_pitch * basesteps/rev * microsteps/step = 6 * 200 * 8 = 9600
D = leadscrewpitch * encoder_resolution = 2.11666 * 4096 = 8669.8666

N/D = (9600 * 15) /( 8669.866666 * 15) = 14400/130048 (both integers) = 1.107 > 1

Reducing encoder resolution makes the N/D problem worse. I need to increase the resolution, or decrease the number of microsteps/step.

Oh well, cannot win them all. Guess I will have to rethink modifying the stepper motor driver with two opto-couplers!
 
Couldn't you simply get a higher resolution encoder?

Perhaps. But one doesn't get something for nothing. Using a higher resolution encoder increases the interrupt rate, which impacts high speed lathe operation. I need to calculate out the interrupt rate and also to determine if I can buy a new encoder for an affordable price. Doubling the rate to 8192, would mean 409600 interrupts/second at 3000 RPM. [ 3000 RPM * 1min/60sec * 8192 counts/rev = 409600 ] That's 2.44us between interrupts.
The encoder is available in (1024, 1200, 1500, 1800, and 2000)*4 counts/rev. I have the 1024. The Teensy 4.1 is pretty fast, but it has to do other things as well!

I will look to see what encoder I need, and what it costs. Thanks for the idea!

These other encoders are about the same price. Now to see which is the lowest one resolution that will work for me.
 
Last edited:
Agreed, 400kHz interrupt frequency is borderline. Just a quick idea: do you actually need the high resolution for normal turning with feed? Maybe you can readout the encoder for threading only and use the zero signal (1pulse per encoder rev) for feed mode?
 
Turns out the limit is the encoder. However, at reasonable speeds, like 2000 RPM and under, the interrupt rate will be 200kHz and under. I have tested to 890 RPM and saw no problems. To go higher, I have to change the belt position on my lathe. I thing if I use 1500 (6000 edges per revolution) encoder, then I have N/D ratios of 0.8 and under.

Usually feed mode is a low N/D ratio so it is not too much action. With 6000 ppr, max RPM (because of the rotary encoder BW) is 4000 RPM. My chuck is limited to 2000 RPM. At 2000 RPM, which is fast for a 200mm chuck, that's 5us/interrupt. At 1000 RPM, 10us/int. Think that is good.
 
Back
Top