element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Power & Energy
  • Technologies
  • More
Power & Energy
Blog STM32H7B3I - TouchGFX Application Framework: A Mock GUI - Show Statuses, Switch Screens
  • Blog
  • Forum
  • Quiz
  • Documents
  • Polls
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
EMI-Reduction-Techniques
Engagement
  • Author Author: Jan Cumps
  • Date Created: 19 Aug 2020 3:21 PM Date Created
  • Views 6545 views
  • Likes 3 likes
  • Comments 30 comments
  • stm32h7b3i
  • rt
  • stm32h7b3i-dk
Related
Recommended

STM32H7B3I - TouchGFX Application Framework: A Mock GUI - Show Statuses, Switch Screens

Jan Cumps
Jan Cumps
19 Aug 2020

I'm selected for the STM32H7B3I-DK -  DISCOVERY KIT road test.

I'm working on a touch screen GUI for my electronic load.

In this post I'm trying a mock interface - see how I can switch between screens

Thank you fellow roadtester jomoenginer for sending me a very good starting project.

 

image

image source: the mockup running in simulator mode on my laptop

 

Goal: Build an app with two screens, display data and info

 

I'm putting some light goals here. I've already checked other TouchGFX parts, button click event handling and showing external data.

Here, I want to see if I can:

  • react on an internal event (a timer tick)
  • show a different form on the screen, from code.
  • try if my basis user interaction scenario would work

 

image

image: proposed GUI flow

 

This is a mock interface. I do not really query my electronic load. Values and messages are made up.

Check previous posts (linked below) to see how a real interaction over a serial interface works.

 

Initial Script: use Timer to Show a Progress Bar and Status while Starting Up

 

The process I'm mocking here, is checking if the test instrument is connected, then check what mode it is in.

While doing that, display a progress bar. And intermediate statuses.

Then when that's done, move to another screen based on the instrument's mode.

 

I used ST's Progress Bar tutorial to learn about using background processes and keeping the interface active at the same time.

 

image

 

There are different locations to react to a TouchGFX tick. I want the tick to animate the screen (progress bar) so I used the home screen View's tick.

I told before that this is a mock. Instead of really checking if the electronic load is ready, I faked a few moments when to simulate that the instrument was up, and it reported it's mode:

 

void MainView::handleTickEvent() {
     static int timesAnimated = 0;

     int currentValue = progrBar.getValue();
     int16_t max;
     int16_t min;
     progrBar.getRange(min, max);


     if (currentValue == min)  {
         increase = true;
         timesAnimated++;
     } else if (currentValue == max) {
         increase = false;
         timesAnimated++;
     }

     int nextValue = increase == true ? currentValue+1 : currentValue-1;
     progrBar.setValue(nextValue);

     if (timesAnimated == 2 ) { 
       Unicode::strncpy(txtStatusBuffer, (const char*)"init THEBREADBOARD,ELECTRONICLOAD,1,1.0", TXTSTATUS_SIZE);
       txtStatus.invalidate();
     }

     if (timesAnimated == 3 ) {
       Unicode::strncpy(txtStatusBuffer, (const char*)"mode detected: constant current", TXTSTATUS_SIZE);
       txtStatus.invalidate();
     }

     if (timesAnimated == 4 ) {
       static_cast<FrontendApplication*>(Application::getInstance())->gotoDisplayCCScreenNoTransition();
     }

}

 

Most of this code is indeed simulation, but there is one new thing I wanted to test: Opening a new screen when the instrument reports ready:

 

static_cast<FrontendApplication*>(Application::getInstance())->gotoDisplayCCScreenNoTransition();

 

This is the mechanism to make the LCD switch another display.

The gotoDisplayCCScreenNoTransition() method is generated by the TouchGFX Designer.

When I created the second screen, called DisplayCC, I defined the handler for its display, by generating an interaction.

 

image

No matter in what screen yo define that interaction, the functions generted will end up in FrontendApplicationBase.cpp:

 

// DisplayCC

void FrontendApplicationBase::gotoDisplayCCScreenNoTransition() {
    transitionCallback = touchgfx::Callback<FrontendApplicationBase>(this, &FrontendApplication::gotoDisplayCCScreenNoTransitionImpl);
    pendingScreenTransitionCallback = &transitionCallback;
}

void FrontendApplicationBase::gotoDisplayCCScreenNoTransitionImpl() {
    touchgfx::makeTransition<DisplayCCView, DisplayCCPresenter, touchgfx::NoTransition, Model >(&currentScreen, &currentPresenter, frontendHeap, &currentTransition, &model);
}

 

Calling the first function from the TouchGFX Application API is all that's needed to switch screens.

The second screen is very simple too. Again a mock:

 

image

 

Then - just to check the look and feel, I animate the two mock measured values:

 

void DisplayCCView::handleTickEvent() {
  static float iCurr = 0.998;
  static float iVolt = 3.898;
  static uint16_t count = 0;

  if ((count % 50) == 15) {
    iCurr = 0.997;
    iVolt = 3.898;
  }

  if ((count % 50) == 40) {
    iCurr = 0.998;
    iVolt = 3.899;
  }

  count++;

  Unicode::snprintfFloat(txtCurrentValBuffer, TXTCURRENTVAL_SIZE, "%3.3f A", iCurr);
  Unicode::snprintfFloat(txtVoltageValBuffer, TXTVOLTAGEVAL_SIZE, "%3.3f V", iVolt);
  txtCurrentVal.invalidate();
  txtVoltageVal.invalidate();
}

 

image

image source: the mockup running on the road test kit

 

What did I learn? That it's not hard to switch screens and use the clock ticks to keep a reactive application when in parallel the system is preparing startup or other things.

With the investigations done before - serial communication, backend data integration, sending commands, I'm set for the next step: real integration.

 

Related Posts
First Experience with CubeIDE
Create a TouchGFX Project with support for the Designer, CubeIDE and Debugger - Pt 1: Screen Works
Create a TouchGFX Project with support for the Designer, CubeIDE and Debugger - Pt 2: Touch Works
TouchGFX Simple Example: react on a button click
USB, freeRTOS ,Task Notifications and Interrupts
the Development Kit STMod+ Connector and Using UART2
TouchGFX Application Framework: Model, View, Presentation, Message Queue
TouchGFX Application Framework: A Mock GUI - Show Statuses, Switch Screens
TouchGFX Application Framework: MVP and the ModelListener
Write a CubeIDE MX application: Hardware Cryptography with DMA
Attachments:
MyApplication_1_20200819.zip
  • Sign in to reply

Top Comments

  • Andrew J
    Andrew J over 5 years ago in reply to Jan Cumps +2
    This is the meat I'm really interested in Jan. Looking forward to your 'real integration'.
  • Jan Cumps
    Jan Cumps over 5 years ago +1
    I've uploaded the project file to the post.
  • Jan Cumps
    Jan Cumps over 5 years ago +1
    Using container for the upper sceen part:
Parents
  • Jan Cumps
    Jan Cumps over 5 years ago

    Using container for the upper sceen part:

     

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • Jan Cumps
    Jan Cumps over 5 years ago

    Using container for the upper sceen part:

     

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • Andrew J
    Andrew J over 5 years ago in reply to Jan Cumps

    This is the meat I'm really interested in Jan.  Looking forward to your 'real integration'.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to Andrew J
    Looking forward to your 'real integration'.

    The hard part is trying to get interesting articles out of that. Everything is going to be a repeat from now on:

    - call a SCPI command

    - show SCPI data

    - change screens,

    - react on buttons.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to Jan Cumps

    That'll be interesting, at least to me.  Particularly, I'm interested in the relative complexity of programming this thing, say to what we did with the RX65N 9 months ago (blimey!!)

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to Andrew J

    Andrew J  wrote:

     

    That'll be interesting, at least to me.  Particularly, I'm interested in the relative complexity of programming this thing, say to what we did with the RX65N 9 months ago (blimey!!)

    There are limitations in what I can implement, while still supporting the TouchGFX simulator.

    Once I start talking to rtos message queues, the simulator stops being helpful.

     

    I'm trying to mitigate that by not using message queues in the GUI part, but build a glue layer, called SCPI_CLIENT.

    In real world, that's the one who sends SCPI requests from the LCD to the electronic load. And accepts info from the load and sends it to the GUI.

    In simulator mode, I'm replacing those real integrations with mock. So that when a SCPI command is sent, a "reasonable" reply is returned. Without queues, without UART to the load.

     

    That should give me the possibility to design the full front end  interactively from designer and test it from there.

     

    How does this look: I decided to go for #ifdef solution right now. There are other solutions.

     

    /*
     * ScpiMgr.cpp
     *
     *  Created on: Aug 9, 2020
     *      Author: jancu
     */
    
    #include "ScpiMgr.h"
    #include "stm32h7xx_hal.h"
    
    #ifndef SIMULATOR
    #include "FreeRTOS.h"
    #include "queue.h"
    
    extern UART_HandleTypeDef *huart;
    extern uint8_t uBuffer[64];
    
    extern "C"
    {
    extern xQueueHandle gui_msg_q;
    }
    
    extern "C" void commsFinished(uint16_t lenght) {
      ScpiMgr::commsFinished(lenght);
    }
    
    void ScpiMgr::commsFinished(uint16_t lenght) {
      xQueueSend(gui_msg_q, &_scpi_message, 0);
    }
    #else
    uint8_t uBuffer[64];
    #endif

     

    void ScpiMgr::idn() {
      _scpi_message = SCPI_IDN;
      uint8_t str[] = "*IDN?\n";
    #ifndef SIMULATOR
      HAL_UART_Transmit(huart, str, sizeof(str), 100);
    #else
      // todo fill buffer and call getReply()
      std::string str( "init THEBREADBOARD,ELECTRONICLOAD,1,1.0" );
      str.copy(uBuffer, 64);
      getReply();
    #endif
    }

     

     

    The #ifndef parts are real, when I talk to the instrument

    The #else parts are the simulation code, pretending that an instrument is attached.

     

    There's no holy grail, but I'll learn while developing.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to Jan Cumps

    I think that's a good approach - not sure what else you can do.  'Mocking' the back end is not unusual as long as it responds to the API; filling in the details later on lets you concentrate on a layer-down approach.  It's how I would do it - actually, it's how I'm building up a LabVIEW NXG Hardware Abstraction Framework for test applications.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube