0
\$\begingroup\$

I have having a bit of difficulty calculating rpm of a motor using feedback from an encoder. The encoder datasheet is attached here: Encoder datasheet.

The encoder has two channels at 1000 PPR, so 4000 PPR that I can count with my FPGA, as I am counting both the rising and falling edges. The max motor speed is 4500 rpm.

I have synchronized these pulse edges with the FPGA 100MHZ clock and I generate a pulse on each rising and falling edge that lasts for one 100 MHz clock cycle. I then have a counter that increments by one on the falling edge of the 100 MHz clock if an edge pulse has been generated. This counter value is clocked into a register every 100 ms which is the count value from the encoder. I then display this count value on a seven segment display to test it.

I have inputted a 20 kHz square wave into the FPGA to simulate one channel of the encoder and the display reads a count value of 4000 on the display. So the hardware on the FPGA end is working perfect, as the counts per 100 ms from 20 kHz is 4000.

I am unsure how I can scale this count value from the encoder mathematically into an RPM value that I can display? At 4000 rpm, the encoder inputs will be 66.6 kHz each. So for around 4000 rpm, the count value per 100 ms will be 26640. I tried to use the following algorithm:

$$ RPM = \frac {(CountValue per 100 ms) (600)} {EncoderPPR} , $$

But to remove the division by 4000 and to shift right to divide by 4095:

$$ RPM = \frac {(CountValue per 100 ms) (600\frac{4095}{EncoderPPR}) } {4095} , $$

So this leaves:

$$ RPM = \frac {(CountValue per 100 ms) (614.25)} {4095} , $$

With the encoder my display is not displaying 4000 rpm so would like to know if anyone can spot a mistake in my calculations.

EDIT

So I actually changed the shift value from 12 (4095) to 14 (16383) and the rpm is not being displayed correctly as far as I know. I have a digital tachometer to measure the speed of the motor shaft as they fluctuate within 2 rpm of each other. I am guessing the extra to shift bits was because 614.25 has two places after the decimal point?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Where does the 26640 come from? Why wouldn't it be 6667 counts per 100 ms at 4000 rpm? \$\endgroup\$
    – Transistor
    Apr 11, 2021 at 12:01
  • \$\begingroup\$ For each channel output frequency that is x number of pulses per second. The number of pulses per 100ms would be x/10. As the encoder has two channels and I count both rising and falling edges, that gives (x/10) * 4. So for a frequency of x as 66.6kHz, that is 26640. That's my thinking anyway, but it might not be correct. \$\endgroup\$
    – David777
    Apr 11, 2021 at 12:19
  • \$\begingroup\$ See edit to question. \$\endgroup\$
    – David777
    Apr 11, 2021 at 12:41
  • \$\begingroup\$ I don't get what those 12 and 14 bits has to do. What is wrong with my answer? \$\endgroup\$ Apr 11, 2021 at 12:46
  • \$\begingroup\$ @MarkoBuršič Nothing is wrong with your answer, it is perfect. I was just curious as to why I had to shift an extra two times. \$\endgroup\$
    – David777
    Apr 11, 2021 at 12:51

1 Answer 1

2
\$\begingroup\$

There are two methods: period and frequency measurement. You have chosen the frequency method. My old books say:

$$f_x = \dfrac{N}{T_M} \pm \dfrac{1}{T_M}$$

Where \$T_M\$ is a measuremnt period (0.1s in your case) and \$N\$ is the number of counts.

$$f_x = \dfrac{RPM_x}{60s}\cdot 4000\ inc$$

$$RPM = \dfrac{60}{4000}\lbrace \dfrac{N}{0.1} \pm \dfrac{1}{0.1} \rbrace$$

$$RPM = 0.15\cdot N \pm 0.15$$

check:

26640*0.15 = 3966, actually it should be 26666 counts to mach my formula.

EDIT:

At 4000 RPM the frequency is 4000*4000/60= 266,666 kHz, so within 1/10s you should count 26666 pulses. Multiply with 0.15 and you get 3999.9 RPM. Next time you will count 26667 pulses that gives 4000.05 RPM, the difference is exactly 0.15 RPM which is the measurement error.

EDIT2:

This is a processor I have developed on the FPGA and the ALU can only divide by powers of 2 so yeah I am not able to divide by 20

That would be easily solved if you would be using an encoder with PPR with power of 2, that's why they do exist. For example 1024 PPR, then you could change the measurement interval so you could get 512/4096. Still you can change the measurement interval to 0.12s then you get:

$$RPM = \dfrac{60}{4000}\lbrace \dfrac{N}{0.12} \pm \dfrac{1}{0.12} \rbrace$$

$$RPM = 0.125\cdot N \pm 0.125$$

Et voila: $$RPM = \dfrac{N}{8} \pm 0.125$$

Set to 120ms and shift right 3 times.

\$\endgroup\$
5
  • \$\begingroup\$ Yeah, so my calculation should work. \$\endgroup\$
    – David777
    Apr 11, 2021 at 12:42
  • \$\begingroup\$ Thank you, this has cleared up my question. I use fixed point arithmetic in my FPGA so I have to use my calculation to divide by a power of two. \$\endgroup\$
    – David777
    Apr 11, 2021 at 12:53
  • \$\begingroup\$ Are you sure, your FPGA can't multiply by 3 and divide by 20? \$\endgroup\$ Apr 11, 2021 at 13:20
  • \$\begingroup\$ This is a processor I have developed on the FPGA and the ALU can only divide by powers of 2 so yeah I am not able to divide by 20 \$\endgroup\$
    – David777
    Apr 11, 2021 at 19:28
  • \$\begingroup\$ @David777 See edit. \$\endgroup\$ Apr 12, 2021 at 7:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.