0

I took over a project including PIC18f25k80 microcontrollers and incremental encoders. Basically I just need to follow the position of the motor using the encoder, and drive a device to specific locations. I know that there are more methods to read an encoder and update the position. The motor does not turn fast at all, no high speeds are involved here.

If I were to develop the whole thing from scratch, I probably would hang one channel of the encoder to an interrupt pin on let's say port B, and in the ISR I would check for the state of the other pin. To me, this seems to be the cleanest solution, this method probably catches all position changes, correct me if I am wrong.

Another method would be to poll the 2 channels in the main loop. There is not much in the main loop, basically just adjusting the motor speed and direction based on the position, so at slow speeds, I guess that I would not miss position changes, but it bothers me, that it is still a possibility to miss changes in the encoder channels.

A third option could be to initialize a timer interrupt, and in that interrupt routine, I could check for the pin states. This interrupt could occure twice as fast as a state change would occur at the highest speed, so I guess I would not miss any changes with this method as well.

Now that being said, my question is as follows: which option should I chose?

As I said, I would go with the first one, the encoder channels are attached to RB4 and RB5, so I could just enable the interrupts on port B. But as far as I know, and this is where I am not sure, I can only enable the interrupt for the whole port B on a PIC18f25k80, and not for single pins. That means that all pins on port B would create an interrupt, not just the one I want. And not just the other channel of the encoder, but all of the pins on port B are attached to something, and I cannot change the layout, only the software. Do I see it right, that in this case this method is out, because all pins would cause an interrupt on port B and that would be too much overhead?

And the end of my question: if I see the above problem correctly, which method would you chose, polling of fixed timer interrupts? We are talking about 5 rotations per second tops.

Thanks for the answers in advance!

This is the encoder in question: https://www.power-tronic.com/wp-content/uploads/2019/11/Type-Magnetic-Incremental-2019-01-08.pdf

Marcell Juhász
  • 528
  • 3
  • 9
  • 3
    You will probably get better responses here - https://electronics.stackexchange.com/ – OldProgrammer Jan 23 '21 at 19:02
  • Thanks! I will post it there. – Marcell Juhász Jan 23 '21 at 19:13
  • 1
    First I have to correct the misinformation that you think. When you use an interrupt on PORTB, you don't enable it for the all pins of the port. Each interrupt source on PORTB has an individual enable option. For the INTx sources you can enable or disable each of it by writing to related INTCONx registers, e.g. INTCON3bits.INT3IE = 1 to enable INT3 interrupt. For the interrupt on change pins which are in your case, you can enable or disable then by writing to the IOCB register. – Kozmotronik Jan 24 '21 at 08:18
  • 2
    Second is about what method you should use. You stated that the rotation rate is very slow. The answer is actually depending on how fast is your oscillator frequency and how fast your main scanning period. If your main loop does not have a heavy load of work that take lots of times to complete (not meaning the seconds but a few hunderds of milliseconds) you can implement it in your main loop. But if the rotation is 5 times per second, then you shuld sample the pins x4 times to get good sample results. But if your main does not accomodate the time constraints, you should go for the interrupts. – Kozmotronik Jan 24 '21 at 08:27

1 Answers1

1

As a summary of what I have learned from here and the electronics stack exchange:

First of all, interrupt can be enabled and disabled for individual pins as well. On port B the corresponding register that needs to be configured if the IOCB register.

The best option would be to use a PIC that has QEI. Although I cannot change the hardware, only the software, this is a solution that is worth mentioning.

Interrupts should be used for low resolution encoders and low speed applications.

Polling is good for high resolution encoders and high speed applications, but you need to make sure that the main loop fits the time constraints. You can also poll more times in the main loop if the main loop takes longer than desired.

The terms "high" and "low" depend on the actual implementation, for example on the clock speed of the MCU, the resolution of the encoder, the maximum rotation speed of the motor and the structure of the software.

Thanks for the answers!

Link to the same question on electronics stack exchange: https://electronics.stackexchange.com/questions/544340/incremental-encoder-polling-or-interrupts

Marcell Juhász
  • 528
  • 3
  • 9
  • 2
    Just the opposite of this! Interrupts should be used for high resolution and high speed! Interrupts should be used for low resolution encoders and low speed applications. Polling is good for high resolution encoders and high speed applications, but you need to make sure that the main loop fits the time constraints. You can also poll more times in the main loop if the main loop takes longer than desired. – Kozmotronik Jan 25 '21 at 05:29