Skip to content

RPi Pico 2W — Using I2C

The Pico 2 can act as I2C master or I2C slave. The default setting is to be master. The SDK controls the I2C hardware and provides functions to configure I2C and read/write to a slave.

First, add the hardware_i2c library to CMakeLists.txt for I2C support.

target_link_libraries(my_project pico_stdlib hardware_i2c)

Now the steps are:

  • Configure GPIO pin(s) for I2C.
  • Set the bus speed.
  • Read data from an I2C peripheral — in this example an LM75 temperature sensor, which uses two bytes to represent the temperature.
void configureI2C()
{
uint32_t baudrate = 10000;
i2c_init(i2c_default, baudrate);
// configure GPIO pins
// This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico)
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
// set pull-up on pins
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
}

The i2c_read_blocking function can be used to read data from a peripheral into a buffer. It handles I2C START and STOP signalling internally.

void readTempFromLM75(uint8_t address)
{
// the temperature is two bytes
uint8_t byte[2];
int8_t rc; // to hold the return code
rc = i2c_read_blocking(i2c_default, address, &(byte[0]), 2, false);
if (rc != PICO_ERROR_GENERIC)
{
printf("byte0: %d, byte1: %d\r\n", byte[0], byte[1]);
}
else
{
printf("I2C error, return value was: %d\r\n", rc);
}
}