Skip to main content
Lead II
April 10, 2024
Solved

TouchGFX analog clock glitch, arms rotating counter clockwise 360 degrees, when passing midnight

  • April 10, 2024
  • 2 replies
  • 2499 views

I've found a bug in the analog clock widget. It works perfectly, except when passing midnight, then the arms go all over the place. I think they go in the wrong direction first and then bounce a few times. I've attached a video and an example project. Glitch occurs in simulator and on board.

This topic has been closed for replies.
Best answer by Mohammad MORADI ESFAHANIASL

Hello @unsigned_char_array and @JTP1 ,

Thank you so much for pointing this bug out and offering a fix for it. We will update the widget as soon as possible. 

Best regards,

2 replies

Graduate II
April 10, 2024

Hello

First, define your 'timeinfoOld' as static so it keeps the old time. Now its initialized every second to 0,  so 'timeChanged ' flag stays false when new time is 0 (midnight).

Then, real bug, as far as I see it, is in analogClock.cpp line

 newHandAngle = convertHandValueToAngle(12, currentHour, hourHandMinuteCorrectionActive ? currentMinute : 0);
 

could be

 newHandAngle = convertHandValueToAngle(12, currentHour%12, hourHandMinuteCorrectionActive ? currentMinute : 0);
 

Otherwise the Z angle of hour hand goes more than one round (hours 12 - 23), and then guard which should handle this situation

if (lastHour != 0 && currentHour == 0)
{
	hourHand.updateZAngle(hourHand.getZAngle() - (2 * PI));
}

cannot work since it takes only one round away. (Z angle stays positive, about  2*PI and then when new Z angle is 0, we see hour hand quickly turning one round back)

Or then manipulate guard like

if (lastHour != 0 && currentHour == 0)
{
	while(hourHand.getZAngle()>0)
	{
		hourHand.updateZAngle(hourHand.getZAngle() - (2 * PI));
	}
}

Hope this helps somebody :D

Br JTP

Lead II
April 11, 2024

I can't believe I forgot to make timeinfoOld static. Now it looks a lot better. I will see if I can fix analogClock.cpp. For some reason if I set a breakpoint it will never get there. I think the code is compiled to a library. I will see if I can make a custom widget that fixes the problem.

"Kudo posts if you have the same problem and kudo replies if the solution works.Click ""Accept as Solution"" if a reply solved your problem. If no solution was posted please answer with your own."
Graduate II
April 11, 2024

Good. You must copy analogClock.cpp for example to /gui/src/common- folder and edit it there to get it compiled :thumbs_up:

Lead II
April 11, 2024

I discovered the analog clock needs to be updated even if time hasn't changed, otherwise the animation doesn't work. So I disabled the time changed check for the analog clock altogether. Your modulo fix works for hours. However the following code doesn't work if the arm moves more than 1 tick past the 0 mark:

 

 

 if (lastSecond != 0 && currentSecond == 0)
 {
 secondHand.updateZAngle(secondHand.getZAngle() - (2 * PI));
 }

 

 

I will check if I can fix it so any change will always go clockwise even if the time change is more than 1 step. If the step is too large I may just disable animation.

 

EDIT:

I fixed it (Thanks to JTP1). I've attached to modified source. Below is a snipped of my modification for the second hand:

 

 

// check if sign of absolute angles difference matches sign of normalized difference of angles
oldHandAngle = secondHand.getZAngle();
diff = (((int16_t)currentSecond - (int16_t)lastSecond + 60 + 30) % 60) - 30;
if (diff > 0)
{
	if (newHandAngle < oldHandAngle)
	{
		while(newHandAngle < oldHandAngle) // correct old angle to force clockwise rotation
		{
			oldHandAngle -= (2 * PI);
		}
		secondHand.updateZAngle(oldHandAngle);
	}
}
else if (diff < 0)
{
	if (newHandAngle > oldHandAngle)
	{
		while(newHandAngle > oldHandAngle) // correct old angle to force counterclockwise rotation
		{
			oldHandAngle += (2 * PI);
		}
		secondHand.updateZAngle(oldHandAngle);
	}
}

 

 

I first calculated the normalized diff between -30 and +29. And if the diff is positive I want to rotate clockwise, otherwise counterclockwise. If the absolute difference between calculated angles has a mismatching sign I will adjust the old value by one full rotation until it matches. The advantage is that this works for adjusting the time forward or backwards and at any point! So if you set the clock back a little it won't do a near full rotation clockwise but just a little backwards.

If the TouchGFX team can apply the same fix that would be great!

"Kudo posts if you have the same problem and kudo replies if the solution works.Click ""Accept as Solution"" if a reply solved your problem. If no solution was posted please answer with your own."
ST Employee
April 12, 2024

Hello @unsigned_char_array and @JTP1 ,

Thank you so much for pointing this bug out and offering a fix for it. We will update the widget as soon as possible. 

Best regards,