Trouble with i2c and bmp280 sensors

I have a project where I need to measure atmospheric pressure in 6 different locations simultaneously. I have selected the BMP280 for this job and because they all have the same 76h address I am using AJ-Burton’s I2C XOD control nodes. When I install a single BMP280 in the XOD design I get a good answer but when I have two sensors, one of them gives very wrong numbers. Re-isolating the sensor that gave the wrong answer then gives the correct results. I must be missing something in how to put multiple BMP280s along with AJ-Burton’s Nodes. Can someone construct an example for me so I can move forward.

You can only talk to one I2C at a time. If you’re going to use the same address, then you’ve got to put a multiplexer between them. To make it interesting, I’ll send you to this version that is also controlled by I2C (but digital pin versions may be easier to program if you’re very new to XOD, since you’ll only deal with one I2C address).

However, your device appears to also be controlled by SPI, if it’s like this one

It says “It has the same specifications but can use either I2C or SPI. For simple easy wiring, go with I2C. If you want to connect a bunch of sensors without worrying about I2C address collisions, go with SPI.”

That’s really your easiest solution, to use SPI (though the multiplex solution is pretty similar, logically)… Each Chip Select from each device will sit on a different Digital Pin on the Aruino, and they all share the other MISO, MOSI, SCK of SPI

You still have to time it so you talk to only one Chip Select at a time (usually pulling to ground to select). I use Output Pulse in XOD for that type of function, and Defer Node back to the DO input pulse of the I2C or SPI.

~xbx~

Hi @kennethwmartin,

If you were trying to use my BMP280 library (wayland/bmp280-barometer — XOD) with the TCA9548A I²C multiplexer, you will have run into the problem of not being able to control when the BMP280 devices are initialized. To setup each BMP280, we have to do the following:

  1. open the appropriate channel on the multiplexer
  2. run an initialization routine

I’ve now modified my BMP280 library to include an initialization node. I’ve also created a very simple library for the TCA9548A (wayland/tca9548a-i2c-mux — XOD). It has only one node, select-channel, which can be used to open one channel on the TCA9548A at a time. Included in the tca9548a-i2c-mux library is the following example patch:

The above patch is for a hardware configuration where we have two BMP280 devices, one on channel 0 of the multiplexer and the other on channel 3.

AJ-Burton’s library (aj-burton/tca9548a — XOD) also works well and provides much richer functionality. The select-channel node in the above patch could be replaced with the open-channel node in AJ-Burton’s library, however the latter node requires slightly more memory.

N.B. the I²C address of my BMP280 devices is 77h. You will obviously need to set the ADDR pin on the init node to 76h for your BMP280s.

Thank so very much for this example and the new data for me. I will try this today.

I will let you know how it goes.

Wayland,

It works perfectly! Well, once I dug out my errors. I am having trouble understanding the logic though. Let me know if I am stating it correctly.

Upon start of the program, each channel of the TCA9548a must be initialized with its own i2c circuit one after the other. Once that is completed each of the i2c circuits will have their channel pulsed for data. Once that is done the first time the clock keeps pulsing the i2c circuits. hmmm?

It is actually the BMP280 devices we need to initialize, rather than the TCA9548A. Let’s start by looking at the block of nodes on the left hand side of the patch - this portion of the program runs only once, at start-up.

  1. At the moment the Arduino starts up, it can see only one device on the I²C bus, the TCA9548 multiplexer.
  2. The first select-channel node instructs the TCA9548 to open channel 0.
  3. The first BMP280 is now visible to the Arduino and can be initialized using the init node.
  4. We send our bmp280-device into a to-bus to avoid criss-crossing wires. The alternative would be to connect the bmp280-device node directly to the read-pressure and read-temperature nodes.
  5. The second select-channel node instructs the TCA9548 to open channel 3 and close all other channels.
  6. The second BMP280 is now visible to the Arduino and can be initialized.
  7. Once initialization of both BMP280s is complete, the output of the flip-flop changes from false to true. This boolean value is passed to the block of nodes on the right.

The block of nodes on the right handle measurement of temperature and pressure.

  1. When INTD changes to true, the clock is activated. The clock is set to generate one pulse per second.
  2. A select-channel node opens channel 0 (and closes all other channels) so that the arduino can read the current temperature and pressure measured by the first BMP280.
  3. Next, another select-channel node opens channel 3 (and closes all other channels) so that the arduino can get the latest temperature and pressure measurements from the second BMP280.

Hope this helps. Let me know if you have any questions.

OK, that was very helpful.

It certainly gives me enough to do some experimenting around. Thanks again.

Kenneth

Thanks Matt,
The TCA9548A I²C multiplexer library works well with the M5Stack Pa.HUB device:


(With some help from Matt) it can also be used to communicate with multiple LCD displays - here talking to 3 different 4004 LCD displays sitting on the same I2C address, but plugged into a M5Stack Pa.HUB device. Matt created a variant of the LCD library: wayland/text-lcd-i2c@0.0.2 that exposes an addressable init function, to allow initialisation of the different displays before writing to the screens.

Thanks again, Matt!

3xI2C_displays2

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.