Hello everyone,
I have a project where two microcontrollers need to communicate with each other via I2C and both must be master and slave.
While I was using two Arduino Nanos it went fine, but then I had to switch one of them for a Raspberry Pi Pico and it no longer works.
If I use just one of them as a master and the other as a slave, it works. However, when I try to make both master and slave, the Nano stops working as a slave. That is, it no longer receives data sent by the Pico as master, nor it sends data back when Pico asks for it.
To be precise, when both are configured as master and slave, data sent by the Pico as master triggers the onReceive() event on the Nano, but after that, when I perform Wire.read(), there are no bytes on the buffer to be read. When the Pico asks for data as master, the onRequest() event on the Nano isn't even triggered.
What could be the issue here? Below is the code I'm using for both boards. The grounds are connected of course and I'm not using pull-up resistors as it seems that the Rpi Pico already has them. I tried the same setup with a 5k resistor on each line and it didn't work.
For the Pico, I'm using the Earlephilhower library instead of the Arduino one, that is why you see the Wire.setSDA(0) and Wire.setSCL(1) commands on the setup, which configure the pins that are being used for I2C.
Edit: I forgot to mention that I'm using a logic level shifter between the two boards, as Nano works at 5V and Pico at 3.3V.
Pico code:
#include <Wire.h>
void receiveEvent(int nBytes) {
Serial.print("RECEIVED FROM MASTER: ");
while (Wire.available())
Serial.print(Wire.read());
Serial.println();
}
void requestEvent() {
byte val = 9;
Serial.print("SENDING TO MASTER: ");
Serial.println(val);
Wire.write(val);
}
void sendCode() {
byte val = 13;
Serial.print("SENDING: ");
Serial.println(val);
Wire.beginTransmission(0);
Wire.write(val);
Wire.endTransmission();
}
void requestCode() {
Wire.requestFrom(0, 1);
Serial.print("RECEIVED FROM SLAVE: ");
while (Wire.available())
Serial.print(Wire.read());
Serial.println();
}
void setup() {
Serial.begin(115200);
Wire.setSDA(0);
Wire.setSCL(1);
Wire.begin(1);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
delay(100);
}
void loop() {
requestCode();
delay(500);
sendCode();
delay(500);
}
Nano code:
#include <Wire.h>
void receiveEvent(int nBytes) {
Serial.print("RECEIVED FROM MASTER: ");
while (Wire.available())
Serial.print(Wire.read());
Serial.println();
}
void requestEvent() {
byte val = 10;
Serial.print("SENDING TO MASTER: ");
Serial.println(val);
Wire.write(val);
}
void sendCode() {
byte val = 11;
Serial.print("SENDING TO SLAVE: ");
Serial.println(val);
Wire.beginTransmission(1);
Wire.write(val);
Wire.endTransmission();
}
void requestCode() {
Wire.requestFrom(1, 1);
Serial.print("RECEIVED FROM SLAVE: ");
while (Wire.available())
Serial.print(Wire.read());
Serial.println();
}
void setup() {
Serial.begin(115200);
Wire.begin(0);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
delay(100);
}
void loop() {
delay(500);
}
The result printed on the serial monitor for this code is:
Pico:

Nano:

In this code, if I just declare the Pico as master only, that is, change Wire.begin(1) to Wire.begin(), it works normally.
Any help is appreciated! Thanks