Error using Encoder library with Pi Pico RP2040

Hey there,

I’m trying to include the Encoder library on a Pi Pico and am getting some errors. The latest version of the Encoder library supports the Arduino Nano RP2040 Connect, so I think it should work with the Pi Pico as well, however I’m seeing a series of errors.
First series of errors that I got was related to the definition of interrupts, as follows:

.pio\libdeps\picow\Encoder/utility/interrupt_pins.h:390:2: error: #error “Interrupts are unknown for this board, please add to this code”
390 | #error “Interrupts are unknown for this board, please add to this code”
| ^~~~~
.pio\libdeps\picow\Encoder/utility/interrupt_pins.h:393:2: error: #error “Encoder requires interrupt pins, but this board does not have any :(”
393 | #error “Encoder requires interrupt pins, but this board does not have any :(”

To fix this, I defined a build flag ARDUINO_NANO_RP2040_CONNECT for the Pico.

I thought that would work, however, I started getting a different error then,

C:\Users---------.platformio\packages\framework-arduinopico\cores\rp2040\SerialPIO.cpp:385:19: error: ‘SERIAL3_TX’ was not declared in this scope
Compiling .pio\build\picow\FrameworkArduino\api\Stream.cpp.o
385 | SerialPIO Serial3(SERIAL3_TX, SERIAL3_RX);
| ^~~~~~~~~~
C:\Users-----------.platformio\packages\framework-arduinopico\cores\rp2040\SerialPIO.cpp:385:31: error: ‘SERIAL3_RX’ was not declared in this scope
385 | SerialPIO Serial3(SERIAL3_TX, SERIAL3_RX);

I looked into the SerialPIO.cpp file, and sure enough there is a definition that relies on the same flag

#ifdef ARDUINO_NANO_RP2040_CONNECT

// NINA updates

SerialPIO Serial3(SERIAL3_TX, SERIAL3_RX);

#endif

I don’t really know what this is doing, but then I tried adding a new build flag replacing SERIAL3_TX and SERIAL3_RX with pin numbers as

-D SERIAL3_TX 16
-D SERIAL3_RX 17

and then I get an even weirder error

*** [.pio\build\picow\firmware.elf] Implicit dependency C:\Users\------------ \.platformio\platforms\raspberrypi@src-ff76a3915224135aafad379817f41edd\builder\16' not found, needed by target .pio\build\picow\firmware.elf’.

Has anyone ever seen this issue before? I’d appreciate any help

Thanks!

I also tried changing the flag while removing the definition for the serial pins

-D ARDUINO_NANO_RP2040_PICO

And also in the encoder, as

#elif defined(ARDUINO_NANO_RP2040_PICO)
#define CORE_NUM_INTERRUPT 20
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
// #define CORE_INT20_PIN A6
// #define CORE_INT21_PIN A7

But then I get this error

In file included from .pio\libdeps\picow\Encoder\Encoder.cpp:2:
.pio\libdeps\picow\Encoder\Encoder.h:68:11: error: ‘IO_REG_TYPE’ does not name a type; did you mean ‘IP_GET_TYPE’?
68 | volatile IO_REG_TYPE * pin1_register;
| ^~~~~~~~~~~
| IP_GET_TYPE
.pio\libdeps\picow\Encoder\Encoder.h:69:11: error: ‘IO_REG_TYPE’ does not name a type; did you mean ‘IP_GET_TYPE’?
69 | volatile IO_REG_TYPE * pin2_register;
| ^~~~~~~~~~~
| IP_GET_TYPE

The struct where the IO_REG_TYPE thingy is is here:

// All the data needed by interrupts is consolidated into this ugly struct
// to facilitate assembly language optimizing of the speed critical update.
// The assembly code uses auto-incrementing addressing modes, so the struct
// must remain in exactly this order.
typedef struct {
volatile IO_REG_TYPE * pin1_register;
volatile IO_REG_TYPE * pin2_register;
IO_REG_TYPE pin1_bitmask;
IO_REG_TYPE pin2_bitmask;
uint8_t state;
int32_t position;
} Encoder_internal_state_t;

The pin defs are only activated on

That worked, Thanks!

Hey! I’m using a Pi Pico W, and for the life of me I can’t get the board to work with the library. I’ve tried defining the board manually like the solution seems to suggest, but no luck. Any help would be appreciated!

What’s your current platformio.ini, code and error message?

So, it’s not a platformio error message - I’m actually using the arduino IDE, but I’m seeing nearly the exact same issue as the one originally posted aka regarding interupts - I can try platformio if need be though

To be of any help we would either need the exact Arduino IDE configuration (screenshot of Arduino IDE → Tools menu) or the platformio.ini, plus the code.

Hope this helps!

/* Encoder Library - Basic Example
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 *
 * This example code is in the public domain.
 */

#include <Encoder.h>

// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
Encoder myEnc(5, 6);
//   avoid using pins with LEDs attached

void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

also, the error message!

In file included from c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:46,
                 from C:\Users\Matt\AppData\Local\Temp\.arduinoIDE-unsaved2024430-22048-q0phb0.rhfc\Basic\Basic.ino:7:
c:\Users\Matt\Documents\Arduino\libraries\Encoder/utility/interrupt_pins.h:390:2: error: #error "Interrupts are unknown for this board, please add to this code"
  390 | #error "Interrupts are unknown for this board, please add to this code"
      |  ^~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/utility/interrupt_pins.h:393:2: error: #error "Encoder requires interrupt pins, but this board does not have any :("
  393 | #error "Encoder requires interrupt pins, but this board does not have any :("
      |  ^~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/utility/interrupt_pins.h:394:2: error: #error "You could try defining ENCODER_DO_NOT_USE_INTERRUPTS as a kludge."
  394 | #error "You could try defining ENCODER_DO_NOT_USE_INTERRUPTS as a kludge."
      |  ^~~~~
exit status 1

Compilation error: exit status 1

after trying to define ENCODER_DO_NOT_USE_INTERRUPTS, I get this:

In file included from C:\Users\Matt\AppData\Local\Temp\.arduinoIDE-unsaved2024430-22048-q0phb0.rhfc\Basic\Basic.ino:8:
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:68:18: error: 'IO_REG_TYPE' does not name a type; did you mean 'IP_GET_TYPE'?
   68 |         volatile IO_REG_TYPE * pin1_register;
      |                  ^~~~~~~~~~~
      |                  IP_GET_TYPE
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:69:18: error: 'IO_REG_TYPE' does not name a type; did you mean 'IP_GET_TYPE'?
   69 |         volatile IO_REG_TYPE * pin2_register;
      |                  ^~~~~~~~~~~
      |                  IP_GET_TYPE
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:70:9: error: 'IO_REG_TYPE' does not name a type; did you mean 'IP_GET_TYPE'?
   70 |         IO_REG_TYPE            pin1_bitmask;
      |         ^~~~~~~~~~~
      |         IP_GET_TYPE
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:71:9: error: 'IO_REG_TYPE' does not name a type; did you mean 'IP_GET_TYPE'?
   71 |         IO_REG_TYPE            pin2_bitmask;
      |         ^~~~~~~~~~~
      |         IP_GET_TYPE
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h: In constructor 'Encoder::Encoder(uint8_t, uint8_t)':
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:89:25: error: 'struct Encoder_internal_state_t' has no member named 'pin1_register'
   89 |                 encoder.pin1_register = PIN_TO_BASEREG(pin1);
      |                         ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:89:41: error: 'PIN_TO_BASEREG' was not declared in this scope
   89 |                 encoder.pin1_register = PIN_TO_BASEREG(pin1);
      |                                         ^~~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:90:25: error: 'struct Encoder_internal_state_t' has no member named 'pin1_bitmask'
   90 |                 encoder.pin1_bitmask = PIN_TO_BITMASK(pin1);
      |                         ^~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:90:40: error: 'PIN_TO_BITMASK' was not declared in this scope
   90 |                 encoder.pin1_bitmask = PIN_TO_BITMASK(pin1);
      |                                        ^~~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:91:25: error: 'struct Encoder_internal_state_t' has no member named 'pin2_register'
   91 |                 encoder.pin2_register = PIN_TO_BASEREG(pin2);
      |                         ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:92:25: error: 'struct Encoder_internal_state_t' has no member named 'pin2_bitmask'
   92 |                 encoder.pin2_bitmask = PIN_TO_BITMASK(pin2);
      |                         ^~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:99:45: error: 'struct Encoder_internal_state_t' has no member named 'pin1_register'
   99 |                 if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1;
      |                                             ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:99:68: error: 'struct Encoder_internal_state_t' has no member named 'pin1_bitmask'
   99 |                 if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1;
      |                                                                    ^~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:99:21: error: 'DIRECT_PIN_READ' was not declared in this scope
   99 |                 if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1;
      |                     ^~~~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:100:45: error: 'struct Encoder_internal_state_t' has no member named 'pin2_register'
  100 |                 if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2;
      |                                             ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:100:68: error: 'struct Encoder_internal_state_t' has no member named 'pin2_bitmask'
  100 |                 if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2;
      |                                                                    ^~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:100:21: error: 'DIRECT_PIN_READ' was not declared in this scope
  100 |                 if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2;
      |                     ^~~~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h: In static member function 'static void Encoder::update(Encoder_internal_state_t*)':
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:303:54: error: 'struct Encoder_internal_state_t' has no member named 'pin1_register'
  303 |                 uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
      |                                                      ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:303:74: error: 'struct Encoder_internal_state_t' has no member named 'pin1_bitmask'
  303 |                 uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
      |                                                                          ^~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:303:33: error: 'DIRECT_PIN_READ' was not declared in this scope
  303 |                 uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
      |                                 ^~~~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:304:54: error: 'struct Encoder_internal_state_t' has no member named 'pin2_register'
  304 |                 uint8_t p2val = DIRECT_PIN_READ(arg->pin2_register, arg->pin2_bitmask);
      |                                                      ^~~~~~~~~~~~~
c:\Users\Matt\Documents\Arduino\libraries\Encoder/Encoder.h:304:74: error: 'struct Encoder_internal_state_t' has no member named 'pin2_bitmask'
  304 |                 uint8_t p2val = DIRECT_PIN_READ(arg->pin2_register, arg->pin2_bitmask);
      |                                                                          ^~~~~~~~~~~~

exit status 1

Compilation error: exit status 1

That library is not yet equipped to handle Pico W, so you’ll need this patched library: https://github.com/PaulStoffregen/Encoder/pull/85/

So I’d suggest you remove remove the old encoder library and install it from this zip

https://github.com/jjsch-dev/Encoder/archive/refs/heads/master.zip
1 Like

wow it compiles!

Got it uploaded with the code showed earlier (changed pins)

but I’m getting nothing from my encoder - like, I’ve tried other wiring combo’s too but as the manufacturer didn’t include a pinout im a little lost as to why its not working:

Okay!
After doing some debugging, I found the correct pinout (A, B, GND). Tested it on my mega2560, and it works fine! although, on my pico w, it refuses to give me any life from the encoder

Edit: half asleep me still had the GND on the wrong pin. It’s KINDA working now, the value outputted to serial just runs away for lack of a better term., although I’m using the code someone posted to get it working with this board implementation:

/*
 * Encoder Library - Basic Example
 * http://www.pjrc.com/teensy/td_libs_Encoder.html
 * This example code is in the public domain.
 */
#include <Encoder.h>

// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder* myEnc; //(6, 7);
// avoid using pins with LEDs attached

void setup() {
   Serial.begin(9600);
   delay(5000);

   myEnc = new Encoder(12, 13);

   Serial.println("Basic Encoder Test:");
}

long oldPosition = -999;

void loop() {
   long newPosition = myEnc->read() / 4;
   if (newPosition != oldPosition) {
      oldPosition = newPosition;
      Serial.println(newPosition);
   }
}

Not sure where to go next with it as I’m waaaay out of my depth with some of this stuff already lol. Any advice is appreciated!