General Casting Issue: Trying to use SoftwareWire with Adafruit BME280 Library

I'm using the Adafruit BME280 Library successfully on the standard I2C pins, using the standard Wire library.

I wanted to change the pins I'm using, and so I installed the SoftwareWire library and am now trying to get it working with the Adafruit BME280 library.

SoftwareWire: https://github.com/Testato/SoftwareWire

Adafruit Library: https://github.com/adafruit/Adafruit_BME280_Library/blob/master/Adafruit_BME280.cpp#L57

This is actually the exact line of code that I'm having problems with in the Adafruit library ... trying to understand how to cast the SoftwareWire object correctly.

In my code I had been using:

  if (!bme.begin(0x76)) {

Which was working perfectly.

Since they allow me to provide my own Wire (TwoWire) object, as seen on line 57 above (and in their comments in their examples), I was thinking this would be pretty easy.

  if (!bme.begin(0x76, &myWire)) {

BUT ... this generates an error since I'm passing a "SoftwareWire" object, and not a "TwoWire" object ... but I was thinking that since they are identical I could cast it?

  if (!bme.begin(0x76, (TwoWire) &myWire)) {

Nope ... this blows up with an error in the TwoWire library:

TestProg:263: error: no matching function for call to 'TwoWire::TwoWire(SoftwareWire*)'

   if (!bme.begin(0x76, (TwoWire) &myWire)) {

I've tried several other variations, but don't want to just keep guessing ... I want to understand what the correct syntax is ... what am I not seeing here?

Is there a proper way I can cast the SoftwareWire reference?

First of all: Do not post the code, you think is necessary.. Post ALL the code! No one can guesstimate what "bme" and "myWire" are. My guess is, that the type casting "(TwoWire) &myWire" should have been either "(TwoWire*) &myWire" or "(TwoWire) myWire".

EDIT: And if "myWire" is of type "TwoWire" then you should just use "&myWire" without any type casting.

Sorry … I know I should have posted the entire test app … :frowning:

I swear I tried all of the combinations … but you provided one that now compiles … but the app fails.

Here is the code, straight from Adafruit, modified with the SoftWire library. I’ve tried both the SoftwareWire, and SoftWire libraries and get identical results … the Arduino resets when the call to bme.begin() is called:

status = bme.begin(0x76, (TwoWire*)&myWire);

Also, I can use a I2C Scanner app … and it finds the part, on those pins, at address 0x76 … so that part is correct. Also, if I put the BME280 on pins 4/5 and run using the standard Wire library it works fine.

Here is the entire test program:

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

//#include <Wire.h>
#include <SoftWire.h>
//#include <SoftwareWire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup() {
    Serial.begin(115200);
    Serial.println(F("BME280 test"));
    delay(1000);

    bool status;
    
    Serial.println(F("Before SoftwareWire"));
    delay(1000);
    // create my SoftwareWire to use alternate pins ...
    SoftWire myWire(18, 22);
//    myWire.setTimeout_ms(40);
    myWire.begin();
    Serial.println(F("After SoftwareWire"));
    delay(1000);
//    myWire.setTimeout_ms(200);

    // default settings
    // (you can also pass in a Wire library object like &Wire2)
    Serial.println(F("Before bme.begin"));
    delay(1000);
    status = bme.begin(0x76, (TwoWire*)&myWire);

    // NOTE: IT NEVER GETS HERE!
    Serial.println(F("After bme.begin"));
    delay(1000);
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
    }
    
    Serial.println("-- Default Test --");
    delayTime = 1000;

    Serial.println();
}


void loop() { 
    printValues();
    delay(delayTime);
}


void printValues() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();
}

You are using class "SoftWire" and trying to cast it to an unrelated class "TwoWire" - this is not possible. You need to use the class TwoWire declared in Wire.h instead of SoftWire.

You need to modify the library and change it to expect an object of class SoftWire.

Makes it very hard to use alternative wire or spi classes even if they implement the same api

Hi
Seems like I am trying to do the same thing. I'd also like to use a bme280 without native i2c support.
Did you manage to make it work?
I wonder why you have both files in your code: SoftwareWire and SoftWire. What is the difference?

Found this page https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries that probably answers the question and also might be a source for other solutions ... or just a waste of time?

Regards

Hi,
just wanted to add that finitespace - https://github.com/finitespace/BME280/pull/82 was so nice and programmed a BMEI2CSoftwareWire class

I am not able to make this work yet - maybe someone else?

regards