Modifying I2C code from uno to Pico

//Compass code by toniz https://forum.arduino.cc/t/gps-and-compass/1101707/25?page=3
//GPS code from https://lastminuteengineers.com/neo6m-gps-arduino-tutorial/
//Direction https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207
//Commands Self

//Direction -35.67593568404272, 147.51781339739313
#define des_LAT -35.67593568404272
#define des_LNG 147.51781339739313

//Compass
#include <Wire.h>
#include <QMC5883LCompass.h>
QMC5883LCompass compass;

//Gps
#include <TinyGPS++.h>
#include <PicoSoftwareSerial.h>

int RXPin = 21;
int TXPin = 16;
int GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);


void setup()
{
  //Compass
  Serial.begin(115200);
  Wire.begin();
  compass.init();

  //GPS
  gpsSerial.begin(GPSBaud);

}

void loop()
{
  //Compass
   int x, y, z;
  compass.read();
  x = compass.getX();
  y = compass.getY();
  z = compass.getZ();
  float heading = atan2(y, x);
  if(heading < 0) heading += 2*PI;
  float headingDegrees = heading * 180/M_PI;

  //GPS
  while (gpsSerial.available() > 0)
    if (gps.encode(gpsSerial.read()))


  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
  Serial.print(" No GPS detected");
  while(true);
  }

  if (gps.location.isValid())
  {
  Serial.print("| Lat: ");
  Serial.print(gps.location.lat(), 6);
  Serial.print(" | Long: ");
  Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print("  Location: Not Available");
  }
  Serial.print(" | Hed: ");
  Serial.print(headingDegrees);
  Serial.print("*");

//Direction 
  double distanceToDestination = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), des_LAT, des_LNG);
  double courseToDestination = TinyGPSPlus::courseTo(gps.location.lat(), gps.location.lng(), des_LAT, des_LNG);
  const char *directionToDestination = TinyGPSPlus::cardinal(courseToDestination);
  int courseChangeNeeded = (int)(360 + courseToDestination - headingDegrees)% 360;
  courseChangeNeeded= map(courseChangeNeeded, 0, 360, 180, -180);

    Serial.print(" | DistRemain=  ");
    Serial.print(distanceToDestination);
    Serial.print("m, | CourseAdjust= ");
    Serial.print(courseChangeNeeded);
    Serial.print(" | Speed: ");
    Serial.print(gps.speed.kmph());
    Serial.println("Km/h|");
}
//Commands

this code is for a GPS and Compass combo originally written to work on a Arduino uno but i need to convert it so it can work (still in C++) on a Raspberry Pico. I have got the GPS working but i am having trouble with the multiple I2C pins on the Pico and how to specify which pins to use.

The raspberry Pi pico has minimum two so called core-packages.
The core-package contains the main basic components including wire.h

So the solution will depend on which core you are using
mbed-core from the Arduino-Team:

core form from Earl Philhower:

Me personal I prefer the ear PhilHower-core

because this core has explicit functions to set the SDA/SCL-pins

So after having tried to use the mbed-core with trying to compile the classical I2C-Scanner sketch which did not compile.

I recommend that you use the Earl Philhower-core. (maybe you are already using this core)

With searching the Arduino-Forum I found this post

which has a demo-code how to use these functions

  Wire.setSDA(PICO_I2C_SDA);
  Wire.setSCL(PICO_I2C_SCL);

These functions are only declared in the Earl Philhower-core

these functions return a boolean result because not all RP2040-IO-pins can do I2C

So you can code

if(! Wire.setSDA(PICO_I2C_SDA)   ) {
  Serial.print("unable to use IO-pin "
  Serial.print(PICO_I2C_SDA);
  Serial.println(" for I2C-SDA"
};

if(! Wire.setSCL(PICO_I2C_SCL)  ) {
  Serial.print("unable to use IO-pin "
  Serial.print(PICO_I2C_SCL);
  Serial.println(" for I2C-SCL"
};

to get feedback if the pin is able to do I2C

I don't understand what the trouble is about.
Use the default pins and ports that are already there for you.

If you use the newest Arduino IDE and install the "Arduino Mbed OS RP2040 Boards" by Arduino, then you have the normal "ArduinoCore-mbed".

The default I2C bus is at pin 4 and 5.
SDA = pin 4 (also called GPIO4 or GP4).
SCL = pin 5 (also called GPIO5 or GP5).
Just use Wire.begin(); without parameters and use the default pins.

The "Serial" port is via the USB cable to the Serial Monitor.

"Serial1" is a extra hardware serial port at pin 0 (TX) and 1 (RX).
Use Serial1.begin(115200); to start using Serial1.
Are you sure that the GPS is at 115200 baud? I think it is at 9600 baud.

Connect the I2C devices to the I2C bus, connect the GPS to Serial1, don't use SoftwareSerial. That's all.

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