-->
Page 1 of 4

Keeping up with lots of interrupts (two encoders)

PostPosted: Sun Mar 19, 2017 2:59 pm
by synfinatic
So I have a project for tracking two encoders and making their values available via WiFi to make it easy for people to locate object in the night sky with their telescope. Typical encoders used for this kind of application are between 1K and 10K CPR (clicks per revolution) which translates to 4K to 40K per revolution after quadrature decoding.

I'm currently using 2.5K CPR US Digital encoders: http://www.usdigital.com/products/encod ... y/shaft/S2

On my telescope, I use the 10K CPR version of the same encoder.

The problem is that I'm finding by using interrupts on all four pins, I'm missing events (on CHANGE, the old value == new value). I'm using a MCP1825S (with the recommended caps) to supply power to the ESP-12F and TXB0104 which I'm using to convert the 5V encoder signals to 3.3V for the ESP, so I'm pretty confident this isn't a problem with power which seems to be a common issue.

So I'm hoping to get some guidance.
First, is there anything I can do to improve the performance of my existing code? For example I know digitalRead() on the AVR chips is pretty slow, but sounds like it's much faster on the ESP8266. https://github.com/synfinatic/esp-dsc/b ... sp_dsc.ino

Another option is to stop using the Arduino environment and program directly in C using the ESP SDK. Not sure if that would provide better results?

Alternatively, I can use something like the LSI LS7366R chip to handle decoding of the encoders, but those are ~$5/ea and I'd need one for each encoder which would obviously dramatically increase costs (and those damned chips are not widely available at Digikey/Newark/etc!)

Or possibly, the internal pullup on the ESP GPIO pins are strong enough and I'm just seeing noise? Honestly, I don't think this is the case as dropping interrupts only seems to happen when I'm moving both encoders at the same time.

Any other ideas? Thanks!

Re: Keeping up with lots of interrupts (two encoders)

PostPosted: Mon Mar 20, 2017 10:55 am
by Paul555
Hi

It is not clear are you looking to increase performance or the (lost) interrupts bothers you. I did some programming with two encoders on arduino uno (16MHz). But I solved this in polling way (without interrupts). The performance was quite good. Here we speak about 160Mhz cpu. I do not know what your code is doing (except waiting for interrupts and serving wifi). If it is absolutely necessary to have all four channels attached to interrupts, first off all I'll go for RISING or FALLING events. Secondly, You need only one interrupt per encoder in order to find out when it is turn and then read another channel to determine to which direction it has been rotated. why both channels on separate interrupts?

Re: Keeping up with lots of interrupts (two encoders)

PostPosted: Mon Mar 20, 2017 7:06 pm
by rudy
You failed to give an important piece of information. Time. You have encoders that have lots of resolution but you have not indicated the rate of those transitions. Is the shaft of the encoder rotating one turn per second or one turn per hour? Without that piece of information it is impossible to evaluate your situation.

The ESP8266 has other work it needs to do handling WiFi communications. It is not a dedicated processor for use. It is a shared processor. If your process can't handle the time the ESP is busy then you need other hardware to handle those functions.

You have choices. Special purpose chips like you have found, or a dedicated processor to handle the position data and then pass that on to the ESP. As far as a $5 cost for a special purpose chip, that doesn't sound like it should be a deal breaker. Compare that to the cost of the encoders.

Re: Keeping up with lots of interrupts (two encoders)

PostPosted: Mon Mar 20, 2017 10:13 pm
by synfinatic
So I can't loose interrupts. I need perfect accuracy or there's really no point. It needs to be on CHANGE unless I were to do something strange and connect each encoder channel to two ESP pins and distribute the interrupts across 8 pins instead of 4 (each pin waits on Rising or Falling). Honestly though, I can't imagine why that would help any, but it's been one idea.

The rotation speed is not very fast- approximately 1 rev/sec. Basically, at 80Mhz I have 2000 operations per encoder tick minus overhead for WiFi/etc. That seems like plenty to me. Especially since my code is so tight (my original post has a link to my code.) I've tried running my ESP-12F at 160Mhz and honestly, I can't say I notice any real difference in performance. Honestly, I don't have a signal generator to do a proper test so the best I can do is rotate the encoder by hand.

I haven't tried disabling the WiFi code (currently it just joins an existing network and does nothing), but I could imagine that would help.

One thing I've noticed is that two 2.5K encoders seem to drop interrupts more then a single 10K encoder.

Honestly, my current thought is that the real issue is that when the ISR is executing, interrupts are disabled. This means when you have two encoders, it's possible for multiple interrupts to fire at the same time or very closely together. My understanding is that the ESP8266 will queue the ISR's up, and then execute them in some order. I can imagine that the queue is only so big though.