简体   繁体   中英

Arduino ESP32 I2C can I set custom pins for SLAVE (Client)

tl;dr can someone tell me if it is possible to set custom pins for an I2C slave (client, peripheral) within the Arduino environment?

Context On an ESP32 (ESP32-WROVER from Freenove) I am trying to communicate with 2 devices that are I2C masters (Adafruit Monster M4sk)

On this particular ESP32-WROVER board the default SDA and SCL pins are used by a camera. So I have to set up I2c on different pins. I'm using pin 2 as SDA and pin 15 as SDL.

I can easily set up I2C as a MASTER on those pins, works just fine using Wire.begin(2,15). I find lots of documentation about setting custom pins, multiple busses using Wire or TwoWire.

What I really want to do is something like this:

#include <Wire.h>

#define SDA1 2
#define SCL1 15

#define SDA2 21
#define SCL2 22

#define SLAVE_ADDRESS_ON_BUS_1 0x52
#define SLAVE_ADDRESS_ON_BUS_2 0x33

setup()
{
  Wire.begin(SDA1,SCL1,SLAVE_ADDRESS_ON_BUS_1); // Join I2C bus 1 using pins 2 and 15
  Wire1.begin(SDA2,SCL2,SLAVE_ADDRESS_ON_BUS_2);// Join I2C bus 2 using pins 21 and 22


  Wire.onReceive(receiveI2CBus1Event); // register event for when master on i2c bus 1  writes
  Wire.onRequest(WriteToI2CBus1Event); // register event for when master1 wants on i2c bus 2 wants to read

  Wire1.onReceive(receiveI2CBus2Event); // register event for when master on i2c bus 2 writes
  Wire1.onRequest(WriteToI2CBus2Event); // register event for when master on i2c bus 2  wants to read
}

As far as I can tell there is no way to use either Wire or TwoWire to create a peripheral on a custom set of pins...

Wire.begin(MY_ADDRESS);

I have tried re-defining SDA and SCL but that does not seem to work Note I am running Expressif's ESP32 libraries v2.0.2 (ESP32 Libraries 1.0.6 and prior did not support ESP32 as a slave) I have tried this (this being redefining SDA and SCL) using both Arduino IDE 1.8.19 and Arduino IDE 2.0.0.rc5

I can't be the first person trying to have an ESP32 act as an i2c slave using something other than the default pins...

Am I gonna have to resort to some sort of I2C bridge/switch/mux? if so, any recommendations? (preferably recommendations with arduino sample code showing how a master can assign an address to another master)

Thank you.

You're very close, you just have the order of the parameters flipped. The address comes first, followed by the pin numbers.

There are optional parameters to Wire.begin() that allow you to specify the pins used for the I2C controller in slave mode:

    bool begin(uint8_t slaveAddr, int sda=-1, int scl=-1, uint32_t frequency=0);

So you could call

Wire.begin(MY_ADDRESS, SDA1, SCL1);

and optionally specify the frequency as a final argument if you need to.

While this form of begin() looks like it's for a master, its code explicitly sets the is_slave flag :

    is_slave = true;

and calls i2cSlaveInit() .

I haven't actually used this so I can't promise it works, but this is the way the code is organized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM