Link.One RAK4631 + RAK5005 + RAK5860 - GPIO

What product do you wish to discuss? RAK4631+ RAK5005-O + RAK5860
AKA “Link.One”

I want to be able to accept a digital input (or 2) from an external dry contact reed switches (pulses)

According to the following article,
I cannot access WB_IO1 and WB_IO2 pins because both GPIO’s are in use.

WB_IO1 is connected to the 1PPS output of the GNSS chip (rak5860), WB_IO2 is used to switch on/off the power and control reset.

No GPIO on the RAK5005-O is available because the on WB_IO1, pin is already used.

The solution offered in the post is to use a RAK13002 to get access to other GPIO’s (WB_IO3 … WB_IO6)

If RAK5860 is connected to IOslot D on RAK5005-O, how do I connect RAK13002? Dont they both require IO Slot?

Is there a way to get external IO and use the RAK5860 (cellular/GPS) board?

Hi @heraldoftech ,

I’ll share some options:

  • Use the I2C lines (SDA or SCL) on the RAK5005-O baseboard.
  • You can also use AIN1 if you are using RAK19007 baseboard (I am not sure if you have RAK5005-O or RAK19007 but AIN on headers of those boards are different).
  • Connect a 3rd party I2C GPIO expander board on the I2C headers if you need more pins.
  • Use Qwiic or Stemma QT GPIO boards using RAK13009.
  • Use the Dual IO base board (RAK19001). You have complete access to IO pins of WisBlock Core here and also add other interface module.
1 Like

Hi @carlrowan,

Thank you for your help!

It appears you have a better understanding of my hardware than I do :slight_smile:

You are correct that I do have a gen 2 RAK19007 baseboard that is sold in the Link.One package - and NOT a RAK5005-0

The solutions you have provided are very helpful, but I am not sure I will be able to achieve what I need. I would like to have the device deep sleep and only respond or take action when pulses/rising edge is sensed by the reed switch.

My understanding is that I2C will not be suitable because using interrupts will conflict with one another?

Alternatively, can an interrupt be implemented on analog AIN1?

The Dual board would work but then it wont fit in the original enclosure.

Perhaps this kit is not suitable or ideal for external digital input and deep sleep?

Hi @heraldoftech ,

You can use I2C lines (WB_I2C1_SDA and WB_I2C1_SDA) and the analog input (WB_A1) as interrupt source pin. I confirmed it using basic interrupt example from Arduino. Take note that if you are using a switch or pushbutton to test, you will encounter debouncing using this example. Also, you need to add this preprocessor directive #include <Adafruit_TinyUSB.h> to avoid USB related errors when you compile.

Thanks again @carlrowan

You can use I2C lines (WB_I2C1_SDA and WB_I2C1_SDA ) and the analog input (WB_A1 ) as interrupt source pin

Are you saying I can use WB_A1 as an interrupt and once the external interrupt is triggered, I can then make use of the I2C connections?

I have done some psuedo code below to confirm if I am understanding correctly:

 * @file RAK4631-DeepSleep-GPS.ino
 * @author Bruce
 * @web
 * @brief simple interrupt and deep sleep example
 * @version 0.1
 * @date 2023-07-14
 * @copyright Copyright (c) 2023
 * @note RAK4631 GPIO mapping to nRF52840 GPIO ports
   RAK4631    <->  nRF52840
   WB_IO1     <->  P0.17 (GPIO 17)
   WB_IO2     <->  P1.02 (GPIO 34)
   WB_IO3     <->  P0.21 (GPIO 21)
   WB_IO4     <->  P0.04 (GPIO 4)
   WB_IO5     <->  P0.09 (GPIO 9)
   WB_IO6     <->  P0.10 (GPIO 10)
   WB_SW1     <->  P0.01 (GPIO 1)
   WB_A0      <->  P0.04/AIN2 (AnalogIn A2)
   WB_A1      <->  P0.31/AIN7 (AnalogIn A7)

#include <Adafruit_TinyUSB.h>

const byte ledPin = 13;
const byte interruptPin = WB_A1;
volatile int pulses_count = 0;
const int MSG_INTERVAL = 300000;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);

  attachInterrupt(interruptPin, increment_pulse, RISING);

void loop() {

  //every 5 minutes check is the pulses have gone up.
  if(pulses_count > 0){
    //wake up the cellular BG77 module on WB_IO1
    // enable GPS on WB_IO2

    //get GPS lock

    //send payload with GPS and pulse count

    //reset pulse count
    pulses_count = 0;

    //turn off WB_IO1
    //turn off WB_IO2


void increment_pulse() {
  //triggered by external interrupt. Updates global volitile int

I haven’t run your code but that should work. You can use WB_A1 and free up the I2C bus.

1 Like

Before closing out and to hopefully help others who might be learning like me.

I didn’t initially understand that on the nrf52840 the analog pin WB_A1 can be used as an analog or digital pin. Hence, an external interrupt can be attached to the analog pin.

Reference: Nordic - PIN assignments

Re-using analog pins as digital pins is common to many popular micro controllers

I have tested this scenario and it works as expected.

Thanks @carlrowan for your guidance.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.