cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Container on multiple screen : set DigitalClock problem [solved]

ELero.1
Associate III

Hello,

I'm currently in the process of creating a Custom Container top bar (Banner) with a clock (and other values like text with wildcard) that propagates through the screens. But I hit a dead end days ago and I cannot find the solution.

Step 1: The fake hardware sets the time

Step 2: I propagate it to the model

Step 3: I propagate it to the presenter of the first screen

Step 4 : I propagate it to the custom container Banner present on all my screens. → That's where I have my problem.

The problem:

The clock updates to the time I set in my Hardware for a second, then the next second (60 ticks), it is set to 00:00:01 (first second passed) and when I change screen, the clock propagates as I want to but with the basis of the first screen aka 00:00:01.

I've based the application mainly on this ST post and glanced info in other posts but I can't manage to make my app work :

https://community.st.com/s/question/0D50X0000C5SiHjSQK/where-is-code-editor-in-touchgfx-also-where-is-output-window-to-know-errors-generatedrun-failed-for-me-where-to-check-for-errors

Here's the Screen1View.cpp code where I update my Clock in the Banner.

Screen1View::Screen1View()
{
}
 
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
    clockscreen1 = presenter->getTimePres();
    banner.setTime(clockscreen1);
}
 
void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}

Here's my Custom container BannerBase.cpp

BannerBase::BannerBase()
{
    setWidth(289);
    setHeight(72);
    digitalClock.setPosition(0, 0, 289, 72);
    digitalClock.setColor(touchgfx::Color::getColorFromRGB(0, 0, 0));
    digitalClock.setTypedText(touchgfx::TypedText(T___SINGLEUSE_BIUJ));
    digitalClock.displayLeadingZeroForHourIndicator(true);
    digitalClock.setDisplayMode(touchgfx::DigitalClock::DISPLAY_24_HOUR);
    digitalClock.setTime24Hour(10, 10, 0);
 
    add(digitalClock);
}
 
BannerBase::~BannerBase()
{
}
 
void BannerBase::initialize()
{
}
 

Here's the Banner.hpp

class Banner : public BannerBase
{
public:
    Banner();
    virtual ~Banner() {}
    virtual void initialize();
    virtual void handleTickEvent();
    virtual void setTime(MyClock value);
protected:
    int tickCounter;
    int digitalHours;
    int digitalMinutes;
    int digitalSeconds;
};

And the Banner.cpp

Banner::Banner()
{
	touchgfx::Application::getInstance()->registerTimerWidget(this);
//	digitalHours = digitalClock.getCurrentHour();
//	digitalMinutes = digitalClock.getCurrentMinute();
//	digitalSeconds = digitalClock.getCurrentSecond();
 
	digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
}
 
void Banner::initialize()
{
    BannerBase::initialize();
}
 
 
// Rajout Clock
void Banner::handleTickEvent()
{
    tickCounter++;
 
    if (tickCounter % 60 == 0)
    {
        if (++digitalSeconds >= 60)
        {
            digitalSeconds = 0;
            if (++digitalMinutes >= 60)
            {
                digitalMinutes = 0;
                if (++digitalHours >= 24)
                {
                    digitalHours = 0;
                } // End hours
            } // End minutes
        } // End seconds
 
        // Update the clocks
        digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
 
    } // End modulo
}
 
 
void Banner::setTime(MyClock value)
{
    digitalClock.setTime24Hour(value.hour, value.minute, value.second);
}

My guess is I would need to put something in the initialize of the Banner but I cannot find what exactly or why my clock is set back to 00:00:00 ... probably related to

touchgfx::Application::getInstance()->registerTimerWidget(this);
digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);

I also have a fear that the BannerBase will set my clock to 10:10:00 and I do not want that either. How can I prevent this?

If possible, I would like to keep using the registerTimerWidget since I don't wanna update each screen (there's a lot of them) I would only set up the time in my first screen. If really not possible, how can I set my 1st screen right (the time I asked in my hardware is set and not 00:00:00) and I'll save it to the model and update it in screen 2. And I fear the time I propagate it to the model and update it in screen 2, I would have missed some ticks so my time would begin to drift.

I have also read that it was planned to insert a feature in a new version of TouchGFX where we would be able to group functionalities used in several screens (like containers) to not repeat the code. Any news on this feature? It seems really interesting.

https://community.st.com/s/question/0D53W000003NieGSAS/example-grouping-of-views-with-common-functionality

Thanks in advance for your answer,

Eve

1 ACCEPTED SOLUTION

Accepted Solutions

Hello,

After trying different things, I finally succeeded on fixing your issues.

Your project is globally fine, I just had to correct small details. I will explain you what was wrong and what I had to add :

  • First, your timer started at 00:00:01 after the first second and not 08:25:36, because in your Banner::handleTickEvent() method you never read the current value of the timer, that you just initialized in Screen1View.cpp. So the digitalClock values (hours, minutes and second) were set to 0 by default in the beginning. To fix that, I just made sure that your function read the current clock value every time a new second passes.
 if (tickCounter % 60 == 0)
    {
// -> Here
    	digitalSeconds = digitalClock.getCurrentSecond();
    	digitalMinutes = digitalClock.getCurrentMinute();
        digitalHours = digitalClock.getCurrentHour();
//
 
        if (++digitalSeconds >= 60)
        {
        	digitalSeconds = 0;
 
 
            if (++digitalMinutes >= 60)
            {
                digitalMinutes = 0;
 
 
                if (++digitalHours >= 24)
                {
                    digitalHours = 0;
                } // End hours
            } // End minutes
        } // End seconds
 
        // Update the clocks
        digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
 
    } // End modulo
  • Now that the timer correctly starts from 08:25:36, I noticed that every time the user wants to switch back to Screen1, the timer reset to 08:25:36. That's because your initializing the clock to this value in Screen1View::setupScreen(), and this method is called every time you display this screen. To initialize the clock only once at startup, I had to declare a Boolean value "alreadyInitialized " in Model.hpp and create 2 methods in Screen1Presenter.hpp for modifying and reading the value of this variable. Then, in Screen1View.cpp, I check if the clock has already been initialized : If no, I initialize it to 08:25:36 through the presenter and the model ; if yes, I skip that part.
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
 
    if(!presenter->isInitialized())
    {
		clockscreen1 = presenter->getTimePres();
		banner.setTime(clockscreen1);
		presenter->setInitialized();
    }
}

I will join the fixed project to this post. Please check it and let me know if you have questions.

/Yoann

Yoann KLEIN
ST Software Developer | TouchGFX

View solution in original post

8 REPLIES 8
Yoann KLEIN
ST Employee

Hello @ELero.1​ ,

Is it possible for you to share your project ?

That could help us a lot for trying to find how to fix your issue.

Thanks,

/Yoann

Yoann KLEIN
ST Software Developer | TouchGFX
ELero.1
Associate III

Hello @Yoann KLEIN​ ,

Sure ! Here you are. (in CM7)

Thanks in advance,

Eve

Yoann KLEIN
ST Employee

Hello,

I ran your project on my computer, and for me everything seems to work fine.

The clock is correctly propagated between all screens.

Could you please provide pictures of the display or a video of the issue you are noticing ?

Thank you,

/Yoann

Yoann KLEIN
ST Software Developer | TouchGFX

Hello @Yoann KLEIN​ ,

Sure, here's some screencaps of the simulator.

Yes the propagation works fine, it's the clock I set that has a problem. I set with my fakehardware the clock to 08:25:36 in screen1.

0693W00000QMB8OQAX.png It stays at that time for 1 second then it reverts back to 00:00:010693W00000QMB8iQAH.pngFrom there it continues counting like it should

0693W00000QMB9HQAX.pngWhen I change the screens it propagates well.

0693W00000QMB9RQAX.png0693W00000QMB9WQAX.pngBut that's not the time I wanted to set at the beginning. I wanted to start at 08:25:36 and start counting from there → 08:25:37 instead of 00:00:01

Kind regards,

Eve

Hello,

After trying different things, I finally succeeded on fixing your issues.

Your project is globally fine, I just had to correct small details. I will explain you what was wrong and what I had to add :

  • First, your timer started at 00:00:01 after the first second and not 08:25:36, because in your Banner::handleTickEvent() method you never read the current value of the timer, that you just initialized in Screen1View.cpp. So the digitalClock values (hours, minutes and second) were set to 0 by default in the beginning. To fix that, I just made sure that your function read the current clock value every time a new second passes.
 if (tickCounter % 60 == 0)
    {
// -> Here
    	digitalSeconds = digitalClock.getCurrentSecond();
    	digitalMinutes = digitalClock.getCurrentMinute();
        digitalHours = digitalClock.getCurrentHour();
//
 
        if (++digitalSeconds >= 60)
        {
        	digitalSeconds = 0;
 
 
            if (++digitalMinutes >= 60)
            {
                digitalMinutes = 0;
 
 
                if (++digitalHours >= 24)
                {
                    digitalHours = 0;
                } // End hours
            } // End minutes
        } // End seconds
 
        // Update the clocks
        digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
 
    } // End modulo
  • Now that the timer correctly starts from 08:25:36, I noticed that every time the user wants to switch back to Screen1, the timer reset to 08:25:36. That's because your initializing the clock to this value in Screen1View::setupScreen(), and this method is called every time you display this screen. To initialize the clock only once at startup, I had to declare a Boolean value "alreadyInitialized " in Model.hpp and create 2 methods in Screen1Presenter.hpp for modifying and reading the value of this variable. Then, in Screen1View.cpp, I check if the clock has already been initialized : If no, I initialize it to 08:25:36 through the presenter and the model ; if yes, I skip that part.
void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
 
    if(!presenter->isInitialized())
    {
		clockscreen1 = presenter->getTimePres();
		banner.setTime(clockscreen1);
		presenter->setInitialized();
    }
}

I will join the fixed project to this post. Please check it and let me know if you have questions.

/Yoann

Yoann KLEIN
ST Software Developer | TouchGFX
Yoann KLEIN
ST Employee
 
Yoann KLEIN
ST Software Developer | TouchGFX

Hello @Yoann KLEIN​ ,

It works perfectly. Thank you so much!

Just a small question in Model.hpp you added this:

#include <touchgfx/containers/clock/DigitalClock.hpp>
touchgfx::DigitalClock digitalClock;

Why did you add those two lines? I didn't add it because I didn't understand what it was doing. It works perfectly fine without it though.

Kind regards,

Eve

Hello,

Sorry, I might have added that while testing stuff and forgot to delete it before sharing the new version of the project.

You can delete it of course.

/Yoann

Yoann KLEIN
ST Software Developer | TouchGFX