I2C Addressless communication

Hi guys,
I have used I2C comms several times in the past and am therefore quite familiar with the setup and protocol. It works very well. I am busy developing a product that will use a number of I2C sensors. As part of the test regime I want to emulate a number of sensors far in excess of the number of actual devices I will be using, in order to test durability of my code and hardware performance. I could set this up with the actual probes, however there are many benefits to setting up a test rig where I can control exactly what comes out of my emulated probe for error detection purposes for example.

Plan A
Grab a substantial handful of low cost Arduino boards and program them up, each behaving as a particular sensor, and hook all that up to my I2C bus
This seems overly complex and expensive, considering at any one point in time my master will only ever be talking with a single slave device.

Plan B
Use a single good quality Arduino board, set it up as a slave device where it listens for any/all valid sensor addresses, and responds to the master accordingly (IE it's response will be determined by address received)

This way I can have as many pseudo-devices hanging off my I2C line as I want, bombarding my database with exactly the data I want to see/evaluate for errors.

Plan B almost certainly means I cannot use I2C hardware peripherals (unless somebody here has a good idea in terms of how you get around the mandated requirement for providing a fixed slave address as part of the peripheral setup). This is most likely a bit bang affair, but does anybody have a library where you can read the address as received from the master?

Does anybody potentially have any other ideas for my test regime?

Keep an eye on the pullup resistance needed, where to apply it etc.
Plan will better emulate the electrical aspekts of a multisensor
Plan B sounds brilliant but do You know how to make one controller monitor several addresses?

Hi Railroader,
no not really. That's essentially my question in a nutshell

Your problem arises from the fact that an I2C slave does not receive the address it listens to and reacts to from the master. The slave determines which address it responds to. It's actually almost like us humans. After the parents (manufacturers) have given us a name, we listen to this name. There are sensors that can be used with the master to give a new I2C address, but not without knowing the original address. this is the only way for the sensor to know that this new address is intended for it. You can of course describe an Arduino with an I2C slave program that also offers the option of logging in to the I2C bus with a new address, and from now on listening to this address until the next change. But the fact that the Arduino as an I2C slave reacts to any address, every time different, should not work, as this is contrary to the I2C protocol. something like this only works on a bus that does not select the desired receiver / sensor / actuator with transmitted addresses, but with chip select / enable lines.

Yep, I agree in terms of I2C hardware peripherals. It certainly wouldn't be conventional to be listening to all traffic on the data line, including the address. All of that is taken care of for you by the hardware, which 99% of the time is a good thing. Now with that said, the hardware certainly is listening to any/all data on the data line, including all addresses, so if this were a part of the standard somewhere, it is technically feasible, but I have not seen this feature drawn out of the standard (if it existed) on any microcontroller I've ever used.

This is why I suspect my only recourse is a bit-bang solution, where I simply listen for any/all Master requests, extract the address and then do what I have to do to formulate the required response. It is a bit surprising that nobody else ever appears to do this as part of their test regime. I can understand for a home user, but in a commercial/industrial environment, where a would-be designer wants to be 100% confident that his design is not borderline buggy, this type of testing is mandatory.

Provided that a slave can change its address dynamically using Wire.begin(addr):

Plan C
Scan sequential addresses and make the slave change its address after each transmission accordingly.

Plan D
Send the next address along the transmitted data and make the slave change to that address. Or add a dedicated "set address" command to the communication.

For a physical-also test a couple of physical slaves have to be used, on a long bus as occurs in practice.

a test with distributed physical slaves on a physical bus is required.

What special test do you want to perform with a dummy slave, reacting on all addresses? At least you also should test addresses which are not in use (node failure, bus lock-up...).

Perhaps you could use the I2C general call (address 0x00) sending two bytes (e.g.) -- the first byte is a "safing" command byte (e.g. 0xA5 indicates a command that change the TWAR) and a second which is that address.

Once the address is changed and any re-initializations required are complete, you can do your address-specific testing.

When you're ready to switch addresses your master issues another general call with a new address etc.

Plan E
Use a dummy Wire library that does nothing. In requestFrom() supply the data expected to be received from the slave.

This topic is going wild.

Plan A: A bunch of Arduino boards that behave as sensors :+1:
This is possible. Most sensors have registers and a register address. That is an array and a index. If you set the onReceive and onRequest handler right and remember the auto-increment of the index and the 'volatile' keyword, then it is possible. A clone board costs about 4 dollars/euros.
If the Controller is an Arduino board with the Wire library, then it feels the same. At hardware level it is not the same because a sensor has a hardware interface and a Arduino uses clock pulse stretching because the I2C interface is hardware + software.

Plan B: React to multiple I2C Addresses :-1:
A ATtiny has a USI that is flexible and might react to multiple I2C addresses. Normal Arduino boards can not do that.
PerryBebbington writes in Reply 18 about a PIC processor that has these capabilities.

Plan bit-bang :-1:
See the list: https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.
There are a few I2C Target implementations, but they require a very specific I2C usage. That is not flexible enough.

Plan C and D and General Call: Send a command to the Arduino to change its behaviour :+1:
This is possible in different ways. It will be complex. This will become a project of its own, and the original plan is almost out of sight. Buying a handful of sensors is easier.

Plan E: Simulate the sensors in the Controller :+1:
There will be no I2C bus and no Target devices. The Arduino Wire library is replaced with a different library that has all the intelligence of the sensors in it.
Now that I think of it, this will work. The hardware has to be tested in a different way, but the hardware of the real sensors behaves different than the Arduino as Targets anyway.

How about the hardware ?
You have not told us how the hardware will be. Will there be level shifters and pullup resistors and wires and cables ? You need to know this before you make something that does not work.

I'm using "Controller" and "Target", see: https://forum.arduino.cc/t/new-i2c-standard-document-by-nxp-controller-and-target/913956

[UPDATE] Plan E gets a thumbs up now that I understand what DrDiettrich is saying.

I'm well behind you folks with regards to advanced I2C subtleties. However would not "SoftWire" on the slave be an option?

Without knowing anything about "SoftWire" I can imagine it might be possible to fool it in reacting to multiple I2C addresses. It might require one to predefine the addresses to be used.

@JohnRob The Controller makes the SCL clock. When a Target gives a acknowledge to its address, it has to that immediately at the 9th clock pulse of the Controller. That part is therefor in hardware. It is almost impossible to do that in software. The "SoftWire" has no Slave implementation. So I gave Plan B, Plan bit-bang and Plan E a thumbs down.

Thanks :slight_smile:

A test of program logic does not require hardware in this case. It's sufficient to simulate master-slave communication for testing purposes. The response generating code of the slaves executes on the master so that debugging is easier. A single #define change allows to switch between simulation and hardware usage.

When I worked in military avionics, we used a MIL-STD-1553 data bus to communicate between Remote Terminals. The Bus Controller had a transaction table that determined the order in which it talked to the Remote Terminals. This sequence was fixed except for a few "random" messages that could be inserted.

If your test setup sent out I2C messages in a similar known sequence, then you could in theory configure your I2C slave device to switch to the next address in the sequence after each message. Store the address sequence on the slave and you would not need any additional I2C messages.

Perhaps the I2C general call message could be used to reset the sequence.

Having worked in a consumer mass production development company that uses I2C a lot I can assure you there are other ways to ensure that a design is not "borderline buggy". No one in their right mind would even consider loading an I2C bus with so many devices that you run out of address space. A good logic analyser is going to show any "borderline buggy" problems. The only problem we ever encounter with I2C was with multi master buses being driven by an FPGA, and that almost always turned out to be subtle errors in the third party FPGA libraries.

We made at least half a million of each design. So there was plenty of variation to show up anything.

I think I would too want to go with the multiple device option as it also checks electrical characteristics of the system - if you test with one device responding to many addresses , is it the same as many devices each with one address, and can you then be sure a test with one device will work the same over voltage temperature tolerance , noise etc

If making a product you don’t want gremlins to appear after sale .

A handful of Chinese nanos won’t cost much

This question intrigued me as I thought B must be possible.

I am familiar with the I2C hardware on a number of different PICs so checked the data sheet of a PIC18(L)F2X4XK22. It is possible to configure the hardware in slave mode to indicate a match for any 7 bit I2C address, or to create a mask to addresses with specified bits match.

Now obviously you will be thinking that a PIC18(L)F2X4XK22 is not used on any Arduino board and you might be wondering how this helps you. My point is that if it's possible on one micro-controller it is likely to be possible on others, you just have to read the data sheet to find out. Then you 'just' need to learn how to control the I2C hardware yourself and write your own code to do it.

The big advantage of pre-written libraries is they make complex hardware easy to access in software, and abstract away the particular hardware details. The disadvantage is there is often a lot more that the hardware can do but which the library does not have a function for. This could well be such a situation.

@DrDiettrich Thank you for explaining it to me. I like the idea a lot. I have changed my reply #10.

@hammy You vote for Option A ? So do I, but only if the hardware I2C bus is okay.

@PerryBebbington Going the PIC way requires knowledge of that processor and time to make it.

To be clear, I am not necessarily suggesting a PIC, I chose that one because I am familiar with the hardware. I am suggesting that @arduino_hero studies the data sheet of the processor on which ever Arduino board is of interest to find out if it can be made to respond to any I2C address rather than to a specific one. My thinking being if it's possible on the first micro-controller I happen to check then it's probably possible on others.