2022-08-08 12:04 AM
Hello,
I created a test project (Riverdi_101STM32H7-4.20) on the side of my main project the other day about managing a clock between multiple screens via a container (see here : https://community.st.com/s/question/0D53W00001g13KBSAY/custom-container-on-multiple-screen-set-digitalclock-problem-solved )
I recently tried to replace my digitalClocks in my screens of my main project by a digitalClock in a container (banner). I copied exactly the same code as in my test project but it failed to work. Indeed, the behavior of the clock was really weird. It started back at 08:25:36 in the first screen (normal because it's the time I set), but then it was 00:00:00 in the second screen and 12:40:28 in the third one.
I tried everything, renaming mytickCounter, renaming the clockbanner widget, but nothing worked.
I printed on my screens the tickCounter/60 to see the problem.
Now, I saw that when I waited 3 seconds in my 1st screen and came back to my 3d, the digitalClock of the 3d screen had passed 3 hours and not 3 seconds. And there was some other weird behavior of time adding up when I changed screens.
Now ... I remember exactly setting in my DigitalClock of the 3d screen (so before I changed it for a banner/container) the time 12:40:28 in the Designer (and 00:00:00 in the 2d screen). But I deleted ALL the digitalClocks of my project in the designer to only leave the one in my banner (which is set to the typical 10:10:00 and not 12:40:28). They had the same name though.
My guess is that the designer or the project kept in memory the information for the previous digitalClocks and didn't erase everything when I deleted the widgets from my screens.
So I tested something out. I recreated from scratch my project, added the banner, copied the GUI entire file (so all my personal code) and now it works perfectly fine, like my test project.
I cannot share my current (failing) project a it has personal info in it, that's why I created a test project in the beginning, to be able to share that one (shared in the link at the beginning of my question).
Thanks a lot in advance,
Eve
Solved! Go to Solution.
2022-09-05 07:06 AM
Hello @ELero.1 ,
After discussing those weird issues with my colleagues, we found out that your project needs a complete functioning change.
To help you change your project, I made an example for you, with 3 screens and a clock + counter running simultaneously on the 3 screens, without any bugs or reset of your values.
You will find the project attached to this post.
Of course, I will now explain you what was wrong and what we have done :
1) In your project, the handleTickHandler() method is called in the Banner directly (and then linked to a view). Since you want to share same clock values with all 3 screens, this method should cycle in a common place between this 3 screens : the Model. So, in Model.cpp, you have to include your clock routine inside the tick() method.
void Model::tick()
{
tickCounter++;
if (tickCounter % 60 == 0)
{
secondsCounter++;
modelListener->updateCounterValue(secondsCounter);
if (++seconds >= 60)
{
seconds = 0;
if (++minutes >= 60)
{
minutes = 0;
if (++hours >= 24)
{
hours = 0;
} // End hours
} // End minutes
} // End seconds
updateClock();
} // End modulo
}
Then, you need to declare the updateClock() method, also in the Model.cpp class. This method will provide the updated values to the modelListener.
void Model::updateClock()
{
// Update the clocks
modelListener->updateClockValues(hours,minutes,seconds);
modelListener->updateCounterValue(secondsCounter);
}
2) After that, you will have to declare 2 virtual functions in your ModelListener.hpp class, in order to propagate later the value to the Presenters (because the ScreenPresenter.hpp of your screens inherit from the ModelListener).
virtual void updateClockValues(int hour, int minute, int second){
}
virtual void updateCounterValue(int secondsCounter){
}
3) Then, in each of your ScreenPresenter.hpp, you have to re-declare those virtual functions. That will enable you to get the clock and counter values into the Presenter class, and to give them later to the Views.
virtual void updateClockValues(int hour, int minute, int second);
virtual void updateCounterValue(int secondsCounter);
4) In your ScreenView.hpp files, add a function which will return the CustomContainer object of your screen. That's mandatory because you need to access the container's widgets from the presenter.
ClockContainer& getClockContainer() {
return clockContainer1;
}
5) Then, in your Presenter.cpp, implement the 2 previous methods, in order to call the CustomContainer methods for updating the UI with clock data.
void Screen1Presenter::updateClockValues(int hour, int minute, int second){
view.getClockContainer().setTime24Hour(hour, minute, second);
}
void Screen1Presenter::updateCounterValue(int secondsCounter){
view.getClockContainer().updateCounter(secondsCounter);
}
6) Don't forget to declare the corresponding methods in the CustomContainer class.
void ClockContainer::setTime24Hour(uint8_t hour, uint8_t minute, uint8_t second)
{
digitalClock1.setTime24Hour(hour,minute,second);
digitalClock1.invalidate();
}
void ClockContainer::updateCounter(int secondsCounter)
{
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", secondsCounter);
textArea1.invalidate();
}
That's the best, cleanest, and more efficient way to achieve what you want.
Don't hesitate to ask me if you have question or things you didn't succeed to implement/ didn't understand 🙂
/Yoann
2022-08-08 05:02 AM
Hello @ELero.1 ,
What happens now, when you try to run the previous project on your board or on simulator ?
Does it still display wrong number after you ran sucessfully the test project ?
/Yoann
2022-08-08 05:14 AM
Hello @Yoann KLEIN ,
When I run my test project it works perfectly fine, when I run my main project (version 1=faulty version) it doesn't work well. When I run my main project version 2 (started from scratch again in designer then copy pasting the gui file with all the functions from main v1), it works well. So there's something TouchGFX must keep in memory in my main project v1. I deleted all the digitalClocks from my screens and added the banner but it keeps in memory the parameters I set in those digitalClocks in the screens.
Version 2 works well because I never added the digitalClocks in the screens and removed them.
I searched in the entirety of my code in the IDE but I cannot find the place where it is set to 00:00:00 or 12:40:28 in version 1. And it has been proven that it wasn't in my code because when I copy the files into a new project, the weird behavior disappears.
Eve
2022-08-12 04:14 AM
Hello @Yoann KLEIN ,
I have found where the problem comes from but I'd like to know why and if possible for TouchGFX to correct the problem or tell me how to prevent it.
I have my Banner as a custom Container. I have other widgets like images, buttons and texts in my screen.
Here's the screencap of the layout. The clocks don't behave as they should here.
When I put the banner just below my container, above my background image, suddenly the clocks work as they should.
Now I first thought it was because of my normal container. So I tried to add an other image below my banner. When I did that, the clocks stopped working correctly.
So I thought. Is that a problem with having two images below my banner? So I tried with any other widget like button or other text. Same think, it's still not working.
So I thought it was because of the number of widgets below my banner. I tried changing the background image by a button and it stopped working.
Any image works : here for example, the clocks are perfect.
So I concluded that you could only use one image below the banner or the clocks would stop working properly.
My question is, how do I manage for my clocks to work if I want to put my custom container on top of all my other widgets?
Thanks in advance,
Eve
2022-08-15 01:25 AM
Hello @ELero.1 ,
That is a really weird behavior. Could you share this new version of your project, so I can try it myself and discuss the potential causes with my colleagues ?
Thanks,
/Yoann
2022-08-15 11:17 PM
2022-08-25 05:20 AM
Hello @Yoann KLEIN ,
Any news on the subject?
Thanks in advance,
Eve
2022-09-04 11:39 PM
Hello @Yoann KLEIN ,
Did you manage to find some time to discuss the weird behavior with your colleagues?
Kind regards,
Eve
2022-09-05 01:35 AM
Hello @ELero.1 ,
Sorry, I was busy on other things lately.
I tried to reproduce your issue, but I don't obtain the same behavior as the one you mentioned.
In the project you shared me, the "print" counter works normally when you switch from Screen1>Screen2>Screen3, not depending whether you put images above or below in the widget list.
But, when I switch from Screen2>Screen1 again, this "print" counter gets initialized to 7620, for some reason:
Does that sound familiar to you, or do you observe a complete different behavior in your project ?
/Yoann
2022-09-05 02:42 AM
Hello @Yoann KLEIN ,
I have found out maybe a clue that could help us:
No problems between the screens if you put the banner at the exact same position in the 3 screens (here for example position number 4 but it also works when everything is in position 2)
But the moment I change this (for example 4th position in screen 1 and 5th in screen 2 and 3), the moment I switch from screen 1 to 2, the counter is starting at 0 on screen 2 and increments perfectly between screen 2 and 3 no matter how many times I change. When I get back to screen 1, it counts on its own counter (starting from where it left off the previous time we were in screen 1). I therefore think that there is one counter keeping in memory where it is for screen 1 and one other counter keeping also in memory where it is for screens 2 and 3.
But something else happens when I choose positions s1:4, s2:4, s3:2,
Screen 1 → screen 2 : everything goes well, continues counting.
Screen 2 → screen 3: starts back at 00:00:00 (cnt=0).
Screen 3 → screen 2: 14:10:30 (cnt=0) not like the first example when it started back from where it left off in screen1.
Other example s1:4, s2:2, s3:2
Screen 1 → screen 2 : gets back to 00:00:00 (cnt=0)
Screen 2 → screen 3: continues counting from the time of screen 2 so for example 00:00:25 (cnt=25)
Screen 3 → screen 2: same, continues counting
Screen 2 → screen 1: 15:00:27 (cnt=0)
I didn't manage to get the counter initialized to 7620 like you, it always came back to 0 when there was a problem with the time.
I'm really wondering if there isn't different tick counters based on the position the custom container is in.
Kind regards,
Eve