How many Devices can you Connect to the I2C Bus?
bluedot.space
bluedot.space
Breakout boards are meant for a quick test. Then you're supposed to design a PCB with the devices you need all in one place. SparkFun spaghetti will only end in tears.
The other thing that sucks about I2C is that you never know what hard-coded addresses you will be limited to, until you've selected all your parts, dug into the datasheets and then discovered the inevitable collisions.
In 20 years of PCB design I think the largest number of I2C devices I've had on one bus is maybe 30? And that was pushing it.
https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-mult...
You could of course design your own multiplexer with more bytes of multiplexer address space and extend the concept indefinitely. I wouldn't recommend it, but it's possible.
SPI is so much more reliable with just two extra pins, I usually don't even consider I2C anymore.
Slave devices that rely on clock stretching are a total pain in the ass, as well. Tend not to play nice with other normal devices. https://www.i2c-bus.org/clock-stretching/
The main thing I use I2C for in recent designs is multiple channels of power monitoring, e.g. using the INA226. I agree that SPI is preferable for sensors that support it.
I mean I guess we could use an i2c GPIO expander to get extra lines. I bet that would be "fun" to get right.
SPI is usually very stable. Here it's being used to generate VGA signals: https://www.artekit.eu/vga-output-using-a-36-pin-stm32/
In some cases where you need to exceed the typically allowed bus capacitance either due to a high number of attached devices, or over a long cable run (it happens...it sucks, but it happens), you can use a part like the LTC4311 which, rather than using resistors to passively pull the bus lines to a resting high state, detects the direction changes and actively assists in pulling the lines to their intended states.
https://www.analog.com/media/en/technical-documentation/data...
(I hate it when people say that!!)
Maybe you're eg a UI/UX expert, you can help plan the direction for a project, feedback the changes needed and why, help make the project a success but just aren't competent enough to code those changes. Sure, no-one owes you their FOSS work, but it seems like we lose something if the only input allowed is from people able to do the coding.
Of course you might also just be a user. If you pay it forward, do you get to make a feature request?? If I don't code it myself ... maybe I should stop being a user if I can't contribute code?
Demanding work for free, and offering suggestions for improvements can be seen as synonymous, but they can actually be vastly different.
Projects I use heavily, like Ubuntu, I try to make myself useful offering advice on forums. That's not putting "money" in the bank of any coders but seems like it's in the spirit of FOSS - contributing what we can to create a better system.
There's always someone ready to exploit others.
Datasheets for Japanese connectors are like a circle of hell for me. Confusing and possibly incomplete dimensions, and the drawing usually looks like it was printed, scanned, and converted to jpg several times.
0: https://mediap.industry.panasonic.eu/assets/custom-upload/Co...
Thanks a lot for your comment! (Just created an account to write this!)
The most likely issue you will encounter with trying to connect many I2C devices is address collisions where devices have fixed addresses or at least some fixed bits in the address. This will probably limit you to about twenty or thirty useful devices on a bus.
So you either have way to set the address using resistors / address lines or you have some config more where you set the configuration for the sensors one by one (Cypress touch sensors had this)
This is sometimes done, though more commonly in my experience is there are some input pins which the chip uses to determine the actual address.
This might be as simple as one to three inputs which should be connected to ground or supply voltage to encode the last bits of the address.
Other chips are a bit more creative, and allows you to, in addition to ground and supply, tie the address pins to the I2C clock and data pins. This allows it to generate four combinations from per address pin.
Far more interesting in that regard is the SMBus, that is compatible in most cases with I2C but can handle things like address resolution.
> " ...and I'm sorry to say, the answer is way lower than 127"
127 is a really high number that nobody should encounter in real design situations. I2c was conceived for communications between chips on the same board; it is extremely unlikely that one could fit that many chips on a board, all talking i2c with each other on the same bus. I2c switch chips also can be used to split the bus in multiple parts so that only a few chips at a time are physically connected to the bus. Example: the PCA9548 from TI, NXP and possibly others.
https://www.nxp.com/products/interfaces/ic-spi-serial-interf...
---
"No one will ever need that code, so let's remove it."
"Aaaah, what did you do!? My SCADA products for a nuclear power plant no longer work!"
If you're interested in the unpleasant details, whitequark has posted about this at length on Twitter.
The main drag about SPI is this Phase and Polarity. Being opinionated (!) I wish the SPI were were all CPHA=0 and CPOL=0 (bits clock in on the positive-going edge).
By the time you're doing that, you're probably reading someone's tutorial on how they did it and monkey-see, monkey-do, or you're far enough along in your learning journey to know to desolder some of the pull-ups.
Arduino "won" by making things dead-easy to get working for people who frankly didn't have a clue what they were doing. This is a good thing, IMO. If it works straight away, you learn something and are inclined to take the second step. If the first attempt starts with a theoretically better lesson on how to calculate, select, order, and solder pull up resistors, you're failing at user engagement and unboxing experience by more than than you're gaining in theory-learning.
Also arguing that desoldering smd resistors is easier than finding a through hole one and plugging it into a breadboard or soldering into a prototype board is a bit of a stretch.
That's pretty nice since you can enable the I2C pull-ups just when needed.
Clocked buses, especially large parallel clocked buses, are generally a bad idea due to clock skew (clock and data signals getting farther out-of-sync with different wire length and loads.)
My experience is that chip to chip signal integrity for them is not an issue - however power/ground noise is, especially if you try and pass the power over the string to the far end
There’s a reason for things like RS422/485.
The hardest bug I’ve seen on an I2C bus was an implementation that every now and then dropped the lines to GND for a small period (~50ms). All I2C devices were working correctly, but because of supply chain reasons we had to introduce a PN change that was on paper 100% compatible.
The new PN was a SMBus device, and guess how SMBus signals a reset...
For a bus like I2C there’s basically two possibilities:
1. You are using a part with a clock rate that extends clock rate over the standard, which means you have very small pull ups on the lines because that is what the datasheet recommends for that speed (thus your rise time gets too short). 2. (And this one is way more likely) you are using I2C to communicate over a long cable.
I have been trying to work with more than one time of flight sensor and an Arduino recently, and I fried them all (the sensors, not the Arduino).
Will study this in detail now.
Not all modules sold have voltage translators built-in. These two for example seem to, but be aware of it.
Get yourself a modern 32 bit ARM Cortex-M chip, it will be cheaper and much more capable than those Atmel dinosaurs.
For example: https://www.digikey.com/en/products/detail/nxp-usa-inc/LPC81....
https://www.mouser.co.uk/ProductDetail/STMicroelectronics/ST... looks like it might be a lot of fun, but it's got a 6 month lead time on it.
Forget the "extra features." They're just along for the ride. Silicon is cheap!
I've been programming embedded systems for-fricking-ever and even I stay with Arduino libraries if I can get away with it for non-critical projects simply because it's easier.
All this is to say I’m always impressed that SparkFun has managed to build a product line around plug and play I2C with their QWIIC stuff. I’ve never used it though, so not sure how well it holds up with multiple devices.
And with Adafruit also adopting the standard there are more options for devices.
Most I2C interface sensors require minimal external components (often just a bypass cap), so they're are quite easy to use without a breakout board.
The one non-trivial thing that a breakout board might do for you is level shifting, if you're using a 5V microcontroller.
Most people splurge and use three wires though...
In theory you can have 32 addresses but in reality because of electrical limitations (even defined in the IEEE488 spec) you can only have about 24 devices.
Typically, no. In SPI all lines are actively driven high or low rather than an open drain configuration. The bus master drives SCK (SPI clock), MOSI (master out, slave in) and CS (chip select), and the slave device(s) drive the MISO (master in, slave out) line(s). From an operating perspective, pullup/pulldown resistors are not required.
Now having said that, in some cases it's considered appropriate to add weak pullup/pulldown resistors to the data lines to ensure that they're in the expected state on power up and to prevent glitches from putting slave devices into weird states.
Virtually all SPI devices that I know of are CMOS with push-pull outputs and high-impedance inputs, which are much more friendly to work with. Until you try to drive the bus with two devices by accident. See my other comment about series resistors. I have a circuit right now that's operating a SPI bus with a 100 MHz clock on a small two-layer board and I'm getting away with it. A real engineer wouldn't allow this, but it's strictly for a research project.
Never heard of PJON.
I2C is electrically far more fragile than CAN. CAN is robust against all sorts of electrical faults. While you might not be able to transmit data, you won't fry the controller, and once the fault is removed it comes back.
I2C is often more tolerant of unexpected traffic on the bus. There are far too many ECUs that will put a vehicle into limp mode (limit speed drastically) if they detect unexpected CAN traffic, even traffic not directed to them. Protocol-wise I2C is significantly simpler to get right.
CAN is really meant for distributed embedded systems where you are having to implement full blown communication between equally complex nodes.
CAN is indeed much more robust both at a physical layer with a differential line and at a transfer layer with all sorts of error detection and mitigation mechanisms.
I2C is highly suitable as an interface to a bunch of registers, while being still very simple (especially wiring/addressing) and easy to get to work. Slave devices are also typically more consistent in behavior/requirements than with SPI.
CAN is by far the most complex of these; it is not intended for connecting components on a single board, but instead to connect discrete components. It typically needs transceivers (separate from your controller), and has typically the most rigid timing requirements for participants. Multiple bitrates are possible, and the protocol already comes with mechanisms for clock synchronization, CRC checking, message retransmission on error and basic protocol structure (11/29bitID + up to 8 data bytes per message). Actual useful bandwith is often the worst with this protocol, also because overhead is very significant (think ~150bits on the bus for every message containing 8byte data+29bit ID) Max Bus baudrate is typically 1Mbit but 250K is most common, while higher rate extensions exist (CAN-FD).
Never used PJON before, but AFAICT its more of a software stack on top of existing protocols (while also defining a custom physical layer). This one is MUCH less pervasive than the other three from my experience.
While with I2C, chances are much better that your microcontroller manufacturer just provides you with a HAL_I2C_Mem_Write function, and you just use defaults everywhere, without understanding or caring, and things just work™.
But all this probably depends a lot on specific platform...
On the other hand, CAN is mildly more difficult to configure initially (usually you need to understand the message box protocol if you want maximum efficiency), but it's then pretty damn bulletproof, and far less actual code to worry about.
CAN is for off board comms.
I2C should really never leave the board.
I've actually seen a blend though, where someone hooked a couple CAN transceivers to bridge an I2C bus off board (a simple LED board had to be 3 meters away from the micro controller). At the end of the day they should have just put a micro controller on the other end and ran CAN over it, as they still had a bunch of glitches anyway.
I2C is relatively susceptible to noise in comparison to CAN. I2C is also very simple to interface with from both a h/w and s/w perspective. CAN, having timing requirements requires more thought on the s/w side.
UARTs are also simple to use and can be used in multi-drop protocols for using multiple devices and can also give good range and noise rejection in some variants (i.e. RS485, RS422, etc).
SPI is for on-board, relatively high-speed use with a handful of devices (maximum) but offers limited noise rejection.
There are also other simple protocols (e.g. one-wire) but they're less popular these days.
PJON on the other hand is pretty much unknown and is a very much higher level protocol that isn't really comparable to CAN-bus.