Change Pi Pico Serial and I2C Pins and use both I2C Ports

Hi everyone

For a study project, we have to build a multi sensor platform. For this, we’ll need a Serial port, one SPI as well as both I2C ports.

We’re using a Pi Pico with PIO on VSCode with the Arduino Framework.

Unfortunately, I can’t find where to define the pins the ports use. I was able to find the pins_arduino.h but in there I find a
#define SERIAL_HOWMANY (1)
which in itself is a bit strange since Pico should have two Serial Ports.
For I2C I can’t even find a corresponding define.

How can we change the used pins for all the different ports?

I found this page Pin Assignments — Arduino-Pico 2.7.1 documentation but the described functions (setRX(), setTX()) don’t seem to exist.

Thanks for your help!

What is your platformio.ini? Note that there exist two Arduino-core implementations for the Pi Pico, one official by Arduino people based on mbed-os (GitHub - arduino/ArduinoCore-mbed), the other one a “third-party” one by Earle Philhower (GitHub - earlephilhower/arduino-pico: Raspberry Pi Pico Arduino core, for all RP2040 boards).

By default, PlatformIO only supports the mbed arduino core. The documentation you’ve linked to is the Earle-Philhower core one, so any instructions for that are invalid if you’re using the default platformio.ini settings for a Pico + Arduino project which gives you the mbed based core.

Note that you can use the Earle-Philhower core with PlatformIO per its documentation (which coincidentally I wrote).

Based on knowing what core you’re using, it should be relatively easy – e.g., constructing a new SPI object with the SPI pins in the constructor, same for a Wire object for I2C and Serial for UART/Serial.

Thank you maxgerhardt for your very fast answer. I’m using the official one then, I guess. This is my platformio.ini:

[env:pico]
platform = raspberrypi
board = pico
framework = arduino
upload_protocol = picotool
upload_port = /volumes/RPI-RP2
lib_deps =
   adafruit/Adafruit MCP9808 Library@^2.0.0
   adafruit/Adafruit HMC5883 Unified@^1.2.0
   adafruit/Adafruit Unified Sensor@^1.1.5
   adafruit/Adafruit BMP085 Unified@^1.1.1
   adafruit/Adafruit AS7341@^1.3.2

In what file would I add these new constructors?

The constructors for these classes are already there, you just have to use them to create new objects.

Test out this program

#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>

// available pins per https://forum.arduino.cc/t/pi-pico-arduino-ide-pin-mapping-for-gpio-in-ide/903691

// default "Wire" object: SDA = GP4, SCL = GP5, I2C0 peripheral
// our new wire object:
#define WIRE1_SDA       2  // Use GP2 as I2C1 SDA
#define WIRE1_SCL       3  // Use GP3 as I2C1 SCL
arduino::MbedI2C Wire1(WIRE1_SDA, WIRE1_SCL);

// default "Serial1" object: UART0, TX = GP0, RX = GP1
// our new Serial object:
#define SERIAL2_TX      4  // Use GP4 as UART1 TX
#define SERIAL2_RX      5  // Use GP5 as UART1 RX
arduino::UART Serial2(SERIAL2_TX, SERIAL2_RX, NC, NC);

// default SPI at MISO = GP16, SS = GP17, SCLK = GP18, MOSI = GP19
// SS/CS is software controlled, doesn't matter which pin
#define SPI1_MISO 12
#define SPI1_MOSI 11
#define SPI1_SCLK 10
arduino::MbedSPI SPI1(SPI1_MISO, SPI1_MOSI, SPI1_SCLK);

void setup() {
    Wire.begin();  // I2C0
    Wire1.begin(); // I2C1

    Serial.begin(115200);  // USB CDC serial
    Serial1.begin(115200); // UART0 serial at TX=GP0, RX=GP1
    Serial2.begin(115200); // UART1 serial at TX=GP4, RX=GP5

    SPI.begin(); // SPI0
    SPI1.begin(); // SPI1 
}

void loop(){

}
1 Like

If you want to use the Arduino-Pico core instead, you can do so as described in Change Pi Pico Serial Pins - #6 by friedrich.kiesel.

Hi maxgerhardt

Thank you so much for your quick replies,

Your solution worked like a charm!