cancel
Showing results for 
Search instead for 
Did you mean: 

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

unsigned_char_array
Senior III

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.

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.
1 ACCEPTED SOLUTION

Accepted Solutions

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,

Mohammad MORADI
ST Software Developer | TouchGFX

View solution in original post

5 REPLIES 5
JTP1
Lead

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

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.

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

unsigned_char_array
Senior III

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.

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,

Mohammad MORADI
ST Software Developer | TouchGFX