开源项目

TouchGFX MVP通信架构

应用实现按照TouchGFX MVP架构来分层,使得结构清晰:

Backend/Control

F7子板读取G0传感器数据:

STM32CubeMX配置USART外设

根据原理图,STM32CubeMX配置G0通过USART2与F7子板通信外设:

串口接收G0子板传感器数据

sensor.cpp

/**
  ******************************************************************************
  * @file
  * @author
  * @version V2.0.0
  * @date    07/13/2019
  ******************************************************************************
  */
#include "sensor.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"

extern UART_HandleTypeDef huart4;

uint8_t aTxBuffer[30]; //发送缓冲区
uint8_t aRxBuffer[1];
__IO ITStatus Tx_ready_UART4 = SET; //此处必须赋值SET
__IO ITStatus Rx_ready_UART4 = RESET;
uint8_t Rx_buff_UART4[30];
uint8_t Rx_count_UART4=0; //UART4 接收计数器
uint8_t Rx_num_UART4=0; //UART4 一条指令全部接收后的接收字节数
extern ts_sensor_data s_sensor_data;


//68 01 0E 01 19 01 B4 00 00 00 00 10 5C 6E
#define FRM_START                0x68
#define FRM_CMD_UPD_SENSOR       0x01
#define FRM_FIXLEN               14
#define FRM_END0                 0x5c
#define FRM_END1                 0x6e

#define FRM_POS_START            0
#define FRM_POS_CMD              1
#define FRM_POS_LEN              2
#define FRM_POS_DATA             3
#define FRM_POS_CRC              11
#define FRM_POS_END0             12
#define FRM_POS_END1             13

uint8_t cal_crc(uint8_t *buf,uint8_t len)
{
       uint8_t t_crc = 0;
       uint8_t r_crc = 0;
        //check crc
        for(int i=0; i<len ;i++)
        {
                t_crc += buf[i];
        }
        r_crc = (uint8_t)t_crc;
        return r_crc;
}

int8_t parse_sensor_package(void)
{
        uint8_t msg[4];
        int rc = 0;
        if(Rx_buff_UART4[FRM_POS_START]==FRM_START && Rx_buff_UART4[FRM_POS_CMD]==FRM_CMD_UPD_SENSOR
           && Rx_buff_UART4[FRM_POS_CRC] == cal_crc(Rx_buff_UART4,FRM_FIXLEN-3))
        {
                HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_11);
                msg[0]=Rx_buff_UART4[FRM_POS_DATA];
                msg[1]=Rx_buff_UART4[FRM_POS_DATA+1];
                msg[2]=Rx_buff_UART4[FRM_POS_DATA+2];
                msg[3]=Rx_buff_UART4[FRM_POS_DATA+3];
                s_sensor_data.temperature[1] = (msg[0]*256+msg[1])/10;
                s_sensor_data.temperature[0] = (msg[0]*256+msg[1]);
                s_sensor_data.humidity = msg[2]*256+msg[3];
        }else{
                rc = -1;
        }
        return rc;

}


void Start_Next_UART_Receive_IT(UART_HandleTypeDef *UartHandle)
{
        HAL_UART_Receive_IT(UartHandle,aRxBuffer,1); //开启下一次接收中断
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
        uint8_t i=0;
        if(UartHandle->Instance == UART4)
        {
                Rx_buff_UART4[Rx_count_UART4] = aRxBuffer[0];
                if(Rx_buff_UART4[Rx_count_UART4-1] == 0x5c && Rx_buff_UART4[Rx_count_UART4] == 0x6e || Rx_count_UART4 > FRM_FIXLEN)//\n
                {
                        Rx_ready_UART4 = SET;
                        Rx_num_UART4 = ++Rx_count_UART4;
                        Start_Next_UART_Receive_IT(&huart4); //开启下一次接收中断
                }
                else
                {
                        Rx_count_UART4++;
                        Start_Next_UART_Receive_IT(&huart4); //开启下一次接收中断
                }

        }
}

void sensor_read_init(void)
{
        Start_Next_UART_Receive_IT(&huart4); //开启下一次接收中断
}

int sensor_read_func(void)
{
        int rc = 0;
        if(Rx_ready_UART4==SET)
        {
                Rx_ready_UART4 = RESET;
                rc = parse_sensor_package();
                Rx_count_UART4=0;
                memset(Rx_buff_UART4,0,sizeof(Rx_buff_UART4));

        }else{
                rc = -1;
        }
        return rc;
}

void sensor_read_start_next()
{
        Start_Next_UART_Receive_IT(&huart4); //开启下一次接收中断
}

传感器读取任务StartsensorTask数据处理

STM32CubeMX配置

Main函数中创建StartsensorTask任务读取将串口收到的数据通过消息队列传给UI的Model层:

ts_sensor_data s_sensor_data;

/* USER CODE END Header_StartsensorTask */
void StartsensorTask(void const * argument)
{
  /* USER CODE BEGIN StartsensorTask */
   sensor_read_init();
  /* Infinite loop */
    for(;;)
    {
        if(sensor_read_func()==0)
        {
                osMessagePut(sensor_msg_qHandle,(uint32_t)&s_sensor_data,200);
        }
        osDelay(500);
    }

  /* USER CODE END StartsensorTask */
}

Model层通过M->P->V更新传感器值

主要代码:Model.cpp

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#ifndef SIMULATOR
#include "stm32f7xx_hal.h"
#include "cmsis_os.h"

extern osMessageQId gui_msg_qHandle;
extern osMessageQId sensor_msg_qHandle;
#endif
Model::Model() : modelListener(0)
{
}
#define MAX_P_SENSORBOARD_LOST_TIM       300     //
static uint16_t s_p_sensorboard_lost_tcnt = 0;
void Model::tick()
{
#ifndef SIMULATOR
    osEvent retsensor;
    retsensor.value.v = 0;
    retsensor = o sMessageGet(sensor_msg_qHandle,1); 
    ts_sensor_data *p_sensor_data=NULL;
    if(retsensor.value.v!=0)
    {
        p_sensor_data = (ts_sensor_data *)(retsensor.value.v|0x20000000);
        modelListener->update_sensor_event(p_sensor_data);
        s_p_sensorboard_lost_tcnt = 0;
    }
    
    //check if the sensor board disconnected
    if(s_p_sensorboard_lost_tcnt++>MAX_P_SENSORBOARD_LOST_TIM)
    {
         p_sensor_data->humidity=0;
         p_sensor_data->temperature[0]=0;p_sensor_data->temperature[1]=0;
         modelListener->update_sensor_event(p_sensor_data);      
    }

#endif
}

F7子板读取按键数据:

读取任务StartkeyTask数据处理

翻页按键

void StartkeyTask(void const * argument)
{
  /* USER CODE BEGIN StartkeyTask */
  /* Infinite loop */
  HAL_GPIO_WritePin(KEY5_COM_GPIO_Port, KEY5_COM_Pin,GPIO_PIN_SET);
  for(;;)
  {
        //FY ->NEXT PAGE
        if(HAL_GPIO_ReadPin(GPIOA, KEY7_FY_Pin )==GPIO_PIN_SET)
        {
            osMessagePut(gui_msg_qHandle,0x08,200);
            osDelay(1000);
        }
        osDelay(100);
  }
  /* USER CODE END StartkeyTask */
}

通过Model层通过M->P->V更新按键操作

主要代码:

Model.cpp

void Model::tick()
{
#ifndef SIMULATOR
    osEvent retkey;
    retkey.value.v = 0;
    retkey = osMessageGet(gui_msg_qHandle,1); 
    if(retkey.value.v==0x08)
    {
        modelListener->key_event();     
    }
#endif
}

Screen1Prensenter.cpp(举例)

void Screen1Presenter::key_event()
{
    view.handleKeyEvent(8);
}


Screen1ViewBase.cpp(举例)

//Handles when a key is pressed
void Screen1ViewBase::handleKeyEvent(uint8_t key)
{
    if(8 == key)
    {
        //Interaction1
        //When hardware button 8 clicked change screen to Screen2
        //Go to Screen2 with screen transition towards East
        application().gotoScreen2ScreenSlideTransitionEast();
    }
}

配网按键

void StartkeyTask(void const * argument)
{
  /* USER CODE BEGIN StartkeyTask */
  /* Infinite loop */
  HAL_GPIO_WritePin(KEY5_COM_GPIO_Port, KEY5_COM_Pin,GPIO_PIN_SET);
  for(;;)
  {
        //PW -> WIFI CONF
        if(HAL_GPIO_ReadPin(GPIOA, KEY6_PW_Pin )==GPIO_PIN_SET)
        {
                HAL_GPIO_WritePin(M_CTRL_GPIO_Port, M_CTRL_Pin,GPIO_PIN_SET);
                osDelay(200);
                HAL_GPIO_WritePin(M_CTRL_GPIO_Port, M_CTRL_Pin,GPIO_PIN_RESET);
        }
        osDelay(100);
  }
  /* USER CODE END StartkeyTask */
}


UI界面实现

资源准备

UI界面所需要的图片库
images.7z
TouchGFX设计需要的中文字体
fonts.7z

将解压后的文件,添加到STM32CubeMX生成的Project目录下的C:~\TouchGFX\assets\fonts的fonts文件夹里,然后重新启动TouchGFX。



UI界面制作演示


说明:

1.视频不含有Screen0的配网图标以及Screen5界面的制作(原理是和里面其他的类似)。

2.我们将Screen0的圆环动画的起点设为-40度(视频演示是0度),初始化温度的UI显示为-20度(视频演示是0度)。

3.在这个部分添加红框的内容,UI显示的通配符。


期望实现的界面

屏幕切换效果

基本操作步骤

1.导入资源


2.TouchGFX designer实现界面

Screen0实现

                                   

设置与更新传感器值以及按键操作:

void Screen0View::update_sensor_value(ts_sensor_data *p_sensor_data)
{
    Unicode::snprintf(temperTextBuffer1, TEMPERTEXTBUFFER1_SIZE, "%d", p_sensor_data->temperature[1]);
    temperText.invalidate();
    Unicode::snprintf(temperTextBuffer2, TEMPERTEXTBUFFER1_SIZE, "%d", p_sensor_data->temperature[0]);
    temperText.invalidate();
    circleProgress1.setValue(p_sensor_data->temperature[1] * 10 + p_sensor_data->temperature[0]);
    circleProgress1.invalidate();
}
void Screen0View::set_sensor_value(ts_sensor_data *p_sensor_data)
{
    v_sensor_data.temperature[0] = p_sensor_data->temperature[0];
    v_sensor_data.temperature[1] = p_sensor_data->temperature[1];
    v_sensor_data.humidity = p_sensor_data->humidity;
}
void Screen0View::handleTickEvent()
{
    wait++;
    if (wait>500)
    {
        ///add test by andy.du 20190710
        application().gotoScreen4ScreenSlideTransitionSouth();
    }
}
void Screen0Presenter::key_event()
{
    view.handleKeyEvent(8);
}

void Screen0Presenter::update_sensor_event(ts_sensor_data *p_sensor_data)
{
    view.update_sensor_value(p_sensor_data);
}

Screen1实现

温度仪表盘显示以及按键操作主要代码:

void Screen1View::setupScreen()
{
    wait = 0;
    circleProgress2.setXY(79, 74-10);
    circleProgress2.setProgressIndicatorPosition(0, 0, 171, 130);
    circleProgress2.setRange(-134, 134);
    circleProgress2.setCenter(85, 85);
    circleProgress2.setRadius(85-98/2);
    circleProgress2.setLineWidth(98);
    circleProgress2.setStartEndAngle(-134, 134);
    circleProgress2.setCapPrecision(180);  
    circleProgress2Painter.setBitmap(Bitmap(BITMAP_A001_002_ID));
    circleProgress2.setPainter(circleProgress2Painter);
    circleProgress2.setValue(z);
    image2.setXY(86, 80-10);
    image2.setBitmap(Bitmap(BITMAP_A001_004_ID));
        
    textureMapperImage2D.setBitmap(Bitmap(BITMAP_A001_001_ID));
    textureMapperImage2D.setWidth(240);
    textureMapperImage2D.setHeight(240);
    textureMapperImage2D.setXY(0, 0);
    textureMapperImage2D.setBitmapPosition(165-3, 80-10);
    textureMapperImage2D.setCameraDistance(300.0f);
    textureMapperImage2D.setOrigo(165, 92+51+28-20, textureMapperImage2D.getCameraDistance());
    textureMapperImage2D.setCamera(textureMapperImage2D.getOrigoX(), textureMapperImage2D.getOrigoY());
    textureMapperImage2D.setRenderingAlgorithm(TextureMapper::NEAREST_NEIGHBOR);
    textureMapperImage2D.setVisible(true); 
        
    add(textureMapperImage2D);
    add(circleProgress2);
    add(image2);
    textureMapperImage2D.updateZAngle(PI *(-120) / 180.0f);
}
void Screen1View::handleTickEvent()
{
    tickCounter++;
        
    if (tickCounter > 100)
    {       
        tickCounter = 0;
        
        Unicode::snprintf(temperTextBuffer1, TEMPERTEXTBUFFER1_SIZE, "%d", From_Presenter_temperature);
        Unicode::snprintf(temperTextBuffer2, TEMPERTEXTBUFFER2_SIZE, "%d", From_Presenter_temperature_z);
        
        if(From_Presenter_temperature>=0&&From_Presenter_temperature<10)
        {
          From_Presenter_temperature=(From_Presenter_temperature-120)+((From_Presenter_temperature-0)*5);
        }
        else if(From_Presenter_temperature>=10&&From_Presenter_temperature<20)
        {
          From_Presenter_temperature=(From_Presenter_temperature-70)+((From_Presenter_temperature-10)*5);
        }
        else if(From_Presenter_temperature>=20&&From_Presenter_temperature<30)
        {
          From_Presenter_temperature=(From_Presenter_temperature-20)+(((From_Presenter_temperature-20)*5)-2);
        }
        else if(From_Presenter_temperature>=30&&From_Presenter_temperature<40)
        {
          From_Presenter_temperature=(From_Presenter_temperature+30)+(((From_Presenter_temperature-30)*5)-2);
        }
        
        circleProgress2.setValue(From_Presenter_temperature+From_Presenter_temperature_z-2);    
        textureMapperImage2D.setupAnimation(AnimationTextureMapper::Z_ROTATION,(PI *(From_Presenter_temperature+From_Presenter_temperature_z-2) / 180.0f),50,0,EasingEquations::expoEaseInOut);
        textureMapperImage2D.startAnimation();
        circleProgress2.invalidate();
        temperText.invalidate();
    }
}

Screen1View.hpp

void Screen1Presenter::key_event()
{
    view.handleKeyEvent(8);
}

void Screen1Presenter::update_sensor_event(ts_sensor_data *p_sensor_data)
{
    view.update_sensor_value(p_sensor_data);
}
#include "sensor.h"
#include <touchgfx/widgets/Image.hpp>
#include <touchgfx/widgets/TextureMapper.hpp>
#include <touchgfx/widgets/AnimationTextureMapper.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/Image.hpp>
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
#include <touchgfx/widgets/TextArea.hpp>
#include <touchgfx/containers/progress_indicators/CircleProgress.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565Bitmap.hpp>
#include <touchgfx/widgets/AnimatedImage.hpp>

public:
virtual void update_sensor_value(ts_sensor_data *p_sensor_data);
virtual void handleTickEvent();

protected:
               const float PI = 3.1415926f;
               int tickCounter;
               float z;
               uint16_t wait;
               int From_Presenter_temperature;
                uint16_t From_Presenter_temperature_z;
                touchgfx::Image image2;
                touchgfx::CircleProgress circleProgress2;
                touchgfx::AnimationTextureMapper textureMapperImage2D;
           // touchgfx::TextureMapper textureMapperImage2D;
               touchgfx::PainterRGB565Bitmap circleProgress2Painter;   
  
              private:  
             static const uint16_t CANVAS_BUFFER_SIZE = 4800;
             uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];
             ts_sensor_data v_sensor_data;

Screen2实现

温度记录显示以及按键操作主要代码:

void Screen2View::setupScreen()
{
    wait = 0;
    Screen2ViewBase::setupScreen();
    
    CanvasWidgetRenderer::setupBuffer(canvasBuffer, CANVAS_BUFFER_SIZE);
    graphT.setXY(40, 0);
    graphT.setup(240,200,Color::getColorFrom24BitRGB(255,0,0),Color::getColorFrom24BitRGB(0,0,0));
    graphT.set_Draw_Range(0, 240, 200, 0);
    graphT.setLineWidth(2);
    graphT.setLineVisible(true);
    graphT.setAreaVisible(true);
    graphT.setDotsVisible(false);
    graphT.setDotsBackgroundVisible(false);
    
    graph_Base.setXY(0, 0);
    graph_Base.setup(320,240,Color::getColorFrom24BitRGB(176,196,222),Color::getColorFrom24BitRGB(0,0,0));
    graph_Base.set_Draw_Range(0, 320, 240, 0);
    graph_Base.setLineWidth(1);
    graph_Base.setLineVisible(true);
    graph_Base.setAreaVisible(false);
    graph_Base.setDotsVisible(false);
    graph_Base.setDotsBackgroundVisible(false);
    
    
    
    graph_avg.setXY(40, 0);
    graph_avg.setup(240,200,Color::getColorFrom24BitRGB(176,196,222),Color::getColorFrom24BitRGB(0,0,0));
    graph_avg.set_Draw_Range(0, 240, 200, 0);
    graph_avg.setLineWidth(1);
    graph_avg.setLineVisible(true);
    graph_avg.setAreaVisible(false);
    graph_avg.setDotsVisible(false);
    graph_avg.setDotsBackgroundVisible(false);
    
    
    add(graphT);
    add(graph_Base);
    add(graph_avg);
    
    graph_Base.addValue(20,40);
    graph_Base.addValue(300,40);
    
    graphT.invalidate();
    graph_Base.invalidate();
}
void Screen2View::handleTickEvent()
{
    g_tick++;
    if(g_tick==30)
    {
      g_tick=0;
      From_Presenter_temperature= v_sensor_data.temperature[1];
      From_Presenter_temperature_z=v_sensor_data.temperature[0];
      g_y++; 
      
      real_temperature=((From_Presenter_temperature+((float)From_Presenter_temperature_z/10))*10)/10;
      
      avg_all=real_temperature;
      if (real_temperature >= max_sim)
      {
          max_sim = real_temperature;
          max_w=From_Presenter_temperature; 
          max_z=From_Presenter_temperature_z; 
      } 
      
      Unicode::snprintf(textArea3Buffer1, 10, "%d", max_w); 
      Unicode::snprintf(textArea3Buffer2, 10, "%d", max_z); 
      Unicode::snprintf(textArea3_2Buffer1, 10, "%d", From_Presenter_temperature); 
      Unicode::snprintf(textArea3_2Buffer2, 10, "%d", From_Presenter_temperature_z); 
      graphT.addValue(g_y,(From_Presenter_temperature*3));

      if(avg_flag>=1)
      {
         avg=avg_all+avg;
         avg_r=avg/avg_flag; 
         avg_r_w=(uint8_t)avg_r;
         avg_r_z=(uint16_t)(avg_r*10)0;
           
         Unicode::snprintf(textArea3_1Buffer1, 10, "%d", avg_r_w);        
         Unicode::snprintf(textArea3_1Buffer2, 10, "%d", avg_r_z);   
         
         graph_avg.clear();
         graph_avg.addValue(0,(avg_r_w*3));
         graph_avg.addValue(240,(avg_r_w*3));
         textArea3_1.invalidate(); 
         graph_avg.invalidate();
      }
      avg_flag++;  
      if(avg_flag==240)
      {
        avg_flag=0;
        avg=0;
      }
      textArea3.invalidate(); 
      textArea3_2.invalidate(); 
      graphT.invalidate();
     }
    if(g_y==240)
    {
      g_y=0;
      graphT.clear();
      time_base_add();
    }
}
void Screen2Presenter::key_event()
{
    view.handleKeyEvent(8);
}

void Screen2Presenter::update_sensor_event(ts_sensor_data *p_sensor_data)
{
    //view.update_sensor_value(p_sensor_data);
    view.set_sensor_value(p_sensor_data);    
}

Screen2View.hpp

#include "Graph.hpp"
    virtual void update_sensor_value(ts_sensor_data *p_sensor_data);
    virtual void set_sensor_value(ts_sensor_data *p_sensor_data);    
    virtual void handleTickEvent();
    
void time_base_add();

private:
       uint16_t wait;
       uint16_t g_tick;
       float max_sim;
       uint8_t max_z;
       uint8_t max_w;
       uint16_t From_Presenter_temperature;
       uint16_t From_Presenter_temperature_z;
       float real_temperature;
       
       Graph graphT;
       Graph graph_Base;
       Graph graph_avg;
       
       uint8_t Time_base;
       uint8_t Time_baseg;
       uint8_t Time_baseS;
       float avg;
       uint16_t avg_flag;
       float avg_all;
       float avg_r;
       uint8_t avg_r_w;
       uint8_t avg_r_z;


protected:
      static const uint16_t CANVAS_BUFFER_SIZE = 4800;
      uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];
      uint16_t g_y;
      ts_sensor_data v_sensor_data;


Screen3实现

湿度记录显示以及按键操作主要代码:

void Screen3View::setupScreen()
{
    wait = 0;
    Screen3ViewBase::setupScreen();
    
    CanvasWidgetRenderer::setupBuffer(canvasBuffer, CANVAS_BUFFER_SIZE);
    graphT.setXY(40, 0);
    graphT.setup(240,200,Color::getColorFrom24BitRGB(255,0,0),Color::getColorFrom24BitRGB(0,0,0));
    graphT.set_Draw_Range(0, 240, 200, 0);
    graphT.setLineWidth(2);
    graphT.setLineVisible(true);
    graphT.setAreaVisible(true);
    graphT.setDotsVisible(false);
    graphT.setDotsBackgroundVisible(false);
    
    graph_Base.setXY(0, 0);
    graph_Base.setup(320,240,Color::getColorFrom24BitRGB(176,196,222),Color::getColorFrom24BitRGB(0,0,0));
    graph_Base.set_Draw_Range(0, 320, 240, 0);
    graph_Base.setLineWidth(1);
    graph_Base.setLineVisible(true);
    graph_Base.setAreaVisible(false);
    graph_Base.setDotsVisible(false);
    graph_Base.setDotsBackgroundVisible(false);

    graph_avg.setXY(40, 0);
    graph_avg.setup(240,200,Color::getColorFrom24BitRGB(176,196,222),Color::getColorFrom24BitRGB(0,0,0));
    graph_avg.set_Draw_Range(0, 240, 200, 0);
    graph_avg.setLineWidth(1);
    graph_avg.setLineVisible(true);
    graph_avg.setAreaVisible(false);
    graph_avg.setDotsVisible(false);
    graph_avg.setDotsBackgroundVisible(false);
    
    
    add(graphT);
    add(graph_Base);
    add(graph_avg);
    graph_Base.addValue(20,40);
    graph_Base.addValue(300,40);      
    graphT.invalidate();
    graph_Base.invalidate();
}
void Screen3View::handleTickEvent()
{
    g_tick++;
    if(g_tick==30)
    {
      g_tick=0;
      From_Presenter_humidity= v_sensor_data.humidity;
      g_y++; 
      
      real_humidity=10000*(From_Presenter_humidity/exp2_16);
      
      avg_all=real_humidity;
      if (real_humidity >= max_sim)
          max_sim = real_humidity;
          
      Unicode::snprintf(textArea3Buffer, 10, "%d", max_sim);
      Unicode::snprintf(textArea3_2Buffer, 10, "%d", real_humidity); 
      
      graphT.addValue(g_y,real_humidity);
      
     
      if(avg_flag>=1)
      {
         avg=avg_all+avg;
         avg_r=avg/avg_flag; 
         Unicode::snprintf(textArea3_1Buffer, 10, "%d", avg_r);        
       
         graph_avg.clear();
        
         graph_avg.addValue(0,avg_r);
         graph_avg.addValue(240,avg_r);
     
         textArea3_1.invalidate(); 
         graph_avg.invalidate();
      }
     
      avg_flag++;  
      if(avg_flag==240)
      {
        avg_flag=0;
        avg=0;
      }
      
      textArea3.invalidate(); 
      textArea3_2.invalidate(); 
      graphT.invalidate();
     }
    if(g_y==240)
    {
      g_y=0;
      graphT.clear();
      time_base_add();
    }

}
void Screen3Presenter::key_event()
{
    view.handleKeyEvent(8);
}

void Screen3Presenter::update_sensor_event(ts_sensor_data *p_sensor_data)
{
    //view.update_sensor_value(p_sensor_data);
    view.set_sensor_value(p_sensor_data);    
}

Screen3View.hpp

#include "Graph.hpp"

    virtual void update_sensor_value(ts_sensor_data *p_sensor_data);  
    virtual void set_sensor_value(ts_sensor_data *p_sensor_data);     
    virtual void handleTickEvent();
    
void time_base_add();

private:
       uint16_t wait;
       uint16_t g_tick;
       uint8_t max_sim;
       float From_Presenter_humidity;
       Graph graphT;
       Graph graph_Base;
       Graph graph_avg;
       
       uint8_t Time_base;
       uint8_t Time_baseg;
       uint8_t Time_baseS;
       uint16_t avg;
       uint16_t avg_flag;
       uint16_t avg_all;
       uint16_t avg_r;
       uint16_t dis_graph_humidity;
       uint16_t dis_graph_humidity_av;
       uint16_t real_humidity;
       uint16_t exp2_16;

protected:
                        static const uint16_t CANVAS_BUFFER_SIZE = 4800;
      uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];
      uint16_t g_y;
      ts_sensor_data v_sensor_data;

Screen4实现

保护界面显示以及按键操作主要代码:

void Screen4View::setupScreen()
{
    Screen4ViewBase::setupScreen();

    CanvasWidgetRenderer::setupBuffer(canvasBuffer, CANVAS_BUFFER_SIZE);

    circle1.setPosition(257, 177, 80, 80);
    circle1.setCenter(40, 40);
    circle1.setRadius(17);
    circle1.setLineWidth(2);
    circle1.setArc(0, 0);
    circle1.setCapPrecision(10);
    circle1Painter.setColor(touchgfx::Color::getColorFrom24BitRGB(8, 129, 255));
    circle1.setPainter(circle1Painter);

    add(circle1);
    
    particleEffect.setPosition(0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT);
    particleEffect.setSnapToOrigin(true);
    particleEffect.setNumberOfParticles(180);
    particleEffect.setOrigin(particleEffect.getWidth() / 2, particleEffect.getHeight() / 2);
    particleEffect.setCenter(particleEffect.getWidth() / 2, particleEffect.getHeight() / 2);

    // Insert particleEffect jut on top of the background (z-order)
    container.insert(&bg_pcb5, particleEffect);

    particleEffect.setNumberOfParticles(150);

}
void Screen4View::handleTickEvent()
{
    tick++;
    itick++;
    if(tick==1)
    {
      tick=0;
      if(c_value==360)
      {
         c_value=0;
      }
      c_value++;
      o_x = rand() % 200 + 20;
      o_y=  rand() % 200 + 20;
     circle1.setArc(c_value, (c_value+100));
     if (itick == 20)
     {
         itick = 0;
         particleEffect.setCenter(o_x, o_y);
         particleEffect.invalidate();
     }
     circle1.invalidate();
    }
}
void Screen4Presenter::key_event()
{
    view.handleKeyEvent(8);
}

Screen4View.hpp

#include <BitmapDatabase.hpp>
#include <touchgfx/widgets/AnimationTextureMapper.hpp>
#include <touchgfx/widgets/canvas/Circle.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>

#include <stdlib.h>
#include <gui/common/ParticleEffect.hpp>
               virtual void handleTickEvent();

protected:
      touchgfx::Circle circle1;
      touchgfx::PainterRGB565 circle1Painter;
      ParticleEffect particleEffect;
      int o_x;
      int o_y;
      int itick;
private:
    uint16_t c_value;
    uint8_t tick;
    AnimationTextureMapper textureMapperImage;

 Callback<Screen4View, const AnimationTextureMapper&> animationEndedCallback;      
 void animationEndedHandler(const AnimationTextureMapper& src);

 void setupAndStartAnimation();
    
 static const uint16_t CANVAS_BUFFER_SIZE = 4800;
 uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];


Screen5实现

配网界面显示以及操作的主要代码:

Screen5ViewBase.cpp

/*********************************************************************************/
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/*********************************************************************************/
#include <gui_generated/screen5_screen/Screen5ViewBase.hpp>
#include "BitmapDatabase.hpp"
#include <texts/TextKeysAndLanguages.hpp>
#include <touchgfx/Color.hpp>

Screen5ViewBase::Screen5ViewBase() :
    buttonCallback(this, &Screen5ViewBase::buttonCallbackHandler)
{
    bg_320x2401.setXY(0, 0);
    bg_320x2401.setBitmap(Bitmap(BITMAP_BG_320X240_ID));

    textArea2_1_1.setXY(98, 0);
    textArea2_1_1.setColor(touchgfx::Color::getColorFrom24BitRGB(253, 252, 252));
    textArea2_1_1.setLinespacing(0);
    textArea2_1_1.setTypedText(TypedText(T_SINGLEUSEID123));

    wifi_on_off.setXY(98, 56);
    wifi_on_off.setBitmap(Bitmap(BITMAP_WIFI_OFF_128_ID));

    textArea2.setPosition(0, 215, 320, 25);
    textArea2.setColor(touchgfx::Color::getColorFrom24BitRGB(208, 197, 197));
    textArea2.setLinespacing(0);
    textArea2.setTypedText(TypedText(T_RESOURCEID4));

    button1.setXY(278, 92);
    button1.setBitmaps(Bitmap(BITMAP_NEXT_BUTTON_ID), Bitmap(BITMAP_NEXT_BUTTON_PRESSED_ID));
    button1.setAction(buttonCallback);

    add(bg_320x2401);
    add(textArea2_1_1);
    add(wifi_on_off);
    add(textArea2);
    add(button1);
}

void Screen5ViewBase::setupScreen()
{

}

void Screen5ViewBase::buttonCallbackHandler(const touchgfx::AbstractButton& src)
{
    if (&src == &button1)
    {
        //Interaction1
        //When button1 clicked change screen to Screen0
        //Go to Screen0 with screen transition towards East
        application().gotoScreen0ScreenSlideTransitionEast();
    }
}

Screen5View.cpp

#include <gui/screen5_screen/Screen5View.hpp>
#include "BitmapDatabase.hpp"
#include <texts/TextKeysAndLanguages.hpp>

Screen5View::Screen5View()
{

}

void Screen5View::setupScreen()
{
    Screen5ViewBase::setupScreen();
}

void Screen5View::tearDownScreen()
{
    Screen5ViewBase::tearDownScreen();
}

void Screen5View::update_sensor_value(ts_sensor_data *p_sensor_data)
{
    if(p_sensor_data->wifi_status==FRM_CMD_UPD_RESTWIFI)
    {
        textArea2.setTypedText(TypedText(T_RESOURCEID1));
        textArea2.invalidate();
    }else if(p_sensor_data->wifi_status==FRM_CMD_UPD_AIRLINK)
    {
        textArea2.setTypedText(TypedText(T_RESOURCEID2));
        textArea2.invalidate();
    }else if(p_sensor_data->wifi_status==FRM_CMD_UPD_CONFIGEND)
    {
        textArea2.setTypedText(TypedText(T_RESOURCEID3));
        textArea2.invalidate();
    }
    else if(p_sensor_data->wifi_status==FRM_CMD_UPD_INITSTAT)
    {
        textArea2.setTypedText(TypedText(T_RESOURCEID4));
        textArea2.invalidate();
    }

    if(p_sensor_data->wifi_status==FRM_CMD_UPD_CONFIGEND)
    {
        wifi_on_off.setBitmap(Bitmap(BITMAP_WIFI_ON_128_ID));
        wifi_on_off.invalidate();
    }else{
        wifi_on_off.setBitmap(Bitmap(BITMAP_WIFI_OFF_128_ID));
        wifi_on_off.invalidate();
    }
}