2025-11-12 1:26 AM
Hello, I have an issue with my touchGFX gauge. First, let me explain what I want to do and how I currently do it.
What I want is receiving data from the CANbus which is a command for the gauge to which position the needle needs to point (same as a car). These commands are direct and if I write it directly to the GUI it jumps positions. It needs to move smooth to that position.
What I have now is:
I receive CAN message with an interrupt. The received CAN message I put in a FreeRTOS queue.
From a CanTask I extract the data from the CAN message that is relevant to me and is put in a other queue (aziQueue).
In the Model.cpp tick funtion I first had this:
if (osMessageQueueGetCount(aziQueueHandle) > 0)
{
if (osMessageQueueGet(aziQueueHandle, &aziTarget, NULL, osWaitForever) == osOK)
{
azi = (uint16_t)filter(aziTarget);
modelListener->aziUpdate(azi);
}
}
This was blocking the GUI, because the CAN message was send every 100ms on the bus so it slowed down the GUI update. (I need to update the gauge every thick with small steps until it reaches the command form the CAN message to make it smooth).
Now I have this as a test if it would work instead of using a queue that blocks the ticks:
volatile uint16_t aziTarget = 0;
In the Screen1View.cpp I have this function where I update the gauge:
void Screen1View::updateAziGauge(int azi)I tried both of these update functions:
gauge1.updateValue(azi, 10);
gauge1.setValue(azi);Still no smooth movement.
Do I miss something?
My display is 60Hz. I think that my filter is fine. Every thick it calculates the next step.
float Model::filter(float fAzimuth)
{
static float sfX_part = 0.0;
static float sfY_part = 0.0;
float fAzimuthDegrees = fAzimuth / 100.0;
float fMovingAverageFactorOld = 1.0 - (1.0 / (float)AZIMUTH_MOVING_AVERAGE_FACTOR); //Example: when factor is 10, old value will be multiplied by 0.9
float fMovingAverageFactorNew = 1.0 - fMovingAverageFactorOld; //And new value by 0.1
sfX_part = (fMovingAverageFactorOld * sfX_part) + (fMovingAverageFactorNew * cos((fAzimuthDegrees * M_PI) / 180.0));
sfY_part = (fMovingAverageFactorOld * sfY_part) + (fMovingAverageFactorNew * sin((fAzimuthDegrees * M_PI) / 180.0));
float fAzimuthDegreesAveraged = (atan2(sfY_part, sfX_part) * 180.0) / M_PI;
if (fAzimuthDegreesAveraged < 0.0)
{
fAzimuthDegreesAveraged += 360.0;
}
return fAzimuthDegreesAveraged * 100.0;
}Some suggestions?