XIAO Expansion board I2C question

Hello

I'm using two XIAO SAMD21, the master sends a number, and the slave activates/deactivates an LED and servo motor depending on the value received by the master.

So far, master-slave communication works fine using the following code:


#include <Wire.h>
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  Wire.begin(3);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  myservo.attach(7);  // attaches the servo on pin 9 to the servo object
}

void loop()
{
  delay(100);
  //

}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
  


if (x < 90) {
    digitalWrite(LED_BUILTIN, HIGH);

    myservo.write(x);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
    myservo.write(0); // Move servo to 90 degrees

  }

}

I want to use the OLED display on the XIAO expansion board base:
https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/

When I try using the code below, I can only display a Hello world!!! message, but it seems I cannot receive the data from the master:

#include <Arduino.h>
#define U8X8_DO_NOT_SET_WIRE_CLOCK
#include <U8x8lib.h>//Use U8x8 library file
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
//Set the constructor, define the display type, controller, RAM buffer size, and communication protocol, generally determine according to the used display model


#include <Wire.h>
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup(void) {
  pinMode(LED_BUILTIN, OUTPUT);
  Wire.begin(3);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  myservo.attach(7);  // attaches the servo on pin 9 to the servo object


    u8x8.begin();//Initialize u8x8 library
    u8x8.setFlipMode(1);//Flip the display 180 degrees, generally numbers 0 and 1
}

void loop(void) {
    u8x8.setFont(u8x8_font_chroma48medium8_r);//Define u8x8 font
    u8x8.setCursor(0, 0);//Set the position of the drawing cursor
    u8x8.print("Hello World!!!!");//Draw content on OLED: Hello World!
}



void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer

if (x < 90) {
    digitalWrite(LED_BUILTIN, HIGH);
    myservo.write(x);
    
  } else {
    digitalWrite(LED_BUILTIN, LOW);
    myservo.write(0); // Move servo to 90 degrees

  }

}

I know that it is because the OLED uses I2C and it is clashing (I suppose) with the I2C communication with the master. On the other hand, IT IS POSSIBLE to use other I2C devices PLUS the OLED screen as in this example using the expansion board:
https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/#project-5---air-quality-sensor-hub---seeed-studio-expansion-base-for-xiao

can you please advice on how can I use both the OLED display and the I2C master-slave communication? my goal is to take the number sent by the master and display it on the OLED display too.

The simple rule is the bus has only one master. If you use more then one master the masters will have to be able to determine when the buss is available for them. Look into pseudo semifore registers.

You need to run the I2C scanner to be sure each unit has a separate address. What you are describing could also be duplicate I2C address.