2024-07-30 08:36 AM
Hi,
I am writing here because I need a help.
I want to use flex button this way - when I hold pressed button then virtual function is executed, so when I release button then the virtual function stops.
I try for example .getPressed() in handleTickEvent, but it doesn't working. I try a sample with CustomButton from this forum but I can't use it enough.
Can somebody help me ?
I will be very grateful for help.
Best regards,
Kamil
2024-07-30 09:39 PM
Hello
Have you make sure your handleTickEvent is working and called every tick ?
If your button is located to customContainer, check this
Here is also example how to use getPressed in handleTick:
Hope these helps you. If not, maybe show us your code which is not working.
Br JTP
2024-07-30 11:29 PM
Make sure your virtual function is non-blocking. From your description it seems like you have a while-loop or similar checking for the release of the FlexButton. But TouchGFX will freeze when the called function is blocking.
2024-07-31 12:01 AM
I use handleTickEvent in MainView - not in ButtonContainer.
Here a code of my handleTickEvent in MainView:
void MainView::handleTickEvent()
{
if(zliczoneFlaga == 1)
{
dlugosc_materialu_View = dlugosc_ustawiona2;
}
Unicode::snprintfFloat(textArea_dlugosc_ustawionaBuffer, TEXTAREA_DLUGOSC_USTAWIONA_SIZE, "%0.1f", dlugosc_ustawiona2 );
textArea_dlugosc_ustawiona.invalidate();
WysylamBigosFloat(dlugosc_materialu_View);
boxProgress1.setValue(dlugosc_materialu_View);
boxProgress1.invalidate();
Unicode::snprintfFloat(textArea_dlugosc_materialuBuffer, TEXTAREA_DLUGOSC_MATERIALU_SIZE, "%0.1f", dlugosc_materialu_View );
textArea_dlugosc_materialu.invalidate();
boxProgress1.setRange(0, dlugosc_ustawiona2);
boxProgress1.invalidate();
if((dlugosc_ustawiona2 - dlugosc_materialu_View) <= 0.01)
{
scalableImage_start.setVisible (true);
scalableImage_start.invalidate();
scalableImage_start_1.setVisible (false);
scalableImage_start_1.invalidate();
}
if(flexButtonCofnij.getPressed() == 1)
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_RESET);
}
}
FlexButtonCofnij is use to control P2_Pin output.
In previous post I expressed myself incorrectly because when I hold a button then the P2_pin output change a state all time but I want to that when I hold button then P2_pin is SET, when I release then P2_pin is RESET.
Do you understand evrything?
Thanks for our help!
2024-07-31 04:31 AM
Hello @KDyrb.1 ,
Based on your last comment, if you want to set or reset a pin, you should handle that function inside Model.cpp to be able to access HAL_GPIO_WritePin() , and you don't want to set or reset the pin every frame.
Instead, follow the comment made by @JTP1 (especially, the second forum thread he mentioned), and call HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_SET) when the button is pressed and call reset when it is released.
Your code should look like below:
void Screen1View::flexButtonClickHandler(const touchgfx::BoxWithBorderButtonStyle< touchgfx::ClickButtonTrigger >& b, const ClickEvent& event)
{
if (&b == &flexButton1)
{
if (event.getType() == ClickEvent::PRESSED)
{
touchgfx_printf("Button is pressed..\n");
//presenter->setPin();
}
else if (event.getType() == ClickEvent::RELEASED)
{
touchgfx_printf("Button is released..\n");
//presenter->resetPin();
}
}
}
Please refer to Backend Communication to read more about how to call hardware related functions.
I hope this helps you, don't hesitate to ask more questions!
2024-07-31 08:34 AM
@Mohammad MORADI ESFAHANIASL
Thank you for your reply!
I know that I should control hardware in Model.cpp, but I was desperate and I tried evrything - a lot of *** idea.
I checked a way which was suggested by @JTP1 in the morning and i have a problem - I can't add a callback to the constructor:
Do you have a idea where is a problem?
I will be very grateful!
Best regards.
2024-07-31 09:52 AM
// Try like this:
MainView::MainView():
flexButtonClickedCallback(this,&MainView::flexButtonClickHandler)
{
keyboard.setPosition (0,0, 379, 320);
add(keyboard);
keyboard.setVisible (false);
keyboard.invalidate(); //gaugel.setValue(bigos),
}
If not work, can you show mainView.hpp and flexButtonClickHandler function from mainView.cpp
Br JTP
2024-07-31 10:05 AM
About the backend communication:, maybe example project 'MVP_toggleBtnExV1' in this thread helps you after you have read the documentation.
2024-07-31 12:17 PM
@JTP1 yours advice with callback is good and I can compile project.
Outputs are turn on/turn off but they are switched all the time when I hold the flexButton - the same effect I had at the beginings, when I wrote here.
Here a code od MainView.hpp:
#ifndef MAIN_VIEW_HPP
#define MAIN_VIEW_HPP
#include <gui_generated/main_screen/MainViewBase.hpp>
#include <gui/main_screen/MainPresenter.hpp>
#include <gui/common/CustomKeyboard.hpp>
#include <gui/common/customButtonContainer.hpp>
class MainView : public MainViewBase
{
public:
MainView();
~MainView() {};
virtual void setupScreen();
virtual void tearDownScreen();
virtual void exitClicked();
virtual void Dlugosc_ustawionaClicked();
void WysylamBigos(uint16_t value);
void WysylamBigosFloat(float value2);
void handleTickEvent();
virtual void startClicked();
virtual void stopClicked();
virtual void resetClicked();
void WyslijFlage();
virtual void enter_clicked();
virtual void cofnij_clicked();
void sendToScreen_zliczoneFlaga(int);
// Add this public function definition:
void flexButtonClickHandler(const touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::ClickButtonTrigger > > & ,const ClickEvent& e);
protected:
CustomKeyboard keyboard;
int namemod;
int agemod;
char dataBuf[20];
char agebuf[TEXTAREA_DLUGOSC_USTAWIONA_SIZE];
//int start_flag = 0;
touchgfx::CustomButtonContainer customButton;
Callback<MainView, const CustomButtonContainer&, bool&> buttonEventCallback;
void handleButtonEvent(const CustomButtonContainer& element, bool& buttonState);
// And add this protected function definition:
Callback<MainView, const touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::ClickButtonTrigger > > &,const ClickEvent&> flexButtonClickedCallback;
private:
};
#endif // MAIN_VIEW_HPP
Here a code od MainView.cpp:
#include <gui/main_screen/MainView.hpp>
#include "BitmapDatabase.hpp"
#ifndef SIMULATOR
#include "stdio.h"
#include "main.h"
#include <stdlib.h>
#endif
uint16_t bigos2;
float dlugosc_materialu_View;
float dlugosc_ustawiona_View;
int kurwa = 0;
extern "C"
{
extern __IO int start_flag;
extern __IO int nawijanieAktywne_flaga;
extern __IO int cofanieAktywne_flaga;
extern __IO int ok_flag = 0;
extern __IO float dlugosc_ustawiona2;
extern __IO int zliczoneFlaga;
}
MainView::MainView():
flexButtonClickedCallback(this,&MainView::flexButtonClickHandler)
{
keyboard.setPosition (0,0, 379, 320);
add(keyboard);
keyboard.setVisible (false);
keyboard.invalidate(); //gaugel.setValue(bigos),
}
void MainView::setupScreen()
{
MainViewBase::setupScreen();
//customButton.setAction(buttonEventCallback);
flexButtonCofnij.setClickAction(flexButtonClickedCallback);
}
void MainView::tearDownScreen()
{
MainViewBase::tearDownScreen();
}
void MainView::Dlugosc_ustawionaClicked()
{
keyboard.setVisible (true);
keyboard.invalidate();
//flexButtonOK.setVisible(true);
//flexButtonOK.invalidate();
//flexButtonEXIT.setVisible(true);
//flexButtonEXIT.invalidate();
//scalableImage_enter.setVisible(false);
//scalableImage_enter.invalidate();
//image_enter.setVisible(false);
//image_enter.invalidate();
//flexButton_ENTER.setVisible(false);
//flexButton_ENTER.invalidate();
//scalableImage_settings.setVisible(false);
//scalableImage_settings.invalidate();
//image_settings.setVisible(false);
//image_settings.invalidate();
flexButton_SETTINGS.setVisible(false);
flexButton_SETTINGS.invalidate();
//scalableImage_LOGO.setVisible(false);
//scalableImage_LOGO.invalidate();
//image_LOGO.setVisible(false);
//image_LOGO.invalidate();
flexButton_LOGO.setVisible(false);
flexButton_LOGO.invalidate();
agemod = 1;
ok_flag = 1;
boxProgress1.setVisible (false);// tutej chce zeby nie było widać progress bar kiedy jest klawiatura aktywna
boxProgress1.invalidate();
}
void MainView::enter_clicked()
{
keyboard.setVisible (false);
keyboard.invalidate();
//flexButtonEXIT.setVisible(false);
//flexButtonEXIT.invalidate();
if(ok_flag == 1)
{
Unicode::strncpy(textArea_dlugosc_ustawionaBuffer, keyboard.getBuffer(), TEXTAREA_DLUGOSC_USTAWIONA_SIZE);
textArea_dlugosc_ustawiona.invalidate();
ok_flag = 0;
}
keyboard.clearBuffer();
int i = 0;
do
{
agebuf[i] = (char) textArea_dlugosc_ustawionaBuffer[i];
i++;
}while(textArea_dlugosc_ustawionaBuffer[i] != 0);
sprintf(dataBuf, "%s", agebuf);
// DOałem to żęb w ustawionej wyświetlało to samo co w ługości materiału - czyli z kropką.
dlugosc_ustawiona_View = atof(agebuf);
Unicode::snprintfFloat(textArea_dlugosc_ustawionaBuffer, TEXTAREA_DLUGOSC_USTAWIONA_SIZE, "%0.1f", dlugosc_ustawiona2 ); // dla zmiennoprzecinkowych
textArea_dlugosc_ustawiona.invalidate();
presenter->sendData(dataBuf);
memset (agebuf, '\0', TEXTAREA_DLUGOSC_USTAWIONA_SIZE);
//scalableImage_settings.setVisible(true);
//scalableImage_settings.invalidate();
//image_settings.setVisible(true);
//image_settings.invalidate();
flexButton_SETTINGS.setVisible(true);
flexButton_SETTINGS.invalidate();
//scalableImage_LOGO.setVisible(true);
//scalableImage_LOGO.invalidate();
//image_LOGO.setVisible(true);
//image_LOGO.invalidate();
flexButton_LOGO.setVisible(true);
flexButton_LOGO.invalidate();
boxProgress1.setVisible (true);// tutej chce zeby nie było widać progress bar kiedy jest klawiatura aktywna
boxProgress1.invalidate();
}
void MainView::exitClicked()
{
keyboard.setVisible (true);
keyboard.invalidate();
//flexButtonEXIT.setVisible(true);
//flexButtonEXIT.invalidate();
agemod = 0;
}
void MainView::WysylamBigos(uint16_t value) //float value - dla zmiennoprzecinkowej wartosci
{
//gauge1.setValue(value);
//gauge1.invalidate();
//boxProgress1.setValue(value);
//boxProgress1.invalidate();
//Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", value );
//textArea1.invalidate();
bigos2 = value;
}
void MainView::WysylamBigosFloat(float value2) //float value - dla zmiennoprzecinkowej wartosci
{
//gauge1.setValue(value);
//gauge1.invalidate();
//boxProgress1.setValue(value);
//boxProgress1.invalidate();
//Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", value );
//textArea1.invalidate();
dlugosc_materialu_View = value2;
}
void MainView::handleTickEvent()
{
if(zliczoneFlaga == 1)
{
dlugosc_materialu_View = dlugosc_ustawiona2;
}
Unicode::snprintfFloat(textArea_dlugosc_ustawionaBuffer, TEXTAREA_DLUGOSC_USTAWIONA_SIZE, "%0.1f", dlugosc_ustawiona2 );
textArea_dlugosc_ustawiona.invalidate();
WysylamBigosFloat(dlugosc_materialu_View);
boxProgress1.setValue(dlugosc_materialu_View);
boxProgress1.invalidate();
Unicode::snprintfFloat(textArea_dlugosc_materialuBuffer, TEXTAREA_DLUGOSC_MATERIALU_SIZE, "%0.1f", dlugosc_materialu_View );
textArea_dlugosc_materialu.invalidate();
boxProgress1.setRange(0, dlugosc_ustawiona2);
boxProgress1.invalidate();
if((dlugosc_ustawiona2 - dlugosc_materialu_View) <= 0.01)
{
scalableImage_start.setVisible (true);
scalableImage_start.invalidate();
scalableImage_start_1.setVisible (false);
scalableImage_start_1.invalidate();
}
}
void MainView::startClicked()
{
presenter -> startClicked();
nawijanieAktywne_flaga = 1;
scalableImage_start.setVisible (false);
scalableImage_start.invalidate();
scalableImage_start_1.setVisible (true);
scalableImage_start_1.invalidate();
zliczoneFlaga = 0;
}
void MainView::stopClicked()
{
presenter-> stopClicked();
nawijanieAktywne_flaga = 0;
scalableImage_start.setVisible (true);
scalableImage_start.invalidate();
scalableImage_start_1.setVisible (false);
scalableImage_start_1.invalidate();
}
void MainView::resetClicked()
{
if(nawijanieAktywne_flaga == 0)
{
presenter -> resetClicked();
}
zliczoneFlaga = 0;
}
void MainView::WyslijFlage()
{
//start_flag;
//presenter -> WysljFlage();
}
void MainView::cofnij_clicked()
{
}
void MainView::sendToScreen_zliczoneFlaga(int zerFlag)
{
zliczoneFlaga = zerFlag;
}
/// Add this function
void MainView::flexButtonClickHandler(const touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::ClickButtonTrigger > > & b,const ClickEvent& e)
{
if(&b==&flexButtonCofnij) // button1 -> your button name
{
if (e.getType() == ClickEvent::PRESSED)
{
//touchgfx_printf("Button is pressed..\n");
presenter->setPin();
}
else if (e.getType() == ClickEvent::RELEASED)
{
//touchgfx_printf("Button is released..\n");
presenter->resetPin();
}
}
}
Here a code Model.cpp:
#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#ifndef SIMULATOR
#include "main.h"
#include "string.h"
#include "EEPROM.h"
#include <stdio.h>
#include <stdlib.h>
extern "C"
{
extern UART_HandleTypeDef huart2;
extern TIM_HandleTypeDef htim4;
extern __IO uint16_t dlugosc_materialu;
extern __IO uint8_t dlugosc_ustawiona;
extern __IO float dlugosc_materialu2;
extern __IO float dlugosc_ustawiona2;
extern float Pobierz_dlugosc(void);
extern __IO uint8_t autoStartFlagaModel;
extern __IO uint8_t zapisMierzonejFlagaModel;
//extern __IO uint8_t zapisUstawionejFlagaModel;
extern __IO float mnoznik_dlugosci;
extern __IO float cofanie_wartosc;
extern __IO int nawijanieAktywne_flaga;
extern __IO int cofanieAktywne_flaga;
extern __IO float dlugosc_ustawiona2_z_pamieci;
extern __IO int zliczoneFlaga;
}
#endif
Model::Model() : modelListener(0)
{
}
void Model::tick()
{
modelListener->WysylamBigos(dlugosc_materialu);
modelListener->WysylamBigosFloat(dlugosc_materialu2);// - dla zmiennoprzecinkowej wartosci
modelListener->autoStartFlagGet(autoStartFlagaModel);
modelListener->zapis_mierzonej_get(zapisMierzonejFlagaModel);
modelListener->sendToScreen_Skala(mnoznik_dlugosci);
modelListener->sendToScreen_cofanieWartosc(cofanie_wartosc);
modelListener->sendToScreen_Dlugosc_ustawiona(dlugosc_ustawiona2_z_pamieci);
modelListener->sendToScreen_zliczoneFlaga(zliczoneFlaga);
}
void Model::sendData(char *data)
{
//uint8_t * dlugosc;
//dlugosc = (uint8_t *)&data;
dlugosc_ustawiona = (uint8_t)atoi(data);
//dlugosc_ustawiona2 = atof(data);
dlugosc_ustawiona2 = atof(data);
//Pobierz_dlugosc();
//dlugosc_ustawiona2 = (uint8_t)atoi(data);
//static uint16_t cnt = 0; // Licznik wyslanych wiadomosci
uint8_t dane[50]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size = 0; // Rozmiar wysylanej wiadomosci
//++cnt; // Zwiekszenie licznika wyslanych wiadomosci.
size = sprintf(data, "Liczba wyslanych wiadomosci:"); // Stworzenie wiadomosci do wyslania oraz przypisanie ilosci wysylanych znakow do zmiennej size.
HAL_UART_Transmit_IT(&huart2, dane, size);
//dlugosc_ustawiona = 23;
//Pobierz_dlugosc(dlugosc_ustawiona);
}
void Model::startClicked()
{
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //docelowo w tym miejscu zamiast wlaczenie TIMERA będziemy wysterowywali przekaźnik żeby wlaczyc silnik
HAL_GPIO_WritePin(GPIOB, P1_Pin, GPIO_PIN_SET);
//HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET); //Zapalamy LED jako wysterowanie prezkaźnika - do sygnalizacji w testach
}
void Model::stopClicked()
{
//HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_1); // do testow - symulacja silnika
HAL_GPIO_WritePin(GPIOB, P1_Pin, GPIO_PIN_RESET); //docelowo w tym miejscu zamiast wylaczenia TIMERA będziemy wysterowywali przekaźnik żeby wlaczyc silnik
//HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
}
void Model::resetClicked()
{
dlugosc_materialu = 0;
dlugosc_materialu2 = 0;
if(autoStartFlagaModel == 1)
{
//nawijanieAktywne_flaga = 1;
HAL_GPIO_WritePin(GPIOB, P1_Pin, GPIO_PIN_SET);
startClicked();
}
}
void Model::WyslijFlage()
{
//start_flag;
nawijanieAktywne_flaga;
//presenter -> WysljFlage();
}
void Model::auto_start_set(uint8_t autoStartFlaga)
{
autoStartFlagaModel = autoStartFlaga;
EEPROM_Write_NUM(5, 0, autoStartFlagaModel);
}
void Model::zapis_mierzonej_set(uint8_t zapisMierzonejFlaga)
{
zapisMierzonejFlagaModel = zapisMierzonejFlaga;
EEPROM_Write_NUM(6, 0, zapisMierzonejFlagaModel);
}
/*void Model::zapis_ustawionej_set(uint8_t zapisUstawionejFlaga)
{
zapisUstawionejFlagaModel = zapisUstawionejFlaga;
EEPROM_Write_NUM(7, 0, zapisUstawionejFlagaModel);
}*/
void Model::sendToMain_Skala(char *data)
{
mnoznik_dlugosci = atof(data);
EEPROM_Write_NUM(8, 0, mnoznik_dlugosci);
}
void Model::sendToMain_cofanie_wartosc(char *data)
{
cofanie_wartosc = atof(data);
EEPROM_Write_NUM(9, 0, cofanie_wartosc);
}
void Model::cofnij_clicked()
{
//HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //docelowo w tym miejscu zamiast wlaczenie TIMERA będziemy wysterowywali przekaźnik żeby wlaczyc silnik
//if(cofanieAktywne_flaga == 1)
//{
// HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_SET);
//}
//HAL_Delay(1000);
//cofanieAktywne_flaga;
//cofanieAktywne_flaga = 1;
}
void Model::sendToMain_Dlugosc_ustawiona(char *data)
{
dlugosc_ustawiona2 = atof(data);
EEPROM_Write_NUM(4, 0, dlugosc_ustawiona2);
}
void Model::sendToMain_cofnij(int cofnijf)
{
/*if(cofnijf == 1)
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_RESET);
}*/
}
void Model::setPin()
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_SET);
}
void Model::resetPin()
{
HAL_GPIO_WritePin(GPIOB, P2_Pin, GPIO_PIN_RESET);
}
Can you help me to find a faulty in my code?
2024-07-31 12:28 PM
Hello. In this case i would check the touch panel handling/reading, is the sampleTouch-function getting steady and consistant coordinates every time it is called.
Br JTP