Go Down

Topic: Reading BMP-280 (Sensor) using SoftI2C (Read 1 time) previous topic - next topic

psman

Hello,

I started using the BMP-280 with I2C some weeks ago (which is working pretty fine), and recently came across SoftI2C.
Because I would like to combine a bigger number of sensors I am thinking of one master-controller collecting data from different slaves (each reading its BMP-280 via SoftI2C).

Has anyone tried to read the BMP-280 via SoftI2C and changed the Pins from A4 and A5 to any others?

Thank you very much!

pylon

Quote
Because I would like to combine a bigger number of sensors I am thinking of one master-controller collecting data from different slaves (each reading its BMP-280 via SoftI2C).
Did I get this correctly? You're trying to read several BMP-280 by connecting them to several Arduinos by any digital IO pins, using SoftI2C to read the sensors and then connecting all these Arduinos to one master Arduino by I2C?
You do know that maximum length of an I2C bus is about 50cm, don't you?

If you just want to read several BMP-280 from one Arduino you can use bus multiplexers (p.e. TCA9548A). You even get more space as you divide your bus in 8 buses and each one can be 50cm in length.

psman

Hello,

yes, that's true - I want a "global" i2c-network for the communication between the controllers, and a "local" i2c-network around every microcontroller for several sensors as well as for one ore two displays.

Thank you for your hint with the bus multiplexer.
Since I would like to use buttons to reset measurements locally, or to turn on and off the backlight of displays, I would prefer the idea with different i2c-networks and use extenders like "PCA9515"! The master of the "global"-i2c-network mainly would collect data from the different sub-networks and insert it into a sql-database.

Thanks a lot for your help!

Koepel

#3
Jul 10, 2018, 06:23 am Last Edit: Jul 10, 2018, 06:25 am by Koepel
@psman, when you found something, please give a link to it.
This is a list of the Arduino I2C libraries: https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.

They do work, the BMP-280 with a software I2C library will work.
You can grab a library for the BMP-280 and copy the *.cpp and *.h files into the Arduino IDE. Then they are in the same folder as your *.ino file. Perhaps you need to change some #include. The *.cpp file often uses the Arduino Wire library. You can change that "Wire" usage to the software I2C.

The Arduino Uno / Nano / Pro Mini and other boards are 5V Arduino boards. The BMP-280 is a 3.3V chip.
If you connect the bare BMP-280 chip directly to a 5V Arduino board, either to power it or with signals, you will blow the BMP-280.

A BMP-280 module with voltage regulator and level shifters for SDA and SCL can be used with a 5V Arduino board. Then you can use it either with the hardware I2C bus or with a software I2C library.

A 3.3V Arduino board does not have all these problems with 3.3V sensors. All new Arduino boards are 3.3V Arduino boards.

To communicate with different modules over some distance is not what I2C is for.
When an Arduino board is set as I2C Slave, you have to carefully write the code, because many things can go wrong.
The most common solution is to use transceivers for wireless communication.
Also wifi is an option.
A wired solution could be RS-485. That would require an extra serial port. The Arduino Leonardo / (Pro) Micro and most 3.3V Arduino boards have a spare serial port.

The PCA9515 is a repeater, it is not ment for very long cables. I doubt if that is a good solution for you.

Sorry for spoiling the fun :( The I2C bus was designed by Philips to be used on the same PCB board inside a television. It's usage can be stretched with special chips, but it is easier to use the I2C bus only locally.

GolamMostafa

A BMP-280 module with voltage regulator and level shifters for SDA and SCL can be used with a 5V Arduino board. Then you can use it either with the hardware I2C bus or with a software I2C library.
The pictorial view and schematic for BME280 with built-in 5V/3.3V Regulator and level sifter.

pylon

Quote
Since I would like to use buttons to reset measurements locally, or to turn on and off the backlight of displays, I would prefer the idea with different i2c-networks and use extenders like "PCA9515"! The master of the "global"-i2c-network mainly would collect data from the different sub-networks and insert it into a sql-database.
What's the overall wire length of your "global" I2C bus? I get the impression you're abusing the I2C interface for a purpose it's not made for.

psman

Hello again,

thanks a lot for your replies, they helped very much!

@Koepel: Taking the pre-done library and altering it probably was the best idea. Since I have not done this before I had to read some tutorials first... Finally I could get rid of all the errors during compiling. For testing the code I wanted to use the Pins A4 and A5 (like used by the "normal" I2C), unfortunately it does not work yet (Serial monitor shows "Could not find a valid BMP280 sensor, check wiring!"). I have attached my files - maybe someone could have a look on it?

@GolamMostafa: The thing mit 3,3V already worked fine, thank you.

@Pylon: To be honest you are true - It would be nice to increase the distance to several meters (5-6m) if possible. If this does not work I will have to move the Hub or transfer the data via WLAN instead of LAN.

Thank you for your help!

Koepel

Does the Adafruit library work in a normal way with the Arduino Wire library ? You should test that before trying the software I2C.
Since half a year or so, some have problems with the Adafruit BMP280 and BME280 libraries. I had to select another BME280 library, because the Adafruit version didn't work for me either.

Do you use a 5V Arduino board ? Which module for the BMP280 do you use ? We prefer that you give proof that you have not already blown the sensors.
That is how this forum works. Some users on this forum have the punchline: "the problem is in the part that you are not showing us". I made up a "law" for that: "Fifty percent chance that the problem is in the section that was ignored from the beginning, because you thought that the problem could not be caused by that section".

I hope you understand now, that when you ask a question, I have many more questions in return.

If you do not include the Arduino "Wire.h", the hardware "Wire" object is not created.
When you use the SoftWire class and create a object called "Wire" with it, then most of the code can be used without changing it. That is a valid way to use a software I2C. I see no problem, I think you did it right.

Do you have a logic analyzer ?

Please give a link to where you got the SoftWire files from. Again, we want you to proof to us that you use valid files, and not some old version you found somewhere on the internet.

As a rule of thumb, the I2C bus can be up to 0.5 meters.

psman

#8
Jul 10, 2018, 11:51 pm Last Edit: Jul 10, 2018, 11:53 pm by psman
Hello Koepel,

that's more than fair, because I would not want to cause more work than necessary and because I would like to learn for future projects!

I will try to answer all your questions:
Quote
Does the Adafruit library work in a normal way with the Arduino Wire library ? You should test that before trying the software I2C.
Yes, this library (version 1.0.2 from Adafruit) still works fine with my BMP280, I retested this several times with the attached script to be sure that I have not caused any damage.

Quote
Do you use a 5V Arduino board --- have not already blown the sensors.
Yes, it is an Arduino Nano working with 5V and powerd by USB. Since I use a level shifter from 5V to 3,3V like for SD-card-readers the connection should be fine. In addition I do have a working example using "normal i2c on A4 and A5" and showing the data in the serial monitor (file attached).

Quote
If you do not include the Arduino "Wire.h", the hardware "Wire" object is not created.
When you use the SoftWire class and create a object called "Wire" with it, then most of the code can be used without changing it. That is a valid way to use a software I2C. I see no problem, I think you did it right.
I deleted the "Wire.h" and inserted the "SoftWire.h" to the script instead. However I used the same name "wire" for the object created in "Adafruit_BMP280.cpp", because I was afraid to miss any modification in the code. And I kept the Pins A4 and A5 even when using SoftWire, so no change in wiring should be required.
In addition I changed the "#include" from braces like <> to "xyz" to use files in the working-directory.

Quote
Do you have a logic analyzer ?
Not yet, I am sorry.

Quote
Please give a link to where you got the SoftWire files from. Again, we want you to proof to us that you use valid files, and not some old version you found somewhere on the internet.
First of all I had a version of "SoftI2CMaster" (Version unknown even by my Arduino IDE). Because this one did not know BeginTransmission like used by the Wire-library I finally came across
https://github.com/stevemarple/SoftWire/tree/master/src today (this one already used in my project posted some hours ago. Should I use https://github.com/felias-fogg/SoftI2CMaster instead like written in https://playground.arduino.cc/Main/SoftwareI2CLibrary?

Quote
As a rule of thumb, the I2C bus can be up to 0.5 meters.
Thanks for this hint - at the moment I am testing only on one breadboard with wires of ~10cm.

Thanks for your support!

Koepel

Sorry that you have so much troubles with it. It should work the first time. I don't know what causes it.

Since I use a level shifter from 5V to 3,3V like for SD-card-readers the connection should be fine.
The SD card readers use often a chip for level shifting. A SD card uses SPI logic signals.
The I2C level shifters use often mosfets, because the I2C bus is a open-drain/open-collector bidirectional bus.
It is two different worlds. Can you show a photo of your I2C level shifter ?

I deleted the "Wire.h" and inserted the "SoftWire.h" to the script instead. However I used the same name "wire" for the object created in "Adafruit_BMP280.cpp", because I was afraid to miss any modification in the code. And I kept the Pins A4 and A5 even when using SoftWire, so no change in wiring should be required.
In addition I changed the "#include" from braces like <> to "xyz" to use files in the working-directory.
That is correct. Then it should work. I don't know why it is not working.

Did you see the list ? https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.
As far as I know, everyone of them should work.

The libraries that you mention are well known software I2C libraries.
Use the version from Github. That code is maintained.

The "felias-fogg SlowSoftWire" is the fallback library, in case nothing else works. It uses only normal Arduino functions. That makes it slow, but it will work with every Arduino board.

In the folder with all your projects, there is a folder "libraries". Can you see what libraries are installed. Are there hardware libraries that might cause a conflict ? You can turn one extra output in the setting for compiling. Then you can see which files the compiler takes. Sometimes the compiler finds multiple libraries and chooses one of them.

When you are serious to fix this, you can do some tests. It will take some time.
Do you have a simple I2C chip that runs at 5V ? For example a DS1307 ? Start a new sketch. Don't connect other things to the Arduino board. Try to use the example from a library. Start with the I2C scanner. This example is a I2C scanner: https://github.com/stevemarple/SoftWire/blob/master/examples/ListDevices/ListDevices.ino and this example is a I2C Scanner: https://github.com/felias-fogg/SoftI2CMaster/blob/master/examples/I2CScanSoftWire/I2CScanSoftWire.ino.

When the I2C Scanner can not detect a I2C sensor, then the I2C bus is not working. In that case take another step back, and use the normal I2C Scanner with the normal hardware Arduino Wire library: https://playground.arduino.cc/Main/I2cScanner. Wiggle some wires, let it run for a while. It should be working 100%.

When both I2C scanners from the software I2C libraries work perfect, and the BMP280 does still not work... then you might have run into a very nasty bug and the software I2C is somehow incompatible with the BMP280 and the Adafruit library. In that case, try another BMP280 library.

psman

Hello again,

Quote
It is two different worlds. Can you show a photo of your I2C level shifter ?
I use this one, which should be bidirectional: https://www.ebay.at/itm/5-Stuck-4-Kanal-Pegelwandler-Level-Shifter-Konverter-I2C-5V-3-3V-Arduino-Ra/253050668603?hash=item3aeafec63b:g:xR0AAOSwiYlaD2Gc

Quote
Did you see the list ? https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.
As far as I know, everyone of them should work.
Thank you - I did not know this overview, but I tested 2 or 3 of them now, and one of them is at least connecting to the sensor (the one from todbot).

Quote
When the I2C Scanner can not detect a I2C sensor, then the I2C bus is not working. In that case take another step back, and use the normal I2C Scanner with the normal hardware Arduino Wire library: https://playground.arduino.cc/Main/I2cScanner. Wiggle some wires, let it run for a while. It should be working 100%.

When both I2C scanners from the software I2C libraries work perfect, and the BMP280 does still not work... then you might have run into a very nasty bug and the software I2C is somehow incompatible with the BMP280 and the Adafruit library. In that case, try another BMP280 library.
The I2C-Scanner works with both the "standard I2C" as well as with the different "softI2C"-libraries.


At the moment the sensor is found by the script
, and I do get data every second. However the numbers are wrong now: I do get ~-140°C instead of 27°C, and 8890mbar instead of 1000mbar. I have attached the code - does anybody have an idea what I have done wrong now?

Thanks a lot!

Koepel

That is a I2C level shifter.

All the I2C Scanners are working, so everything should be okay...  :smiley-confuse: No ? (pulling my hear and screeming: why?).
I have checked my sensors. I found a BMP180 and a BME280, but not a BMP280, so I can not test the same code :(

I had similar problems with my BME280 and the Adafruit library.
Others using the ESP8266 have issues with the Adafruit library: https://github.com/adafruit/Adafruit_BMP280_Library/issues/5.

That means there might be problems with the Adafruit libary.

In the Library Manager in the Arduino IDE is another library: The "Grove" BMP280 library by Seeed Studio.
That library code has a issue: https://github.com/Seeed-Studio/Grove_BMP280/issues/1, but that is a minor issue.

In the future, the code for the sensor will hopefully be seperated from the code of the Wire library. Selecting a certain Wire library can be like this:
Code: [Select]

#include <Wire.h>
#include <CommonSensorClass.h>
CommonSensorClass <TwoWire> sensor( Wire);

Those lines in the main *.ino file is enough to select a certain Wire libary, without changing something else.

At this moment, you have to carefully check the source code of a library. Are you willing to test another BMP280 library ?

pylon

Quote
To be honest you are true - It would be nice to increase the distance to several meters (5-6m) if possible. If this does not work I will have to move the Hub or transfer the data via WLAN instead of LAN.
Do that! You won't get the I2C bus reliable at 5m length. Ethernet, WiFi or an RS-485 based bus are alternatives that work on longer distances.

psman

Hello,

after testing different libraries for the BMP280 as well as different libraries for softI2C I noticed, that the only - theoretically - working combination I posted on 10th of July at 11:51pm is measuring at least something. And it notices changes in temperature.

Maybe it does not get the correct calibration values, and maybe I found the reason:
The todbot-softI2C-library has not implemented the quantity within the "requestFrom". I did only find the following comment in line 135ff in "SoftI2CMaster.cpp":
Quote
// Ignore 'quantity', since SoftI2CMaster::requestFrom() just sets the start of read adresses,
    // so it's the same for any number of bytes.
In addition it says, that this part is only inserted for being compatible to the standard-i2c-library.

Do you think, this could be the reason? Do you think that I should try to copy the comparable code from other libraries, or do you have a good idea how to implement the quantity in there?

Have a nice evening!

Koepel

#14
Jul 12, 2018, 12:07 am Last Edit: Jul 12, 2018, 03:15 am by Koepel
No that is not the reason, as far as I know.

Writing data is: beginTransmission - write - write - write - endTransmission
Reading data is: requestFrom - read - read - read

The Arduino hardware Wire library uses buffers. The Wire.write() writes a buffer and the Wire.read() reads a buffer. The Wire.endTransmission() and Wire.requestFrom() do all the hard work on the I2C bus.

The software I2C libraries sometimes shift the functionality around.
The SoftI2CMaster::requestFrom() does not use a buffer, and the SoftI2CMaster::read() does operate on the I2C bus.

I forgot to mention that this issue: https://github.com/adafruit/Adafruit_BMP280_Library/issues/5 is very important, since the ESP8266 uses a software I2C library ! That means whatever problem they have, you might have some of that as well.

Go Up