2025-04-22 10:41 AM
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.
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;
}
}
}
}