Using rotary encoder with interrupt

#1
Hi, i have been testing interrupt and it works pretty good and fast but i have some programming issues so far with the looping of interrupts.

First i will decode the rotary encoder with a D flip flop which will give 2 signals; an up-down bit and a pulse for each mechanical rotations of the rotary encoder. The pulse will be used for the interrupt pin on the Picaxe. I have been testing the example code given with the "setint" command and understand it well so far but i need the interrupt to be done as a one shot only for each rotary pulse. Since we have to redo the setint command within the interrupt sub itself, it will repeat again if the interrupt pin is still maintained high after the interrupt sub is finished. If i do not reset the interrupt in the sub it will do just a one shot interrupt but then again you have to reset it eventually somewhere in your code after the pulse has ended.

Besides making the pulse much faster in hardware or making a loop that waits for the pulse to end on the interrupt pin to reset setint, can i use a software trick to prevent interrupt looping?

Anyone in the great Picaxe collective have a trick on this or am i missing something?
Thanks
 

AllyCat

Senior Member
#2
Hi,

Firstly, you haven't said if you're using an M2 or X2 chip, which have rather different interrupt features. Particularly with M2s, a problem is that the only source of interrupts can be an input pin (so additional output pins may be needed to "manage" the interrupt source). Also, the response time to an interrupt can be very variable because of their "polled" nature.

The type of solution may depend on the response times you require, and to some extent the type of Program code you're running (some instructions can block the interrupts for a considerable time). However, my first thought is that you might interrupt on both edges of the
signal from the "one shot". Then the program can be aware when each pulse has ended.

On a related issue, a concern with polling loops is that a pulse might be "missed", but PICaxe does have some mechanisms to detect/avoid that. I have used the "Timer 1 Gate Control" hardware (in M2s), but also (IIRC) one of the PIC's Interrupt SFRs can be used as an internal Latch,, which can be polled (and cleared) even though it can't be used as a PICaxe interrupt source.

Cheers, Alan.
 

hippy

Technical Support
Staff member
#3
can i use a software trick to prevent interrupt looping?
Yes, you can interrupt on a high signal, within the interrupt use a SETINT to next interrupt on a low, and on that set it back to interrupting on a high. You can count the changes on one or both interrupts.

You can even feed the two rotary encoder signals into interrupts and interrupt on all four edges -

https://picaxeforum.co.uk/threads/interrupts-on-both-rotary-encoder-pins-possible.28661/#post-295962

That uses the hardware interrupts available on an X2 but similar should be possible using just SETINT -

https://picaxeforum.co.uk/threads/best-way-to-interface-with-rotary-encoder.30244/#post-314026

Depending on what your input source is, what you are using the encoder for, you may not need maximum rates and may not need to detect all four transitions.

It also shouldn't be necessary to use external hardware and you can just take the two pins into the PICAXE. There are plenty of discussions on the forum for using rotary encoders.
 
#4
While there are many elaborate solutions with or without using interrupts, they often seem to use many conditional branching statements. Reading the direction of a rotary encoder with any PICAXE and responding to this can be done accurately in a loop with just a dozen commands. You just need to use two adjacent input pins and a reasonably tight loop. I posted a solution here.
 

hippy

Technical Support
Staff member
#6
One of the interesting areas of discussion is whether there is a need to have external hardware, Schmitt triggers, flip-flops, or RC circuits, on the inputs to give clean switching and remove switching bounce.

I personally don't think there is, because of the way a quadrature decoder works, and this applies to any Gray Code input; a signal will only change when the other is static. At worse one will see rapidly altering high or lows which may alter the count back and forth when they occur but will quickly settle to what they should be, rather exaggerated -
Code:
     _   _   _________________   _
____| |_| |_|                 |_| |________________
                   _   ____________________   _
__________________| |_|                    |_| |___

0   1 0 1 0 1     2 1 2       3 2 3        4 3 4

---.       .-----.   .-------.   .--------.   .----
 0 |-------|  1  |---|   2   |---|    3   |---| 4
---'       `-----'   `-------'   `--------'   `----
The argument for filtering is, that without, the micro has to keep up and the determined value will be varying rapidly at times.

The first may be valid, and when using interrupts it means control will be taken more frequently away from any other executing code, but missed bounces aren't actually a problem as things end up where they should be even if some bounce is missed.

Varying values when bounce is detected may be problematic in some cases but not all, and it should be possible to filter that out in software where it is.

I would recommend trying it without external hardware, only pursuing adding that if problems do appear. As there's probably a pull-up resistor involved somewhere, adding a capacitor to create an RC would be a good first port of call.

When it's not a pure quadrature system, where it's quadrature-like with pulses occurring close together as a single 'count' tick, and there's a lot of bounce; it could be appropriate to add external hardware, but again I'd try it without and see if there are problems -
Code:
       ____                       ____
____|||    |||_________________|||    |||__________
         ____                       ____
______|||    |||_________________|||    |||________
 
#7
Ok thanks! I have made a small code that flip flop the setint command for high and low. I will post it here after doing some tests but it works as a one shot that resets when interrupt pulse turns low with no interrupt looping.

Now since i want to do a digital pot using the rotary encoder on a picaxe 08m2 that would send the rotary's changing value to an external serial 10 bit DAC, i must avoid all serial types like i2c and SPI because these are based on Picaxe's internal timers which could be corrupt by the interrupt?

So i must use a parallel DAC and communicate to it with an external shift register (SIPO) like a 74hc595 ? In other words make my own serial channel that is interrupt proof right? Anyone knows a serial DAC 8,10 bits that would be interrupt friendly?

Thanks for info, i appreciate
 

hippy

Technical Support
Staff member
#8
I2C and SPI use their own timers so you can use those at the same time as other PICAXE internal timers, and your interrupt would not seem to be using any timers anyway.
 
#9
I2C and SPI use their own timers so you can use those at the same time as other PICAXE internal timers, and your interrupt would not seem to be using any timers anyway.
SPI: Protezoid is using an 08M2 and is discussing the use of 74HC595 (Ie SPI) and the manual indicates that "All (non X1 and X2) parts must use the sample (SPIOUT) program included (overleaf" to duplicate this behaviour". So, Protezoid, you have no option but to use bit-banging to drive the 74HC595. I have used Microchip's MCP42010/MCP42050/MCP42100 SPI pots with PICAXEs in the past.

I2C: As hippy says, above
 

Flenser

Senior Member
#10
i must avoid all serial types like i2c and SPI because these are based on Picaxe's internal timers
You do not have to avoid all serial types.The hardware serial commands HSEROUT & HSERIN do not use Picaxe' s internal timers so they are another option you can consider.
 
Top