Register / Login  |  Desktop view  |  Jump to bottom of page

tcMenu Arduinio library » renderer.takeOverDisplay for push buttons not a rotary encoder?

Author: Mr.Robot
06/12/2021 19:37:41
Hi,

I am back with a new question. smilie

I am using the renderer.takeOverDisplay function to display my own screen which works great. According to the API, the method which is called by takeOverDisplay needs to have the following parameters:
unsigned int encoderValue, RenderPressMode clicked


My issue here is that I do not use a rotary encoder but a push button setup (up/down/left/right/a/b). In case I only need a single button press to return the control to tcMenu, this works. For one custom screen, however, I need the other buttons as well. Hence my question: Is there a way to read the other button states instead of the encoder value when the method is called? In case not, is there a solution/workaround which I am overseeing at the moment?

Author: davetcc
07/12/2021 00:10:20
There’s a couple of things you can do here.

First, you could implement the switch listeners yourself and pass them through to the menu when needed..

See https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menumanager-and-iteration/

Secondly, you can poll the switches object yourself using the following method during the rendering callback. Depending how much control you need this could be enough.

bool isSwitchPressed(pinid_t pin);

Author: Mr.Robot
07/12/2021 07:44:56
Thanks Dave!

Using isSwitchPressed works. I need it to flip through a couple of pages - for this use case the method is enough.

Downside: As expected, sometimes it misses a button press (for me roughly 1-2 presses out of 10). This happens whenever the button is pressed & released between the calls of the function referenced by takeOverDisplay. From a usability point of view, the user might think there is a hardware issue since the button press does not lead to any reaction and it needs to be pressed again.

Here is my code as reference for others looking for a similar functionality:


(Screen.h)
struct MyStruct {
    int screenCounter;
    int currentPage;
    int numOfPages;
};

class Screen {
   public:
      static void showCustomPages(unsigned int encoderValue, RenderPressMode clicked);
   private:
      static MyStruct myStruct;
};

(Screen.cpp)
#include "Screen.h"
#include "tcmenu_menu.h"  // or whatever your tcmenu header is called

MyStruct Screen::myStruct = {0,0,5};

void Screen::showCustomPages(unsigned int encoderValue, RenderPressMode clicked) {
  if (myStruct.screenCounter == 0) {

   // initial page of the custom screen.

    myStruct.infoScreenCounter++;
    myStruct.currentPage = 0;


      // this example draws a footer with page number on a 240x240 screen 
      gfx.fillRect(0, 215, 240, 25, 0x4A69);
      gfx.setTextColor(ST77XX_WHITE);
      gfx.setCursor(20,232);
      gfx.setFont(&FreeSans9pt7b);
      gfx.print("Page: ");
      gfx.print(myStruct.currentPage+1);        // count starts at 0, human readable value should start at 1
      gfx.print("/");
      gfx.print(myStruct.numOfPages);
      gfx.print("");
      gfx.setCursor(140,232);
      gfx.print("<A - Exit>");
  }
  
  if (switches.isSwitchPressed(RIGHT_BUTTON_GPIO) ) {
    if (myStruct.numOfPages > myStruct.currentPage) {
      myStruct.currentPage++;

      // draw next page
      // this example draws a footer with page number on a 240x240 screen 
      gfx.fillRect(0, 215, 240, 25, 0x4A69);
      gfx.setTextColor(ST77XX_WHITE);
      gfx.setCursor(20,232);
      gfx.setFont(&FreeSans9pt7b);
      gfx.print("Page: ");
      gfx.print(myStruct.currentPage+1);        // count starts at 0, human readable value should start at 1
      gfx.print("/");
      gfx.print(myStruct.numOfPages);
      gfx.print("");
      gfx.setCursor(140,232);
      gfx.print("<A - Exit>");
    }
  }

  if (switches.isSwitchPressed(LEFT_BUTTON_GPIO) ) {
    if (myStruct.currentPage > 0) {
      myStruct.currentPage--;

      gfx.fillRect(0, 215, 240, 25, 0x4A69);
      gfx.setTextColor(ST77XX_WHITE);
      gfx.setCursor(20,232);
      gfx.setFont(&FreeSans9pt7b);
      gfx.print("Page: ");
      gfx.print(myStruct.currentPage+1);        // count starts at 0, human readable value should start at 1
      gfx.print("/");
      gfx.print(myStruct.numOfPages);
      gfx.print("");
      gfx.setCursor(140,232);
      gfx.print("<A - Exit>");
    }
  }

  if (clicked) {
    myStruct.infoScreenCounter = 0;
    renderer.giveBackDisplay();
  }
}


Author: davetcc
08/12/2021 07:31:36
How to proceed really depends on how you are using the buttons in the other context.

If they are still being treated as up and down buttons (ie as an encoder) then you can just change the range of the encoder and use the integer value provided in your callback.

However, if the function of them is completely different then you could take a look at the UpDown encoder class that’s defined in IoAbstraction SwitchInput.h/.cpp and make your own version that allows you to take the buttons on demand. The updown encoder is very simple.

Author: davetcc
08/12/2021 07:34:42
For the later case:

https://www.thecoderscorner.com/ref-docs/ioabstraction/html/class_encoder_up_down_buttons.html




Register / Login  |  Desktop view  |  Jump to top of page