I have a project where I want to communicate from jetson nano to arduino. My idea is to use i2c with the arduino as slave. From arduino I want to continue the chain to I/O i2c port expander MCP23017.
Would it be possible to connect the MCP23017 at all since my arduino is already busy being a i2c slave to Jetson Nano? Or can arduino act as both slave and master at the same time?
ESP32 has 2 I2C controller (also referred to as port), responsible for handling communications on the I2C bus. A single I2C controller can operate as master or slave.
A separate bus is not required for master/slave reasons because the Arduino can act as master and slave on the same bus. The bus length however may become critical if the expander with further nodes is attached to the same bus.
I2C as master AND slave cannot work (with one device):
a master generates the clock (an output), the slave it gets the clock from a master (an input).
You could re-configure from master to slave and back. But at the same time - not possible.
What is only "allowed": to have two masters on the bus. So, your master will "read" (sense) the clock output signal (it is Open Drain): if signal is low - the "bus is busy" (and master do not get the bus access and will not send).
What you could do:
configure TWO I2C devices, one as master, one as slave. And connect both on the outside. So, your own slave could get the traffic from your own master. If you filter based on I2C slave address then your own slave will not receive the traffic send by your master when it addresses other slaves on bus (your slave is just another slave on bus).
With TWO real HW devices on same MCU (2x I2C) - yes, you can have both (but not with a single instance of I2C, it is exclusive master OR slave).
Master and Slave is not a constant property of a device. A device becomes master when it starts a transmission and generates clock pulses. At the end of the transmission it becomes a slave again.
I would disagree with that definition. When a slave answers a request for data from a master that doesn't make that slave a master. A master has no address and can request data from a slave at a specific address.
You can get a protocol know as a multi master system but often these are a bit flaky. It involves collision detection and backing off for a random time when two masters try and send at the same time. It will not transfer data at a known rate and the more transfers you have 5e more likely is a collision.
The ESP32 as a I2C Slave in Arduino mode has been added half a year ago, I don't know how well it works.
You might be the first to try using two I2C buses, where the ESP32 is a Slave on one bus and a Master on the other bus, so expect to run into bugs. For example timing issues. Sometimes a delay of 1ms is required between writing data (set register address) and reading data (read data from register).
If the Jetson Nano is the Master for the Arduino and the Arduino is a Master for the MCP23017, then you have a Multi-Master bus. That will not work. DrDiettrich is right, a Arduino board can be Master and Slave at the same time, but the Multi-Master bus is the problem. I have not seen a good implementation of a Multi-Master bus with Arduino boards yet.
I assume that the Jetson Nano has a 3.3V I2C bus ? If you connect a 5V Arduino board to that, then you need a I2C level shifter.
Keep in mind that there are software implementations for a I2C bus on any pins, but only for Master mode. That means you can use a Arduino MKR Zero as a Slave and a software I2C for the MCP23017. Or use software I2C for the ESP32 if using two hardware I2C buses is buggy. See the a big list for software implementations.
ok, but it might work with esp32 then using thed two i2c? But on arduino the multimaster becomes a problem right?
Otherwise, so what is the suggested way of doing this? The thing is that I need to send some data from jetson nano to use in my arduino sketch. Then since I need more outputs my idea was to connect the MCP23017.
But if that is not possible to connect in that way I suggested?
As I said: the master provides the clock signal. What's so difficult to understand with this definition?
Then the master with the first LOW bit wins over all others which send and expect a HIGH bit on SDA. The winning master continues its transmission and so on until all stations have completed their transmissions.
Of course there is no guarantee that misconfigured devices do not violate the rules.
No idea about I2C speed; I think it can be 400 kHz clock. An Arduino supports up to 2 MBits/s; I don't know about the Jetson. But in your question, you did not specify a need for speed
There are a few considerations in my opinion.
I2C was designed for InterIc Communication so very short distances (less than 20 cm); you can achieve longer but need to know what you do (I barely do). Serial has (in theory) barely a limit on distance when using RS232 or RS422 (see e.g. http://www.rs485.com/rs485spec.html). You did not give a spec for the distance.
There are also other speeds you can clock it at depending on what is on the other end and also with what sort of Arduino you use.
I once using a Pico 2040 I successfully clocked an I2C interface at 8 MHz with an OLED display at the other end. I didn't take it to the limit of not working and also I ramped the speed down in the final design because it did exceed the specs some what.
Is there some reason the arduino cannot be the master all the time, and request the data from the jetson nano, perhaps in response to the jetson nano pulling a line low to indicate it has data, or by just polling the jetson nano?
@david_2018 Do you want to set the Jetson Nano in Slave mode ? Do you know if that works ?
@acroscene I think that I have already answered your questions.
The I2C bus is not good to communicate between processors. If a serial bus is possible, then I think you should use that. I don't care about speed, the goal is a working project.
If it is only a few MCP23017 chips that you want to use, then forget about a Arduino in the middle and use it directly from the Jetson Nano.
The Arduino in the middle makes it not twice as hard, but perhaps ten times harder.
A Arduino as I2C Slave has to do everything just right. There are many things in hardware and software that can go wrong.
Seeing the bus can only be pulled down and not up how can any one master win?
What is to stop another master from transmitting during the transmitted message of the first?
When that happens the message sent is a wired OR of the two messages which could do anything from addressing the wrong , ie a totally different device, to corrupting the data being sent.