cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with text area wildcards

Enginerdy
Associate

Hello,

I created a timer for a display using two text areas. One is a text area with a single wildcard (i.e. minutes), and another is a text area with two wildcards (i.e. seconds). It runs fine for ~9 minutes and 4 seconds but then suddenly the text area with two wildcard randomly generates a ? on the second wildcard, and this occurs on both the simulation and on the hardware that I am running. The typography has the 0-9 wildcard ranges, for all font sizes used. There are rare occasions when the question mark (?) goes away, but I do not know at what time that occurs. Any help is greatly appreciated.

Screenshot 2025-04-22 093659.pngScreenshot 2025-04-22 103627.png

Screenshot 2025-04-22 102511.png

Here is the code that controls the timer.

HPP code

#ifndef RACETIMERVIEW_HPP
#define RACETIMERVIEW_HPP

#include <gui_generated/racetimer_screen/RaceTimerViewBase.hpp>
#include <gui/racetimer_screen/RaceTimerPresenter.hpp>
#include <touchgfx/canvas_widget_renderer/CanvasWidgetRenderer.hpp>
#include <touchgfx/Color.hpp>

class RaceTimerView : public RaceTimerViewBase
{
public:
    RaceTimerView();
    virtual ~RaceTimerView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    virtual void handleTickEvent();
    
    void setRow2()
    {
    	secondRow11Painter.setColor(lOrg);
	secondRow11.setPainter(secondRow11Painter);
	secondRow21Painter.setColor(lOrg);
	secondRow21.setPainter(secondRow21Painter);
	secondRow11.invalidate();
	secondRow21.invalidate();
    }
    void set3()
    {
    	threeLight1Painter.setColor(lOrg);
	threeLight1.setPainter(threeLight1Painter);
	threeLight1.invalidate();
	textStage.setVisible(false);
	textStage.invalidate();
	textThree.setVisible(true);
	textThree.invalidate();
    }
    void set2()
    {
    	textThree.setVisible(false);
	textThree.invalidate();
	textTwo.setVisible(true);
	textTwo.invalidate();
    	twoLight1Painter.setColor(lOrg);
	twoLight1.setPainter(twoLight1Painter);
	twoLight1.invalidate();
    }
    void set1()
    {
    	textTwo.setVisible(false);
	textTwo.invalidate();
	textOne.setVisible(true);
	textOne.invalidate();
    	oneLight1Painter.setColor(lOrg);
	oneLight1.setPainter(oneLight1Painter);
	oneLight1.invalidate();
    }
    void setGo()
    {
    	goVis = true;
    	textOne.setVisible(false);
	textOne.invalidate();
	textGO.setVisible(goVis);
	textGO.invalidate();
    	greenLight1Painter.setColor(lGrn);
	greenLight1.setPainter(greenLight1Painter);
	greenLight1.invalidate();
    }
    void setStop()
    {
    	textOne.setVisible(false);
	textOne.invalidate();
	textTwo.setVisible(false);
	textTwo.invalidate();
	textThree.setVisible(false);
	textThree.invalidate();
    	textGO.setVisible(false);
	textGO.invalidate();
    	textStage.setVisible(true);
	textStage.invalidate();
	if (goVis == true)
	{
		redLight1Painter.setColor(lRed);
		redLight1.setPainter(redLight1Painter);
		redLight1.invalidate();
		goVis = false;
	}
    }

    void resetColors()
    {
	threeLight1Painter.setColor(dOrg);
	threeLight1.setPainter(threeLight1Painter);
	twoLight1Painter.setColor(dOrg);
	twoLight1.setPainter(twoLight1Painter);
	oneLight1Painter.setColor(dOrg);
	oneLight1.setPainter(oneLight1Painter);
	greenLight1Painter.setColor(dGrn);
	greenLight1.setPainter(greenLight1Painter);
	secondRow11.invalidate();
	secondRow21.invalidate();
	threeLight1.invalidate();
	twoLight1.invalidate();
	oneLight1.invalidate();
	greenLight1.invalidate();
    }
    void start()
    {
    	started = true;
	RaceTimerStartButton.setVisible(false);
	RaceTimerStartButton.invalidate();
	RaceTimerStopButton.setVisible(true);
	RaceTimerStopButton.invalidate();
	RaceTimerStartButton.moveTo(-260,1000);
	RaceTimerStopButton.moveTo(10,1000);
	redLight1Painter.setColor(dRed);
	redLight1.setPainter(redLight1Painter);
	redLight1.invalidate();
    }
    void stop()
    {
    	started = false;
	countDown = 4;	//reset count down
	RaceTimerStartButton.setVisible(true);
	RaceTimerStartButton.invalidate();
	RaceTimerStopButton.setVisible(false);
	RaceTimerStopButton.invalidate();
	RaceTimerStartButton.moveTo(10,1000);
	RaceTimerStopButton.moveTo(-260,1000);
    }
    void setMsec(int16_t val)
    {
    	val = (val % 60)*16;
    	touchgfx::Unicode::snprintf(secTextBuffer2, SECTEXTBUFFER2_SIZE, "%03d", val);
	secText.setWildcard2(secTextBuffer2);
	secText.invalidate();
    }
    void setSec(int16_t val)
    {
    	Unicode::itoa(val%60 , secTextBuffer1, SECTEXTBUFFER1_SIZE, 10);
	secText.setWildcard1(secTextBuffer1);
	secText.invalidate();
    }
    void setMin(int16_t val)
    {
    	Unicode::itoa(val , minTextBuffer, MINTEXT_SIZE, 10);
	minText.setWildcard(minTextBuffer);
	minText.invalidate();
    }
protected:
    bool started;
    bool goVis = false;
    int16_t counter;
    int8_t countDown;
    int8_t countDownTime;
    int16_t sec;
    int16_t min;
    uint32_t lGrn = 0xFF00D600;
    uint32_t dGrn = 0xFF005000;
    uint32_t lOrg = 0xFFFA6600;
    uint32_t dOrg = 0xFF8A3800;
    uint32_t lRed = 0xFFF00000;
    uint32_t dRed = 0xFF700000;
};
#endif // RACETIMERVIEW_HPP

CPP Code

#include <gui/racetimer_screen/RaceTimerView.hpp>
#ifdef SIMULATOR
#include <touchgfx/utils.hpp>
#endif

RaceTimerView::RaceTimerView():
started(false),counter(0),countDown(4),
countDownTime(60),sec(0),min(0)
{

}

void RaceTimerView::setupScreen()
{
    RaceTimerViewBase::setupScreen();
#ifdef SIMULATOR
    touchgfx_printf("Race Timer Page Started\n");
#endif
    setMsec(counter);
    setSec(sec);
    setMin(min);
    setRow2();
}

void RaceTimerView::tearDownScreen()
{
    RaceTimerViewBase::tearDownScreen();
}

void RaceTimerView::handleTickEvent()
{
    if(RaceTimerStartButton.getPressedState() == true)
    {
        start();
        counter = 0;
        sec = 0;
        min = 0;
        setMsec(counter);
        setSec(sec);
        setMin(min);
#ifdef SIMULATOR
        touchgfx_printf("Start Pressed\n");
#endif
    }
    if(RaceTimerStopButton.getPressedState() == true)
    {
        stop();
        setStop();
        resetColors();
#ifdef SIMULATOR
        touchgfx_printf("Stop Pressed\n");
#endif
    }
    if(RaceTimerStartButton.getPressedState() == false &&
        RaceTimerStopButton.getPressedState() == false)
    {
        if (started == true)
        {
            switch (countDown)
            {
            case 0:
                if(++counter % 60 == 0)
                {
                    if (++sec % 60 == 0)
                    {
                        min++;
                        setMin(min);
                    }
                    setSec(sec);
                }
                setMsec(counter);
                break;
            case 1:
                setGo();
                countDown--;
                break;
            case 2:
                set1();
                if(--countDownTime == 0)
                {
                    countDown--;
		    countDownTime = 60;
		}
                break;
            case 3:
                set2();
                if(--countDownTime == 0)
                {
                    countDown--;
                    countDownTime = 60;
                }
                break;
            case 4:
                set3();
                if(--countDownTime == 0)
                {
                    countDown--;
                    countDownTime = 60;
                }
                break;
            }
        }
    }
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
GaetanGodart
ST Employee

Hello @Enginerdy ,

 

You set your counter as int_16 which range from -2^15 et 2^15, so the maximum value is around 32 000.

The issue happens after 9 minutes and 4 seconds and every second has 60 ticks:
((9*60)+4)*60 = around 32 000
So you simply go to negative values after that.

To fix that, you should reset your counter after every second and increase your second counter, then only increase your minute counter when you are at 650 seconds and set back the seconds to 0.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

View solution in original post

3 REPLIES 3
GaetanGodart
ST Employee

Hello @Enginerdy ,

 

You set your counter as int_16 which range from -2^15 et 2^15, so the maximum value is around 32 000.

The issue happens after 9 minutes and 4 seconds and every second has 60 ticks:
((9*60)+4)*60 = around 32 000
So you simply go to negative values after that.

To fix that, you should reset your counter after every second and increase your second counter, then only increase your minute counter when you are at 650 seconds and set back the seconds to 0.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Gaetan,

Thank you for pointing that out! I thought I was resetting the counter, but I guess I deleted it at some point. 

Thanks again! I really appreciate it!

My pleasure! :)

Gaetan Godart
Software engineer at ST (TouchGFX)