Difficulty with interrupts

Is there anything different needed with these boards to use interrupts? I’m assuming interrupts are possible.

I have a simple sketch for testing a rotary encoder. that originally came from bildr Rotary Encoder + Arduino - bildr and has been slightly modified. It works on the original Nano just fine but not on the 33 BLE, no errors produced and the “Button” works ok but no change in encoder value.

Having a look at the schematic there is no INT(0), INT(1) labels on any of the GPIO pins so assume no hardware interrupts which was a surprise but a software interrupt should be possible?

Here’s the test sketch:

//From bildr article: https://bildr.org/2012/08/rotary-encoder-arduino/

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
int encoderSwitchPin = 4; //push button switch

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

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

  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);

  pinMode(encoderSwitchPin, INPUT);

  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  digitalWrite(encoderSwitchPin, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);

}

void loop() {
  //Do stuff here
  if (digitalRead(encoderSwitchPin)) {
    //button is not being pushed
  } else {
    Serial.println("Button");
  }
  //button is being pushed


  Serial.println(encoderValue);
  delay(1000); //just here to slow down the output, and show it will work even during a delay
}

void updateEncoder() {
  int MSB = digitalRead(encoderPin1); //MSB = most significant bit
  int LSB = digitalRead(encoderPin2); //LSB = least significant bit

  int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
  int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
  lastEncoded = encoded; //store this value for next time
}

In addition, it seems someone beat me to it by a few hours https://github.com/arduino/ArduinoCore-nRF528x-mbedos/issues/7

Also, adding interrupts() doesn't work either just in case it wasn't enabled by default.

I don’t think you’re doing anything wrong – this looks like a genuine bug.
I suspect it’s this one, reported upstream against ARM’s mbed-os:

It sounds like the only thing needed to fix this would be to set the following macro definition when compiling mbed-os:

NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS=8

I’ve been trying to create a drop-in replacement for libmbed.a all weekend without much success. I can’t figure out which release of mbed-os they’re using here, and without that this is turning into major surgery.

I’ve filed another issue here:

Once we have that, getting this fixed should hopefully be relatively straightforward.

That's a real shame, given the age of that bug report, the number of other bugs on there, and lack of comments on the issue, I would guess it could to take a long time to fix and trickle down.

For anyone following here but not on github, I managed to fix this.

Bug report: https://github.com/arduino/ArduinoCore-nRF528x-mbedos/issues/7 Proposed fix: https://github.com/ohazi/ArduinoCore-nRF528x-mbedos Pull request: https://github.com/arduino/ArduinoCore-nRF528x-mbedos/pull/10

The instructions in the top level README.md should work, if you want to try this out before it gets reviewed / merged. Substitute 'ohazi' for 'arduino' when cloning ArduinoCore-nRF528x-mbedos.

Thanks so much for your work on this ohazi!

This is great ohazi thank you.

I think I’m going to have to wait for a release as I don’t fully understand the changes you’ve suggested. There’s also an issue that was fixed involving ltoa/ultoa that hasn’t been released yet. That’s no comment on your explanations btw, they’re very thorough, it’s my lack of experience. Which is only improved by people like yourselves going to such lengths to find the root of a problem and explaining a fix so it’s very much appreciated. This is the second bug in the core I’ve had some kind of involvement in already, what a time to pick to learn Arduino! :smiley:

Having said that I might try cloning your repo. Is there somewhere that points the IDE to the file location of mbed for compile? I’d like to clone your repo to a seperate location so that I can compare the changes and switch back to the default quite easily, ie not overwrite the original folder.

I'm using Linux, so there may be some minor differences if you're using a different operating system.

When I install the board package the usual way (via Tools > Board > Boards Manager), it places files in a few locations:

~/.arduino15/packages/arduino/hardware/mbed/...
~/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/...
~/.arduino15/packages/arduino/tools/bossac/...
~/.arduino15/packages/arduino/tools/openocd/...

You shouldn't ever need to touch these files, but this is where you would look if you wanted to compare changes.

First, install the latest version of the board package via the Boards Manager ("Arduino nRF528x Boards (Mbed OS)" 1.1.1). This is useful because it installs a bunch of things that you need in tools/ (ARM compiler, board flashing utilities, etc.) in addition to the actual board files in hardware/. You'd need to install these tools manually if you wanted to do everything from scratch, so this will save you some trouble.

You can also manually install packages by putting them in the correct location in your sketchbook directory. The Arduino IDE will preferentially use those packages if they're available. That's why the README.md file refers to $sketchbook/hardware/arduino.

My sketchbook location is ~/Arduino, so I did the following:

~/Arduino$ mkdir -p hardware/arduino
~/Arduino$ cd hardware/arduino
~/Arduino/hardware/arduino$ git clone git@github.com:ohazi/ArduinoCore-nRF528x-mbedos mbed
~/Arduino/hardware/arduino$ git clone git@github.com:arduino/ArduinoCore-API -b namespace_arduino
~/Arduino/hardware/arduino$ ls
ArduinoCore-API  mbed

That's it. If you relaunch the Arduino IDE, it'll use the managed tools, but will use the board files from your sketchbook directory instead of the managed version. When you want to go back to the managed version, just delete the hardware directory in your sketchbook.

You can confirm that everything is working as expected by looking at the output when you verify your sketch. You should see the following near the top:

Using board 'nano33ble' from platform in folder: /home/ohazi/Arduino/hardware/arduino/mbed
Using core 'arduino' from platform in folder: /home/ohazi/Arduino/hardware/arduino/mbed

and later:

/home/ohazi/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-g++ -c -I. -Wall -Wextra -g -Os -nostdlib @/home/ohazi/Arduino/hardware/arduino/mbed/variants/ARDUINO_NANO33BLE/defines.txt @/home/ohazi/Arduino/hardware/arduino/mbed/variants/ARDUINO_NANO33BLE/cxxflags.txt -DARDUINO_ARCH_NRF52840 -MMD -mcpu=cortex-m4 -DARDUINO=10809 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED -I/home/ohazi/Arduino/hardware/arduino/mbed/cores/arduino -I/home/ohazi/Arduino/hardware/arduino/mbed/variants/ARDUINO_NANO33BLE -I/home/ohazi/Arduino/hardware/arduino/mbed/cores/arduino/api/deprecated -iprefix/home/ohazi/Arduino/hardware/arduino/mbed/cores/arduino @/home/ohazi/Arduino/hardware/arduino/mbed/variants/ARDUINO_NANO33BLE/includes.txt /home/ohazi/Arduino/hardware/arduino/mbed/variants/ARDUINO_NANO33BLE/variant.cpp -o /tmp/arduino_build_142589/core/variant.cpp.o

That line is kind of a mess, but if you look closely, you'll see that it's using arm-none-eabi-g++ from the managed location, but taking everything else from the sketchbook location.

Finally, in my comment here, I was just trying to describe the process so that someone else could reproduce what I did from scratch. This is primarily for the maintainer, in case they want to change the way the fix works, or perhaps rebase it off of a different version of upstream mbed-os. It would probably be easier for them to go through my process from scratch than to try and modify my tree.

You shouldn't have to go through any of that if you just want to test out my changes with your sketch.

Once again ohazi this is excellent thank you!

I was struggling with the where to put the cloned repo before your post. I also managed to add the required symlink for the api folder.

I managed to get everything setup but was getting an undefined reference error on Serial.println() after some time (like 3 hours!) head scratching and reading about what undefined reference actually meant I noticed in the verbose output some references to previous builds of the same sketch in my temp folder.

After deleting all the temp files my sketch compiled correctly, uploaded successfully and the interrupts work with the rotary encoder.

The encoder value seems very slow to update but that could be something else entirely so I'll do some more fiddling. I certainly don't have the expertise required to test the response time. I originally had the encoder value going to a display so I'll get that working again and this will remove the serial print and delay and see how i get on.