How to use I2C SDA2 and SCL2 on stm32f103c8tb with my compass HMC5883L

i tried this 2 methods it shows x=0 y=0 z=0 while with the pro micro board it works perfectly could someone help me please
#include <QMC5883LCompass.h>
#include <Wire.h>
//TwoWire Wire1(PB11, PB10);
//TwoWire Wire1(1,I2C_FAST_MODE);
TwoWire Wire1(2,I2C_FAST_MODE);
QMC5883LCompass compass;

void setup() {
Serial.begin(9600);
compass.init();

}

void loop() {
int x, y, z;

// Read compass values
compass.read();

// Return XYZ readings
x = compass.getX();
y = compass.getY();
z = compass.getZ();

Serial.print("X: ");
Serial.print(x);
Serial.print(" Y: ");
Serial.print(y);
Serial.print(" Z: ");
Serial.print(z);
Serial.println();

delay(250);
}

Hi @newtechai

Looking at your code, it appears that your QMC5883LCompass library code has no knowledge of your Wire1 object.

Usually sensor libraries that employ communications over I2C use the standard Wire library by default, together with the board's SDA and SCL pins.

However, sometimes libraries also permit an additional I2C port to be specified by passing in the address of a second Wire object as argument. For example the Adafruit BMP280 barometer library's constructor allows a second Wire library to be specfied, (but uses the address of the Wire library by default):

Adafruit_BMP280(TwoWire *theWire = &Wire);

Therefore in your sketch you could pass in the address of the Wire1 object (after instantiating/creating it) like this:

Adafruit_BMP280 bmp280(&Wire1);

If you check the code of your QMC5883LCompass library, you'll be able see if it supports this feature.

Let me try that thank you

#ifndef QMC5883L_Compass
#define QMC5883L_Compass

#include "Arduino.h"
#include "Wire.h"
this is the libary it is using i think i should modify from here
/**
INIT
Initialize Chip - This needs to be called in the sketch setup() function.

@since v0.1;

**/
void QMC5883LCompass::init(){
Wire.begin();
_writeReg(0x0B,0x01);
setMode(0x01,0x0C,0x10,0X00);
}

/**
SET ADDRESS
Set the I2C Address of the chip. This needs to be called in the sketch setup() function.

@since v0.1;

**/
// Set I2C Address if different then default.
void QMC5883LCompass::setADDR(byte b){
_ADDR = b;
}

i downloaded the libary to compare

@newtechai Do you have a link to your QMC5883L library?

Is it this one?:

yes it is it

@newtechai The library as it stands doesn't support an additional Wire object, but it should be possible to easily modify it, so that it can.

I made the changes and for expediency did a compilation test using the Arduino Due, which I know by default supports two I2C ports: Wire and Wire1. This compiled successfully.

Here are the changes that I made to the QMC5883LCompass.h and QMC5883LCompass.cpp files:

Firstly QMC5883LCompass.h:

Change line 11 to:

QMC5883LCompass(TwoWire* p_wire = &Wire);

Then add this line to the list of private variables:

TwoWire* p_wire;

Next QMC5883LCompass.cpp:

Change the constructor to:

QMC5883LCompass::QMC5883LCompass(TwoWire* p_wire) 
{
	this->p_wire = p_wire;
}

Then do a find and replace, replacing all occurences of:

Wire.

with

p_wire->

After saving both the files, you should now be able pass your Wire1 object through to the QMC5883LCompass library in your sketch:

QMC5883LCompass compass(&Wire1);

@newtechai Here's the sketch that I compiled for the Arduino Due (Native USB Port):

#include <QMC5883LCompass.h>

QMC5883LCompass compass(&Wire1);

void setup()
{
  compass.init();
}

void loop() {}

let me do that now

it is giving normally now thank you so much
image

Hi @newtechai

Pleased to hear that your compass is working :smiley:.

:raised_hands: :raised_hands: :raised_hands:

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