Skip to main content
Associate III
March 21, 2025
Solved

Integrate BNO055 sensor code to Touchgfx compass UI

  • March 21, 2025
  • 3 replies
  • 2278 views

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

 

 

Best answer by Kai_Satone

@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




3 replies

Andrew Neil
Super User
March 21, 2025

@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.
Prajyot1Author
Associate III
March 21, 2025

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
Technical Moderator
March 24, 2025

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,

Prajyot1Author
Associate III
March 24, 2025

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

 



Andrew Neil
Super User
March 24, 2025

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.
Kai_SatoneBest answer
Associate III
March 28, 2025

@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




Prajyot1Author
Associate III
March 28, 2025

i have able to rotate the compass texture mapper. but the wildcard is not updating the value .
here is the video  ->Compass.MOV - Google Drive 

GaetanGodart
Technical Moderator
March 28, 2025

Hello @Prajyot1 ,

 

The wildcard show question marks because you have to add the characters that can be in your wildcard. We do that to ensure that we don't add characters that are not used because they take memory space.

To add characters, go to your typography (the one you use for that textArea) and add characters to the wildcard range (here I put 0-9 to be able to use all the numbers but you can put any char you want). :

GaetanGodart_0-1743163025608.png

 

Regards,