cancel
Showing results for 
Search instead for 
Did you mean: 

Simple example to demonstrate use of a Wildcard on TouchGFX

Mon2
Senior III

Hi.

Is there a simple, complete example on how to use a Wildcard that can populated in real-time with custom values? That is, change a counter every few seconds or similar.

For example, reading from an I2C widget and then print onto the display?

So far, have most of the day invested to learn but failing. What a painful exercise this has become.

Here is what I have so far:

1) Used TouchGFX to create a textArea1 with Wildcard1 -> wildcard buffer set to 10.

2) Initial value is blank.

3) After much trial and error, able to print my value using the following code:

Screen1View.cpp

#include <gui/screen1_screen/Screen1View.hpp>
#include <texts/TextKeysAndLanguages.hpp>
#include <touchgfx/Color.hpp>
#include "stm32f4xx_hal.h"              // Keil::Device:STM32Cube HAL:Common
 
Screen1View::Screen1View()
{
 
}
 
void Screen1View::setupScreen()
{
  
  textArea1.setTypedText(TypedText(T_SINGLEUSEID1));
  textArea1.setXY(88, 180);
  textArea1.setColor(Color::getColorFrom24BitRGB(0xFF, 0xFF, 0xFF));
  textArea1.setWildcard(txtBuffer);
  add(textArea1);
  updateTxt(129);
  updateTxt(315);
      
  
 
 
}
 
void Screen1View::updateTxt(int newValue)
{
  Unicode::snprintf(txtBuffer, 10, "%d", newValue);
  textArea1.setWildcard(txtBuffer);
  textArea1.resizeToCurrentText();
  textArea1.invalidate();   
}
void Screen1View::tearDownScreen()
{
 
}

The above works to print 315 onto the screen.

Q1: How to update the above after a period of time?

Q2: Is there a simple code sample that will demonstrate counting from 0..9 to the above textArea1 wildcard?

Is the solution to create a new FreeRTOS thread and make repeated calls to the above after a period of time?

It appears that HAL_Delay(xx) cannot be used here. Tried to insert HAL_Delay(100) between lines 19-20 and failed to work to see 129 -> then 315.

Also, why does 315 stay statically posted onto the screen after compiling and reflashing?

Expected to see 129 and then 315.

The documentation is severely lacking. Where are the referenced code examples from the Draupner website? They do not appear to be posted inside the 4.10 toolchain.

ie. from

https://touchgfx.zendesk.com/hc/en-us/articles/207015345

https://touchgfx.zendesk.com/hc/en-us/articles/207015345-Using-texts-and-fonts

Where can the following reference example be found? Guessing it is no longer supplied in the current distribution.

0690X000006CwPCQA0.png

This toolchain requires complete and concise code examples of "how to".

A good product manual should have started with a simple "Hello World" but instead, came across C++ functions:

https://www.touchgfx.com/documentation/html/index.html

How about full examples on how to use each of these functions?

No problems in using the GUI tool, interactions, printing via button clicks / callbacks but this wildcard is something else.

There must be something that I am missing or is that the only available documentation?

Printing to the screen should not have consumed the better part of the day.

Extremely frustrated with this current experience.

1 ACCEPTED SOLUTION

Accepted Solutions
Martin KJELDSEN
Chief III

Hi,

Sorry you're having trouble! I'll make a note to take a look at the documentation for wildcards - It's supposed to helpful!

There are a few ways to have your view "come to life" like hooking into the tick event of the application or sending messages from your model -> presenter -> view.

In your example you're calling a method to update the text area twice, but only the last value will be shown because setupScreen() and your own method are called just once (to ultimately show 315). HAL_Delay will not work here and you must use the TouchGFX timing paradigms to create this kind of behavior.

If we take a contrived example, you could simply override the handleTickEvent() method and update the content of the textarea using the method you've already tried (update buffer, invalidate textarea that knows about that buffer).

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
 
    uint16_t tick = 0;
    virtual void handleTickEvent()
    {
       tick++;
       Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", tick);
       textArea1.invalidate();
    }
...

To achieve this, your typography must know about a range of possible outcome values - So in this case where we'll be incrementing a value from 0 a range of 0-9 is the right setting.

0690X000006CwT9QAK.png

Another option is to use a hardware timer and communicate with the GUI Task that way, but that's a different story. By using handleTickEvent() what you'll be doing is receive a call every time your hardware generates a VSYNC signal.

Hope that helps! Don't hesitate to ask more questions.

Best regards,

Martin

View solution in original post

7 REPLIES 7
Martin KJELDSEN
Chief III

Hi,

Sorry you're having trouble! I'll make a note to take a look at the documentation for wildcards - It's supposed to helpful!

There are a few ways to have your view "come to life" like hooking into the tick event of the application or sending messages from your model -> presenter -> view.

In your example you're calling a method to update the text area twice, but only the last value will be shown because setupScreen() and your own method are called just once (to ultimately show 315). HAL_Delay will not work here and you must use the TouchGFX timing paradigms to create this kind of behavior.

If we take a contrived example, you could simply override the handleTickEvent() method and update the content of the textarea using the method you've already tried (update buffer, invalidate textarea that knows about that buffer).

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
 
    uint16_t tick = 0;
    virtual void handleTickEvent()
    {
       tick++;
       Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", tick);
       textArea1.invalidate();
    }
...

To achieve this, your typography must know about a range of possible outcome values - So in this case where we'll be incrementing a value from 0 a range of 0-9 is the right setting.

0690X000006CwT9QAK.png

Another option is to use a hardware timer and communicate with the GUI Task that way, but that's a different story. By using handleTickEvent() what you'll be doing is receive a call every time your hardware generates a VSYNC signal.

Hope that helps! Don't hesitate to ask more questions.

Best regards,

Martin

Thanks @Martin KJELDSEN​. With the aid of your reply, now have the tick counter being printed onto the LCD display fine.

A few more questions as we are facing assorted learning curves. We are hardware engineers and our knowledge is in C so C++ is new to us (this is our first C++ project) as well (along with FreeRTOS and TouchGFX). Our schooling goes back to days when Phillipe Kahn started and ran Borland (Pascal / C compilers for DOS).

Q: How much time can we invest inside the tick routine? We wish to ping a few I2C slave devices which will consume 30-50ms at most -> extract the data and move on after printing to the display. Is that permitted? On the next tick, we will use a state machine to ping a different I2C slave and do the same, etc.

Q: If no to the above idea - the approach is to create another FreeRTOS thread and after our defined xx period of time -> perform the I2C access for our updates? So for this idea, we apply the I2C updates to the same target buffer and allow for the tick timer to just update to the LCD display? Is this understanding correct?

Will the main.cpp code have access to the same buffer? Will experiment...

Many thanks for the clarity and ideas. We appear to be on the right path now.

Mon2
Senior III

@Martin KJELDSEN​ - I think we get it now. Our dim thinking (led) light is turning on 🙂 Following the Pool example code from your Draupner website - specifically the logic used by the STM32F769G Disco kit. This almost identical to what we are after.

You are creating a new thread on FreeRTOS and using the MVP model to interact under our own custom timing to update the LCD display. The tick value appears to be about every 16ms so it is not wise for us to embed our I2C chatter inside the tick routine. Using message queues we should be able to perform the required tasks.

For now, please ignore or quickly validate our approach.

Reference to other readers:

https://touchgfx.zendesk.com/hc/en-us/articles/205074561-Interfacing-with-other-hardware-peripherals

This is the example that should suit as well:

http://ftp.draupnergraphics.com/TouchGFX/knowledgebase/PoolDemoHwInt469Eval.4.9.3.zip

ADC is sampled in a separate thread and then the results are posted using the tick timer.

We had the click button method working but is not suitable as we wish to continue to monitor the I2C results in the background.

Will continue to experiment and learn...Thanks again!

@Mon2​ , I'll just reply to your questions even if you've become wiser to them in your latest post.

30-50ms is a lot to spend inside the tick routine if you want a high framerate. Anything you do inside tick(), in terms of blocking calls, will be a part of your render time. So the answer is to apply the principles you've discovered where you e.g. create peripheral threads that communicate with an I2C slave device and then communicate that through a message queue to the GUI Thread (Model::tick()) that checks that queue every tick() / VSYNC.

The model knows about the active presenter, and can then communicate with it to ultimately display the value from the queue on the view.

You're on the right path now. This is the procedure we recommend using, as outlined in the article. There are a couple of different examples in there - Polling peripherals from individual tasks and communicating that through a FreeRTOS message queue and also using an interrupt based procedure.

I'm progressing on writing an article that should explain all this much better. How timing works and how TouchGFX is designed in general to give users a better understanding of the inner workings.

Glad to see you've made some progress! Let me know how you do.

Hello, Martin! I know that this is old, but Google sent me here while looking for answers related to TouchGFX. Were you able to finish the artcile you were talking about in the above comment? Also, I tried to read gouchgfx.zendesk.com articles but no success. Were they moved to another location? Thank you

We've moved away from zendesk some time ago. Go to support.touchgfx.com instead. You should be able to find information on how to interface with backend/hardware and propagate that to the UI

Now you can also find the examples i talked about earlier as direct examples in the designer, for code inspection 🙂

/Martin