Show Posts
Pages: [1] 2 3 ... 7
1  Community / Exhibition / Gallery / Re: PinChangeInt library- To attach interrupts to multiple Arduino (Uno/Mega) pins on: September 02, 2014, 09:43:31 pm
Don't do a Serial.print() inside an ISR. If it does work, consider yourself lucky and stop doing it as soon as possible because things are (were?) problematic when printing from an ISR (but supposedly fixed in IDE 1.5; see ).

Regarding the rest of your question, you stated that you tried the PinChangeInt library and it didn't work for you. This thread is about the PinChangeInt library. The code you speak of was written by someone else so I don't think this is the appropriate place for this question, but perhaps someone will lend you the time and help you out.
2  Community / Exhibition / Gallery / Re: PinChangeInt library- To attach interrupts to multiple Arduino (Uno/Mega) pins on: August 20, 2014, 06:46:06 pm
First you have to study the Mega pinout and figure out which pins and ports are available to you. Have you done this?

It looks like you have two rotary encoders (4 pins total). Is that correct?
3  Community / Exhibition / Gallery / Re: Tigger library released: A library for reading digital switches on the Arduino on: July 31, 2014, 02:00:49 pm
Version 0.2-rc1 has been released. It can be found at . Source code is on Github, zip file is on Bintray. See the Google code page for links and such.
4  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: July 31, 2014, 01:19:34 pm
Announcing version 0.8-rc1 of the AdaEncoder library. See

In this release, I have simple changed the license to the Apache-2.0 license. I also am using Git so the source is on Github, and I'm using Bintray for the zip file downloads. See the Google Code website (linked above) for more details.


5  Community / Exhibition / Gallery / Re: ooPinChangeInt library released: Pin Change Interrupts, object style on: July 29, 2014, 12:26:56 pm
Announcing Release 1.06-rc2 of the ooPinChangeInt library.

This release incorporates a fix from JRHelbert for the Arduino MEGA platform, such that Arduino pins 14 and 15 (on PORTJ) now should work properly. This fix has not been tested, unfortunately, although the code is simple enough that I have high hopes that it works out of the box.

Let me know if you notice any issues.

As usual, the website is at but the source code is now on Github, and Downloads are not on Bintray.

This code will not work with the Due (not to be confused with the Duemilanove), because the Due is based on an ARM Cortex CPU. For that you simply use the attachInterrupt() function.
6  Community / Exhibition / Gallery / Re: PinChangeInt library- To attach interrupts to multiple Arduino (Uno/Mega) pins on: July 29, 2014, 11:26:13 am
Note: I don't have a Mega, so I didn't test ports J and K. If you use it, please let me know if it works. Thanks.
7  Community / Exhibition / Gallery / Re: PinChangeInt library- To attach interrupts to multiple Arduino (ATmega) pins on: July 28, 2014, 01:23:04 pm
After some time, I have updated the library. There is a significant fix submitted by jrhelbert which makes the two Port J pins work properly with the Mega. See

Downloads available at

Bleeding edge source available at
8  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: November 30, 2013, 12:00:53 am
This is actually a feature, not a bug.  smiley-cool  Perhaps it should only have returned a positive or a negative, to indicate any movement since the last query(). But the idea is this:

You have a main routine loop() which takes an arbitrary amount of time to run. Asynchronously, it is interrupted by a rotary encoder going up and down. My thinking is that because of this disconnect, you can't perfectly track the turns of the encoder.

Say I've gone 3 clicks CW and 1 click CCW. Net is 2 clicks CW. Now the main routine does a query(); we discover that we have clicked net CW so we should act on that. Do you want to act on the fact that you've gone 2 clicks CW? Maybe- maybe not. Yes, you have gone CW, so the query() decrements the counter and now indicates 1 click CW. Maybe, while you're processing the first of the two CW clicks, the user actually turns the encoder CCW. Now you are at 0. Do you still want to register the second previous click? I don't know.

If your routine is fast enough, you can query() repeatedly, count the number of query()'s that get you to 0, and move on. But again, based on the disconnected nature of the interrupt and the main loop, I don't want to make any assumptions... that you can act on the current counters fast enough to catch any intermediate moves. If your main routine is slow enough to allow the internal adaencoder counter to accumulate to 3 or 4 clicks, I'm uncomfortable in assuming that it would be able to take the counter and perform 3 or 4 actions. I leave it up to you; drain the counter using repeated query()'s until you get to 0 (should be pretty fast) and then act on that information.
9  Topics / Robotics / Re: Problem: PID speed with wheel encoders and PinChangeInt on: July 07, 2013, 11:02:33 pm
Besides what Aaron wrote, it appears you are using an old version of PinChangeInt. Try upgrading to the latest, which is 2.21beta.
10  Using Arduino / Programming Questions / Re: Errors with AdaEncoder on: July 02, 2013, 08:54:54 pm
Sounds like you got it figured out.

You don't need ByteBuffer to work with AdaEncoder. That's just for me to work with my test code and such. Using it is really an exercise for the programmer; I just include it to be complete. Plus, it's kind of interesting.

You should probably remove the #include from your code, as it's not necessary. (unless you need a ByteBuffer).
11  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: December 22, 2012, 12:35:57 am
Thanks, vasquo. Anyway, your post prompted me to create some test code, and I hope to use this to ensure the integrity of the library in the future... (this works for v. 0.7beta and above only, but the basic algorithm applies to 0.5 as well)

// Version 1.0: OO version

#include <ByteBuffer.h>
#include <digitalWriteFast.h>
#include <ooPinChangeInt.h> // necessary otherwise we get undefined reference errors.
#define DEBUG
#ifdef DEBUG
ByteBuffer printBuffer(200);
#define SWINTR_DEBUG // To debug using software interrupts on your two pins, define this.
                    // Then in your sketch, set your pins as outputs.  Initialize them as you
                    // desire, attach an interrupt, then the interrupt code will be called.
                    // CAUTION: Make sure you do NOT have any switches connected to those outputs,
                    // or you may end up frying your ATmega328!
#include <AdaEncoder.h>

I like to keep this diagram around so I know which Arduino pin
is part of which port.
            PC6  1|    |28  PC5 (AI 5)
      (D 0) PD0  2|    |27  PC4 (AI 4)
      (D 1) PD1  3|    |26  PC3 (AI 3)
      (D 2) PD2  4|    |25  PC2 (AI 2)
 PWM+ (D 3) PD3  5|    |24  PC1 (AI 1)
      (D 4) PD4  6|    |23  PC0 (AI 0)
            VCC  7|    |22  GND
            GND  8|    |21  AREF
            PB6  9|    |20  AVCC
            PB7 10|    |19  PB5 (D 13)
 PWM+ (D 5) PD5 11|    |18  PB4 (D 12)
 PWM+ (D 6) PD6 12|    |17  PB3 (D 11) PWM
      (D 7) PD7 13|    |16  PB2 (D 10) PWM
      (D 8) PB0 14|    |15  PB1 (D 9) PWM
// An encoder for every port
#define ENCD_a 2
#define ENCD_b 3
#define ENCC_a A3
#define ENCC_b A4
#define ENCB_a 9
#define ENCB_b 10

AdaEncoder encoderD = AdaEncoder('d', ENCD_a, ENCD_b);
AdaEncoder encoderC = AdaEncoder('c', ENCC_a, ENCC_b);
AdaEncoder encoderB = AdaEncoder('b', ENCB_a, ENCB_b);

int8_t clicks=0;
char id=0;

void setup()
  Serial.begin(115200); Serial.println("---------------------------------------");
  Serial.println("AdaEncoder test. Assumes detent position is 1,1 (pin a, pin b).");
  Serial.println("Encoder states: 11->01->00->10->11 (== CCW 1 click)");
  volatile uint8_t portmask0=PCMSK0;
  volatile uint8_t portmask1=PCMSK1;
  volatile uint8_t portmask2=PCMSK2;
  PCMSK0=0; PCMSK1=0; PCMSK2=0; // turn off PinChange interrupts for a minnit
  pinMode(ENCB_a, OUTPUT); pinMode(ENCB_b, OUTPUT);
  digitalWriteFast2(ENCB_a, HIGH); digitalWriteFast2(ENCB_b, HIGH);
  pinMode(ENCC_a, OUTPUT); pinMode(ENCC_b, OUTPUT);
  digitalWriteFast2(ENCC_a, HIGH); digitalWriteFast2(ENCC_b, HIGH);
  pinMode(ENCD_a, OUTPUT); pinMode(ENCD_b, OUTPUT);
  digitalWriteFast2(ENCD_a, HIGH); digitalWriteFast2(ENCD_b, HIGH);
  PCMSK0=portmask0; // interrupts back on.

void changeEncoder(uint8_t pin) {
  if (digitalReadFast2(pin)) { digitalWriteFast2(pin, LOW); }
  else digitalWriteFast2(pin, HIGH);

void printEncoderState(uint8_t pina, uint8_t pinb) {
  Serial.print(digitalReadFast2(pina), DEC);
  Serial.println(digitalReadFast2(pinb), DEC);

void loop()
  char inChar, outChar;
  // 00 -> 10 -> 11 -> 01 -> 00
  if(Serial.available()) {
    inChar=(; // get command from serial input
    switch (inChar) {
    case '1':
        Serial.print("B-a "); changeEncoder(ENCB_a); printEncoderState(ENCB_a, ENCB_b);
    case '2':
        Serial.print("B-b "); changeEncoder(ENCB_b); printEncoderState(ENCB_a, ENCB_b);
    case '5':
        Serial.print("C-a "); changeEncoder(ENCC_a); printEncoderState(ENCC_a, ENCC_b);
    case '6':
        Serial.print("C-b "); changeEncoder(ENCC_b); printEncoderState(ENCC_a, ENCC_b);
      case '9':
        Serial.print("D-a "); changeEncoder(ENCD_a); printEncoderState(ENCD_a, ENCD_b);
      case '0':
        Serial.print("D-b "); changeEncoder(ENCD_b); printEncoderState(ENCD_a, ENCD_b);
  while ((outChar=(char)printBuffer.get()) != 0) Serial.print(outChar);
  AdaEncoder *thisEncoder=NULL;
  if (thisEncoder != NULL) {
    Serial.print(thisEncoder->getID()); Serial.print(':');
    if (clicks != 0) { Serial.print("Clicks: "); Serial.print(clicks, DEC); }
    if (clicks > 0) {
      Serial.println(" CW");
    if (clicks < 0) {
       Serial.println(" CCW");

...If I then hit a sequence of numbers in the Monitor screen, I can then demonstrate that the library behaves as expected.

For example, if I hit the following sequence, I simulate switch bounce on the two pins and it registers "CCW" exactly when I expect it:
Number Output
1 B-a 01
1 B-a 11
1 B-a 01
1 B-a 11
1 B-a 01
2 B-b 00
2 B-b 01
2 B-b 00
2 B-b 01
2 B-b 00
1 B-a 10
1 B-a 00
1 B-a 10
1 B-a 00
1 B-a 10
2 B-b 11
  b:Clicks: -1 CCW
12  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: December 22, 2012, 12:08:30 am
Well, I tried using the 0.7beta.  ... But I can't get it to work properly. ... I'm going back to 0.5.

I do have a few questions on the sample MyEncoder in 0.7beta

On Line# 15, we have this code
AdaEncoder encoderA = AdaEncoder('a', ENCA_a, ENCA_b);

but nowhere else in the program is "encoderA" used. What's the purpose of line#15?

Then on line#30, I see this
AdaEncoder *thisEncoder=NULL;

*thisEncoder is used in the loop() program.  But how does Arduino know how *thisEncoder is setup?  We defined encoder pins 2 and 3 for "encoderA", not "thisEncoder".

I'm sorry it didn't work out for you. It is a little more Object-Oriented like, so it's not everyone's cup of tea.

Also I'm sorry I am late in replying. This thread is not intended for support; there is a support link on the page for that. Anyway, I will answer your questions for posterity:

The code is an example that shows you how to set up 2 encoders, A and B. encoderA and encoderB are designed to encapsulate all the important data within, so you can think about "encoders" rather than the pins of your Arduino. It's a conceptual change over version 0.5 of the library, really.

In the old days, then, of version 0.5, the genie() method would fill in the values for "clicks" and "id" for you, so you could then query the variables and ask, "Who turned?  How far?".

Now in version 0.7, the genie() method returns a pointer to an AdaEncoder object. The "thisEncoder" variable is set to NULL on every iteration of loop. Then, if genie() finds a changed encoder, it will send back the pointer to the AdaEncoder object, and now you can do whatever you want with this encoder that you've found. It sends back either encoderA or encoderB- whichever one was turned. "thisEncoder", then, changes its identity to that of either A or B. I have done the simplest thing, which is to have it query itself and return the number of times it was clicked.

By using Object Oriented techniques, you are not bound to if/then statements based on values (like id numbers) of the encoders. Each encoder object intrinsically knows who it is; you can even subclass the encoder and have your subclass do special things simply based on its identity.

On this small of a scale it may be difficult to see any kind of win at all, that I'll grant. But I think it's interesting, and I like the way Object Oriented programming makes me adjust my way of thinking, so I have decided to go that route. Thankfully the AdaEncoder library is simple enough that, in the last year, I haven't moved from the functionality I created in version 0.5. The old one should continue to be useful to people.  Although I do recommend an upgrade of the underlying PinChangeInt library.

13  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: December 21, 2012, 11:46:06 pm
I've encountered a bug with the AdaEncoder (old version).

So you power up, turn the encoder CCW... the counter decrement. All is good.

You stop turning, and then turn one click CW... the counter instead of incrementing as expected, instead decrements! 
Turn it again by another click CW, then the counter increments correctly.
Does this update fix this bug? 

I don't think the update fixes that bug- not directly anyways. The bug actually came from the PinChangeInt library, which was not properly testing the state of the pins when interrupts came in quickly. If you have bouncing switches (yes- if you have a mechanical encoder, then you do have bouncing switches), then quite likely you had some issues.  I recommend you continue to use AdaEncoder 0.5 but update PinChangeInt to 2.19beta or greater.
14  Community / Exhibition / Gallery / Re: AdaEncoder: a library for use with simple quadrature encoders on: December 04, 2012, 10:29:04 pm
Announcing version 0.7beta of the AdaEncoder library. This release incorporates some bugfixes in the ooPinChangeInt library (which it uses).

I have moved the library to using the ooPinChangeInt library because, well, I like OO programming. So using the AdaEncoder library is now a bit different. Check the included "MyEncoder" sketch for an example. Most significantly, instead of calling genie() with reference arguments whose values are filled in, you now call genie() and an AdaEncoder object is returned. Then you query the object for details.

The older AdaEncoder 0.5 will continue to work with the latest PinChangeInt library, which repaired some bugs in the PinChangeInt library itself and makes AdaEncoder more reliable. If you don't like the OO-ness of this release, continue to use 0.5 but make sure to upgrade your PinChangeInt library to 2.19beta or above!
From the Release Notes:
Now works with the latest ooPinChangeInt. Should be much more reliable.

Bugfixes: the clicks variable was supposed to be int8_t, but I had query() and getClicks() returning uint8_t types.

Updated to utilize the ByteBuffer to fill a buffer of text for debug purposes.

turnOffPWM has been moved into its own file, as that code is distributed under the LPGL license. I use the GPL.
15  Community / Exhibition / Gallery / Re: ooPinChangeInt library released: Pin Change Interrupts, object style on: November 30, 2012, 06:07:34 pm
Yeahhh... next version, I guess. We'll see how complicated it gets to do.
Pages: [1] 2 3 ... 7