[SOLVED] Reading two encoders on Leonardo pins A2-A5

I'm building a bluetooth controlled robot using these components:

So far I've managed to get the motors running and control the robot with my phone but I can't get the encoders to work.

The shield takes up most of the Leonardo ports. I'm using ports 0-1 (RX-TX) for the bluetooth module and A2-A5 for the encoders. Each hall-effect quadrature encoder has 4 cables: 2 for power and 2 for outputs A and B. I was able to read the encoders using interrupts when I was using the Arduino MEGA but it's not working with the Leonardo.

Can anyone recommend which code to use to read the encoders?

SOLUTION: Rerouting pin 2 to pin 11 on the shield does the trick of freeing enough interrupt pins (2 and 3 / int.1 and int.0) to read the encoders reliably

Can anyone recommend which code to use to read the encoders?

Some code running on the Mega.

I think that the interrupts used for the MEGA code might be "busy" on the Leonardo because the same code doesn't work. On the MEGA I was using interrupts #2-5 to read the encoders on ports 18-21. On the Leonardo I'm using ports A2-A5 but the interrupts don't work (maybe they're taken by the bluetooth module or the motor shield?).

lothas: I think that the interrupts used for the MEGA code might be "busy" on the Leonardo because the same code doesn't work. On the MEGA I was using interrupts #2-5 to read the encoders on ports 18-21. On the Leonardo I'm using ports A2-A5 but the interrupts don't work (maybe they're taken by the bluetooth module or the motor shield?).

The Mega is very different from the Leonardo. You need to examine the Atmel data sheet for the ATmega32u4 MCU in the Leonardo to find out which pins are suitable for use as interrupts.

Also you need to study the program that worked on your Mega to find out how it was using the interrupts.

I would be surprised if code written for a Mega would transfer to a Leonardo without a lot of work.

...R

On http://arduino.cc/en/Main/arduinoBoardLeonardo it says that:

External Interrupts: 3 (interrupt 0), 2 (interrupt 1), 0 (interrupt 2), 1 (interrupt 3) and 7 (interrupt 4). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.

Same goes for http://arduino.cc/en/Reference/attachInterrupt (0-3 + 7) Ports 0, 1 and 7 are taken by the BT module and motor shield: So the only pin left would be 3, right?

The question was why do you want to switch to the Leonardo when the Mega was doing everything you want?

The Leonardo has a smaller form factor. I'd actually like to go even smaller but those are the two that we have available at the lab for now.

Ports 0, 1 and 7 are taken by the BT module and motor shield:

So the only pin left would be 3, right?

Isn't 2 also available?

The BT module probably needs to be connected to pins 0 and 1 because they are the Serial! Rx and Tx pins

I have no idea whether the motor shield needs an interrupt pin, or is just using 7 for convenience.

One of the inconveniences of shields is that they occupy pins in an inflexible way. If you made your own connections you might be able to use different pins and free up the specialized pins.

You might be able to free up pins 0 and 1 by using SoftwareSerial to communicate with the Bluetooth module - but I haven't checked if it works on a Leonardo.

...R

That's what I figured... One option is to reroute pin 2 of the shield to A5 and move the A pin of each encoder to pins 2-3 to use the interrupts.

The other option, like you mention is to read the encoders on pins 0-1 and use SoftwareSerial for Bluetooth. The problem with this option is that reading the bluetooth signal with SoftwareSerial will work as well as reading the encoders inside loop(), right?

I'll try option one and post the results

The Leonardo has direct interrupts for portD[0..3], portE[6] It has pin-change interrupts for portB[0..7]

This translates to Arduino pin numbers D2/D3/D0/D1/D7 and for pin-change ints Arduino pins SS/SCLK/MOSI/MISO/D8/D9/D10/D11

[ assuming I've not made a mistake - datasheet and Arduino sourcecode is definitive ]

Running high speed encoders without interrupt pins isn't going to be easy. The only likely method to me is using direct port access from a timer interrupt routine that runs fast enough never to miss a transition. A2..A5 are all on portF so can be read simultaneously with

  byte port = PINF & 0x33 ;

So I just rerouted pin 2 on the shield to pin 11 (which was free) and now I can use pins 2 and 3 as interrupt pins (on int.1 and int.0, respectively) to accurately read the encoders.

Thanks to everyone who gave their 2c!

lothas: I was able to read the encoders using interrupts when I was using the Arduino MEGA but it's not working with the Leonardo.

Hi lothas, Can you share the code that you implement in Arduino Mega to read both quadrature encoders using interrupts, please?, or could give me the link to read it.