Koepel:
You have done most things right.
well that's nice to hear ![]()
With the total length of the wires for SDA and SCL I mean to add every piece of wire. A star shaped bus of 20" each to four devices makes 80".
Just one more sanity check: should I count SDA and SCL separately when calculating total length, i.e. if I have just 2 devices with 8 inches of wire between'em, 2 wires, is that 16 inches (SDA plus SCL) or 8 inches? I am guessing the latter (length of SDA, length of SCL -- not length of SDA+SCL).
I will measure my star architecture but am pretty sure it will be in excess of 50cm. So I will look into the method for dropping the speed. This is hardly a time-critical app so I bet I can afford to throttle down the I2C bus quite a bit w/o any performance penalty.
The pullup resistors for SDA and SCL should be according to the I2C specifications, and that is maximum 3 mA pull down current.
Internal pullup resistors: use it only for testing.
10k pullup resistors: when a sensor is directly next to the Arduino board.
4k7 is a normal value.
The longer the wires the lower the pullup resistors should be.
You have to calculate the total value of all the pullup resistors on every Arduino board and every module.
Suppose two Leonardo boards with 50k internal each and two modules with 10k each. The total pullup resistor will be 1 / (1/50k + 1/50k + 1/10k + 1/10k) = 4k1. That makes a pull-down current of 1.2 mA.
Then you could add pullup resistors of 4k7 to 5V to create a pull-down current of 2.2 mA.
You are a little over my head there; I do know about Ohm's law, but I don't know about all the slave devices and what (if any) pullups they have. The message I take away is (a) I probably so need pullup resistors and (b) I need to learn how to determine the correct value (maybe practise on a simple breadboard setup before mucking with my working device).
You can test the pull-down current of a I2C bus. Turn everything on, call Wire.begin(), but keep the I2C bus idle. Then with a multimeter measure the current (shortcut current) of SDA to GND and of SCL to GND.
OK, I can make a minimalist version of the code that warms up the bus but never uses it, and try this. And all I have to do is set my multimeter to "milliamps" and put the probes across SDA/GND and then SCL/GND? I think I can handle that. If I get a number larger than 3 mA than that's bad, right? and since my bus is very long, I would ideally like a much lower number like 1.5 mA? I did read Nick Gammon's article on I2C pullups but again it was a bit over my head; what I remember was that he concluded that lower values (of pullup current) made for cleaner wave forms, up to a point, and that in his case 2.2K was about right.
I do have an Xminilab Portable which I barely know how to use (another learning curve ahead!), so it's possible that I can figure out how to watch the wave forms while the bus is in use and see what shape they are.
One power supply is the safest. That is one power supply of 5V, with the output split to two wires, going to the USB connectors of the Arduino boards. With the GNDs of the Arduino boards still connected with a wire of course.
Or a 7.5V power supply going to the barrel jack power input of both boards.
As of yesterday they are running on a shared wall wart providing 9v @ 2A. And I now realise that I need to remember to unplug them from USB before unplugging the wall wart (and the reverse at startup), otherwise they will revert to the (not so smart) USB power setup when the 9v is withdrawn. Is there any way, short of cutting traces, to tell the Arduino not to use USB power?
What about some kind of waiting loop to wait for the SDA and SCL to go HIGH ? With a message on the display or a blinking led. For example waiting for 30 seconds.
It did finally occur to me (doh!) that Leo2 might be checking the I2C bus just at the moment when Leo1 is busy doing the roll call of its slaves. If Leo2 checked at the wrong moment, the bus might be pulled low & it would report "no power". So yes, I put in a bit of a loop in the Leo2 code and maybe will make it longer yet, with many retries before it finally gives up. I suppose I could do a clunky hardware semaphore with a Leo1 port driving a Leo2 port, Leo1 holding the port high when it's busy talking to its slaves and dropping it when I2C is idle -- but gee, that seems like overkill.
Don't use Serial functions in the receiveEvent() or requestEvent(). I don't care what you do with an error, but don't use them.
The receiveEvent() and requestEvent() are real interrupt routines. The Serial functions use interrupts themself. That can cause a lot of troubles. I know that it is in the official Arduino examples, but that is terrible. Those interrupt routines should be very short to keep the I2C communication fast and reliable.
Remove those Serial.print and Serial.println from those functions right now.
OK, OK, I heard you
they are outta there! I set another volatile global var instead and check it when safely outside the interrupt code.
Fritzing does not produce "real" schematics. When you learn KiCad or Eagle, you already know 50% of the other one. It takes time to learn to use them. Well... not only time, also frustration and asking yourself why those programs make it hard instead of easy.
OK glad it's not just me then
-- I took an initial look at KiCAD and reeled back in dismay. So complicated, so unwieldy. Seems like an awful lot of learning curve to design a very simple board. However I realise I really do have to learn a PCB layout program of some kind eventually, so it may as well be KiCAD. At least it looks smarter & more flexible than Fritzing.