SoftI2CMaster: additional helpful features

There may be others who read here who are as marginally competent in coding as i am, but....

After discovering that the Honeywell Sensors I need for a project are sold with a single I2C address despite suggestions that they might be made in 8 or so flavors in the sales literature, I washed up on the shores of SoftI2CMaster.

Since this is a package which enables the use of any of the Arduino digital pins to substitute for the hardware I2C interface, I assumed it would provide a workaround for this address conflict issue. I also, foolishly as it turned out, assumed that with the substitution of the SoftI2Cmaster library for the Wire library and some fussing with pin numbers, I would simply be able to do a search and replace of Wire with "I2C" in the "Wire.whatever" commands resident in the existing and useful sketches already available for my sensors. And it would work!

But alas, this was not to be. None of the extant versions of SoftI2CMaster provides the following functions:

Wire.requestFrom(HONEYWELL1, 4);
while(Wire.available() == 0);
Wire.requestFrom(HONEYWELL1, 4);
byte a = Wire.read();
etc....

The beauty of this version of requestFrom is that it allows the specification of the number of bytes to be read from the specified register, and the while(Wire.available() == 0) lays them out so that they can be read a byte at a time.

easypeasy in Wire.

So the issue is that some very good libraries have been constructed for people who can code the sketches themselves, which I suppose like a lot of other things, I'll eventually work out.

But it could have been so easy. There appear to be four or five libraries available to use digital pins instead of hardware for I2C, and a couple of them are quite sophisticated, and yet....

I can't be the first person to have thought of this. Maybe code that works on the digital pins must necessarily be so different that the commonality in architecture between Wire and SoftI2CMaster isn't
reliably achievable.

Am I missing something here?

BTW, nothing I've said above should be interpreted as critical of the people who have put together these libraries, some with a considerable amount of signal testing. Really admirable.

Maybe I should work harder on my code.

I tried to stay away from soft I2C, so I didn't use any of them.

Using multiple sensors on a single I2C bus can be done with a mux, or a special I2C-mux/extender, or sometimes with a trick.
So I suggest to use a mux, even if that has many pitfalls.

Whenever you see code like this: while ( Wire.available () == 0 ) ;
You can be sure that the writer of that code has done a bad job.
It doesn't work like that. The Wire.requestFrom() actually waits until the number of specified bytes have been received. If Wire.requestFrom() returns, the I2C session has completely ended. The Wire.available() only tells how many bytes are in the buffer.

Still me, I found my earlier login identity. I found some other i2c sketches which do what I want. None of them has the "while" statement. must be redundant.

I've decided to modify the best (to my mind) of the SoftI2C Libraries to add the byte count specification to requestFrom.

Thanks much for your observations.

john

I found the handiwork of Loovee, seeed technoologies which does not have the avaiable fiunction but does have requestFrom(address quantity). And it works for me.

library is here:

I only need two bytes and it does seem to work well - readings agree with 2nd sensor running on Wire and located in same environment.

What a relief.

john

That is the most simple code, but it needs a few fixes.
Looking at the code, I think that SCL is not set HIGH at the end of a I2C session.
And the function SoftwareI2C.endTransmission() does not return a value. That is needed to see if the Slave did acknowledge the address, which is needed to be able to run a i2c_scanner.

Perhaps the timing is also not perfect, but that is a minor problem.
If the problems are fixed, it shouldn't be hard to expand it for many I2C busses with a single SCL and multiple SDA. Perhaps up to 16 sensors with the same I2C address can be connected to an Arduino Uno.

Hi Peter,
Thanks for your thoughts on this. The way I'm using this is pretty crude and it does seem to work for me.

See the PM I sent you with more details

best regards,

john ferguson
delray beach, fl

I have read the PM, but I reply here :slight_smile:

The Arduino pins go directly to the pins of the microcontroller. Therefor the Arduino is for hobby and is not something industrial. You can make it a lot safer with a resistor to an input pin to protect it.

I hope you don't use long wires for the I2C. About up to 50cm is okay. Flat ribbon cable is not okay. Some can use a I2C bus up to 2 meters.
A level shifter does make it more reliable. Search Ebay for : i2c level

That reeedstudio Software I2C is worth fixing, and I looked at it, but I can't be sure if a few fixes by me would result in something safe and sound.
For a reliable multi-I2C bus, I would use a hardware mux.

I am using a level shifter and cable is good communications cable, shielded with big conductors. maybe I should post what I put in pm in case anyone else is interested.

like I lot of things i do, i put the thing together and then work on it until it performs right. this can never be a commercial project - likely not robust enough.

thanks again,

john

A good communications cable is bad for I2C.
The I2C bus doesn't like a cable at all, it wants loose wires hanging in free air.
Seriously, the I2C is never designed to be used with a cable at all.

Ah, cable length and type. It will be easy to try. I need about 8 feet of wire between the level shifter and the arduino. I have to go back and look at what I did on my boat, but i believe the cable length there was over twenty feet and that worked successfully for two years and was working when we sold the boat - details to follow although I think I posted most of them on a thread here which could be found by searching "SeaTalk" It is late here, but I'll check my notes for device.

best,

john

hi Peter,
I checked the boat project and find that i ran Pololu lsm303dlh ic2 signal from the radar arch of the boat down to the arduino controller on the bridge which required 24 feet of cable. It provided tilt-compensated heading information for an anchoring monitor. I think I used the same cable I'm planning to use here. i didn't use a level shifter, compass ran 3.3 volts but signal went into the sda/sdl on the Mega2560 I used for this. It could be that the pololu board had a level shifter built in. it worked so as with most things that work, i didn't learn anything.

I agree that running i2c inside a shielded cable sounds like there would be a risk of rfi for the signals themselves.

we'll see.

thanks for your thoughts,

john

This one has a level shifter : Pololu - LSM303DLH 3D Compass and Accelerometer Carrier with Voltage Regulators

The I2C siignal can have only a little capacitance to ground, which can be larger with a shielded cable. But lowering the speed will help.
However, a coupling between SDA and SCL is worse, and lowering the clock does not help.
When the SDA changes state, the SCL must be steady and vice versa. If a state change cause a glitch or pulse in the other, the I2C bus does no longer work.
In another topic I wrote something like this: Don't put SDA and SCL next to each other in a ribbon cable or twisted pair, they don't like each other that much.

Peter,
I could have been lucky on the boat project, I think cable I used was Garmin 8 conductor datacable left over from another project. It was definitely not twisted pair. I cannot remember if it was shielded - maybe not, and maybe I had the sda and scl wires not near each other - possibly on opposite sides of group of wires. I know i didn't think about it and there was only one i2C device in the system.

I accepted your advice about the MUX and bought one that can handle up to four i2c devices. My biggest worry about this project is noise from the engine. The Gipsy Queen has shielded ignition as do most modern airplane engines, but then there is the other instrumentation and the alternator.

Those issues drift more into the "project" area and if they prove problems, I'll have to deal with them.

thank you again,

John

The MUX I bought from DSS Circuits in Massachusetts works fine. I was able to connect both Honeywell Pressure Sensors to it and read the signals reliably at the other end of 12 foot cable. I have a Real Time Clock which is also an i2c device and there is no conflict - different address, of course. So the mux has an address of 0x70, the Honeywells, 0X28, and the clock 0x68.

I still have some hardware nit-noys to deal with, but essentially this thing is read to go flying.

john