cancel
Showing results for 
Search instead for 
Did you mean: 

Integrate BNO055 sensor code to Touchgfx compass UI

Prajyot1
Associate III

Prajyot1_0-1742555144172.png

Hello , 
i am using STM32h750B-dk . i took compass image (PNG file) as texture mapper and i want to rotate the compass image according to BNO055 sensor which is magnetometer. this is connected through I2C4 (for I2C4 , STmod+ is used). i have share the codes. Thank you!
#Model.cpp:

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#include <cstdint>
#include "stm32h7xx_hal.h"
#include <math.h>


#define BNO055_I2C_ADDR (0x28 << 1)  // Shifted for STM32 HAL
#define BNO055_MAG_DATA_X_LSB_ADDR  0x0E


extern I2C_HandleTypeDef hi2c4;

Model::Model() : modelListener(0)
{

}

void Model::tick()
{
	static uint32_t lastUpdateTime = 0;
	uint32_t currentTime = HAL_GetTick();
	if ((currentTime - lastUpdateTime) >= 1000)  // Check if 1 second has passed
	    {
	        lastUpdateTime = currentTime;

	 if (modelListener)
	    {
	        int heading = getHeading();
	        modelListener->updateHeading(heading);
	    }
	   }
}
int Model::getHeading()
{
    uint8_t buffer[6];
    int16_t mag_data[3];

    // Read magnetometer data
    HAL_I2C_Mem_Read(&hi2c4, BNO055_I2C_ADDR, BNO055_MAG_DATA_X_LSB_ADDR, I2C_MEMADD_SIZE_8BIT, buffer, 6, HAL_MAX_DELAY);

    // Convert to signed 16-bit values
    mag_data[0] = (int16_t)((buffer[1] << 8) | buffer[0]);  // X-axis
    mag_data[1] = (int16_t)((buffer[3] << 8) | buffer[2]);  // Y-axis
    mag_data[2] = (int16_t)((buffer[5] << 8) | buffer[4]);  // Z-axis

    // Calculate heading angle (in degrees)
    float heading = atan2((float)mag_data[1], (float)mag_data[0]) * (180.0f / 3.14159265359f);

    if (heading < 0)
        heading += 360;  // Normalize to 0-360°

    return (int)heading;
}

#Screen1Presenter.cpp:

#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

Screen1Presenter::Screen1Presenter(Screen1View& v)
    : view(v)
{

}

void Screen1Presenter::activate()
{

}

void Screen1Presenter::deactivate()
{

}
void Screen1Presenter::updateHeading(int heading)
{
    view.updateCompass(heading); // Send heading to the UI for display

}

#Screen1View.cpp:

#include <gui/screen1_screen/Screen1View.hpp>

Screen1View::Screen1View()
{

}

void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
}

void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}

void Screen1View::updateCompass(int heading)
{
    float angleRadians = heading * 3.14159265359f / 180.0f;
    textureMapper1.setAngles(0,0,angleRadians);
    textureMapper1.invalidate();
}

 

 

33 REPLIES 33

i have update the code ..
In model.cpp , i am getting proper heading reading but in Screen1view.cpp, i am getting heading =0.

am i missing something or linking between files?


@Prajyot1 wrote:

 i have debugg the code.. i was getting same reading everytime


So your basic sensor interface was not working?

If the basic sensor interface is not working, then clearly your GUI cannot work !

The GUI cannot magically create correct data by itself !

You need to get the basic sensor interface working first !

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Yes , i have corrected sensor code .. now it is giving proper readings.

Prajyot1_0-1742985737333.png

Prajyot1_1-1742985828002.pngPrajyot1_2-1742985854513.png

 

In setHeading , i am getting proper values. but in tick() , i am not getting values 

Please see How to insert source code - not as images.

Show the definition of currentHeading - is it volatile ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

yes the currentHeading is volatile

class Model
{
public:
    Model();

    void bind(ModelListener* listener);
    void tick();

    void setHeading(float heading);

protected:
    ModelListener* modelListener;
    volatile float currentHeading;
};

#endif

 

So what do you see in your printf output?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Hello @Prajyot1 ,

 

It is hard to follow where you are right now because you send a lot of message.

Have you fixed the error message in the comment I am responding from?

 

You issue could be from different reasons.
Andrew say you should check your sensor.
I think it could either be because you are not able to get the data from the model to the screenView (you have to check that your function definitions are the same so the link correctly, perhaps you can create a simple project to just test that you understand and can send data from model to view.
Another reason could be that indeed your texture mapper doesn't move, you should test that by calling a function that does that only.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

the values from sensor like 27.937,81 ,etc

@GaetanGodart  yes data is not able to transfer from model to screenView. 

i have rotate the texture mapper by

textureMapper1.setAngles(0.0f, 0.0f, 29.8f);
textureMapper1.invalidate();

it rotate properly