2025-03-21 4:22 AM
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();
}
Solved! Go to Solution.
2025-03-27 11:52 PM
@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:
You'll have a producer (sensor) that collects data and pushes it to a queue.
The consumer (Model.cpp) will pull data from the queue inside Model::tick().
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
2025-03-21 4:33 AM
@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?
2025-03-21 4:48 AM
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
2025-03-24 3:26 AM
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,
2025-03-24 5:51 AM
Hello @GaetanGodart,
i have debugged code .. the values i got are
heading int 225
angleRadians float 3.92699075
it still not rotating..
2025-03-24 5:59 AM - edited 2025-03-24 5:59 AM
Have you debugged your sensor interface code?
Is that getting correct readings from the sensor?
2025-03-24 6:40 AM
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,
2025-03-25 10:00 PM
@Andrew Neil yes i have debugg the code.. i was getting same reading everytime.. i think it is code integration issue.
2025-03-25 10:07 PM
@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
2025-03-25 11:50 PM
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