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();
}

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kai_Satone
Senior

@Prajyot1 
Try using a Queue to send sensor data from a sensor to Model.cpp and then process it using Model::tick().

Here's what I assume:

  1. You'll have a producer (sensor) that collects data and pushes it to a queue.

  2. The consumer (Model.cpp) will pull data from the queue inside Model::tick().

  3. We’ll use std::queue with a mutex and condition_variable for thread safety.

void Model::tick() {
#ifndef SIMULATOR
    BNO055_Data sensorData;
    // Check for new data without waiting (timeout 0)
    if (osMessageQueueGet(mid_BNO055MsgQueue, &sensorData, nullptr, 0) == osOK) {
        currentHeading = sensorData.heading;
        printf("Model tick: Updated heading from queue: %.2f\n", currentHeading);
    }
#endif

    if (modelListener) {
        printf("Model tick: Sending heading %.2f to presenter\n", currentHeading);
        modelListener->updateHeading(currentHeading);
    }
}

and also there could be some error like Embedded-specific declarations for that you can use 

extern "C" {
}
#endif




View solution in original post

33 REPLIES 33

@Prajyot1 wrote:

i have share the codes.


Is there a problem with it, or are you just sharing it for  the benefit of anyone who might be interested?

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.

Actually there is problem with rotation . the image is not rotating according to the sensor value.. i am not getting the  how can i resolve this issue.. video of testing 

GaetanGodart
ST Employee

Hello @Prajyot1 ,

 

Can you debug to check that you enter the functions

If you do reach "updateCompass", please check the value that it receive.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Hello @GaetanGodart,
i have debugged code .. the values i got are
heading            int        225
angleRadians  float     3.92699075
it still not rotating..

Prajyot1_1-1742820694720.png

 



Have you debugged your sensor interface code?

Is that getting correct readings from the sensor?

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.

Are you sure that your display is not frozen? If you are not sure, just add a box and move it 1 pixel every tick.

 

I have tried to call

textureMapper1.setAngles(0, 0, 3.92699075);
textureMapper1.invalidate();

and it worked fine for me on a simulator.
If you call your function in the simulator (through a button click for instance), does it work?

What about if you call the function (click the button) on target?

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

@Andrew Neil yes i have debugg the code.. i was getting same reading everytime.. i think it is code integration issue.

 

@GaetanGodart  i tried but it do not worked. also while running simulator it shows error. so i wrote new code .it has BNO055 library files. but in that also the texture mapper is not rotating

 

 Compile
        make -f simulator/gcc/Makefile -j8
        Reading ./application.config
        Reading ./target.config
        Compiling gui/src/screen1_screen/Screen1View.cpp
        Compiling generated/gui_generated/src/screen1_screen/Screen1ViewBase.cpp
        Compiling gui/src/model/Model.cpp
        Compiling gui/src/screen1_screen/Screen1Presenter.cpp
        gui/src/model/Model.cpp: In function 'void updateModelHeading(float)':
        gui/src/model/Model.cpp:7:17: error: no previous declaration for 'void updateModelHeading(float)' [-Werror=missing-declarations]
         extern "C" void updateModelHeading(float heading) {
                         ^~~~~~~~~~~~~~~~~~
        cc1plus.exe: all warnings being treated as errors
        generated/simulator/gcc/Makefile:196: recipe for target 'build/MINGW32_NT-6.2/gui/src/model/Model.o' failed
        make[2]: *** [build/MINGW32_NT-6.2/gui/src/model/Model.o] Error 1
        make[2]: *** Waiting for unfinished jobs....
        generated/simulator/gcc/Makefile:155: recipe for target 'generate_assets' failed
        make[1]: *** [generate_assets] Error 2
        simulator/gcc/Makefile:32: recipe for target 'all' failed
        make: *** [all] Error 2
        Failed
    Failed

this is the error is it showing