Message |
|
Ok, got it working!
Check here for a short video that might clarify why I'm trying to do this: https://www.youtube.com/watch?v=BPyFJuu6M0I
I'm using tcMenu to "patch" or "route" guitar effects, see the "built using tcMenu" subforum for some more movies where I'm doing comparable stuff.
Anyway, going through the patchcables and connecting a setup takes quite a few clicks. The second encoder saves me a lot of clicks: instead of activating a menuItem in order to change it, I can change it with the second encoder without activating. The callback figures out if the highlighted menuItem is changeable and then changes according to the value of the second encoder. At the end of the callback I'm setting the encoder to the halfway value so I have the same starting point. Clunky but it works :
setupMenu();
// code voor de 2e encoder
secondEncoder = new HardwareRotaryEncoder(PB8, PB9, [](int encoderValue) {
// do the action on the switch press
Serial.print("2nd encoder value change: ");
Serial.println(encoderValue);
// uitzoeken welk menupunt actief is
MenuItem* activeItem = menuMgr.findCurrentActive();
switch(activeItem->getId()) {
case 4: // menuCable, see STM32F401_eSPI_menu.cpp
if(encoderValue > 5) {
menuCable.setCurrentValue(menuCable.getCurrentValue() + 1);
} else {
menuCable.setCurrentValue(menuCable.getCurrentValue() - 1);
}
break;
case 5: // menuFrom
if(encoderValue > 5) {
menuFrom.setCurrentValue(menuFrom.getCurrentValue() + 1);
} else {
menuFrom.setCurrentValue(menuFrom.getCurrentValue() - 1);
}
break;
case 6: // menuTo
if(encoderValue > 5) {
menuTo.setCurrentValue(menuTo.getCurrentValue() + 1);
} else {
menuTo.setCurrentValue(menuTo.getCurrentValue() - 1);
}
break;
default: // niets gedefinieerd, doe niets.
break;
}
// value van encoder 2 weer terugzetten naar midden value
secondEncoder->setCurrentReading(5);
});
secondEncoder->changePrecision(10, 5); // max value, current value
switches.setEncoder(1, secondEncoder);
|
|
|
Ok, clear, thanks for the pointers.
I'll see where I end up and report back!
Iwan
|
|
|
Hi Dave,
On the description page of the encoders/switches plugin there's a code snippet that shows how to use a second encoder to change a certain menu item directly.
I'm wondering if it's easily doable to make it so that the 2nd encoder changes the value of the item "under the cursor", without activating (clicking) that item under the cursor? I'm working on a project where there's a lot of configuring going on, with dynamically changing enums etc. Using two encoders would speed up the use of the menu tremendously, since the user wouldn't have to click the menu, edit value, click to accept, go down, click enum, modify enum, click to accept, go up again to go to the value, etc. (I'll can a video of this process if you want).
I think the code for this would become something like: (pseudo-ish code)
// somewhere globally, define the variable
HardwareRotaryEncoder* secondEncoder;
void setuo() {
// other stuff...
setupMenu(); // Important! This must be before any usage of switches
// here we assume that menuVolume was defined in your menu project as an analog item
secondEncoder = new HardwareRotaryEncoder(pinA, pinB, [](int encoderValue) {
activeMenuItem = ... ???
switch(activeMenuItem) {
"menuvolume" : increase_or_decrease_volume(); // ???
break;
"menuchannel" : increase_or_decrease_channel();
break;
etc....
});
secondEncoder->changePrecision(menuVolume.getMaximumValue(), menuVolume.getCurrentValue());
switches.setEncoder(1, secondEncoder);
}
Would this be the way to go? If so, how do I find out the activeMenuItem, and where would I put the changePrecision() call? This last one should probably change whenever one turns the primary encoder, right?
Also, is there a way to get the highlighter menuitem in the middle of the (TFTeSPI) screen? I'd like to see at least two lines of menu *below* the current highlighted item, but when scrolling up the bottom one disappears off-screen.
|
|
|
Ok, thanks for the hints. Will report back when I have something working.
|
|
|
Hi Dave,
Subject says all: is it possible to create a ListRuntimeMenuItem, where all the rows are a ScrollChoiceMenuItem? I know that the rows are clickable so they can trigger an action, but I would like to have each row select an item from a ScrollChoice.
Iwan
|
|
|
How does this work from a users' perspective? How do 'clicks' and 'scrolls' work? I'm working on a new project and I haven't decided what input to use: encoder, joystick or touch. Until now I've used only encoders and while that works absolutely fine, I'm wondering if joystick or touch would give a better experience.
|
|
|
|
|
|
Hi Dave,
Is it possible to prevent the menu from scrolling up to the Title, which does nothing? Using version 2.2 I can scroll onto the title, but I would like the cursor to stay on the topmost item. Is this possible?
|
|
|
No worries! I'm pretty new to TFT_eSPI as well, but I found the following: in order to differentiate, it is checking for the defines, see line #4750 of https://github.com/Bodmer/TFT_eSPI/blob/master/TFT_eSPI.cpp
I was able to get it working using either numbered fonts or freefonts, but I don't think you can combine them in one project. Also, when using a freefont the magnification cannot be set.
I had to change tcMenuTfteSpi.cpp as follows, in the same vein as TFT_eSPI.cpp:
void TfteSpiDrawable::fontPtrToNum(const void* font, int mag) {
#ifdef LOAD_GFXFF
if(font == nullptr) {
tft->setTextFont((uint8_t) mag); // <= does not work, for some reason GLCD data structure is not found
}
else {
tft->setFreeFont(static_cast<const GFXfont *>(font));
}
#else
tft->setTextFont((uint8_t) mag); // numbered font does not take font data, just a number
#endif
}
Then you have to either, using numbered fonts:
User_Setup.h
#define LOAD_FONT4
Arduino_menu.cpp
installCoolBlueTraditionalTheme(renderer, MenuFontDef(&FreeMono12pt7b, 1), MenuFontDef(&FreeMono12pt7b, 1), true);
or, using freefonts:
User_Setup.h
#define GFXFF
Arduino_menu.cpp
installCoolBlueTraditionalTheme(renderer, MenuFontDef(nullptr, 4), MenuFontDef(nullptr, 4), true);
I didn't get setTextFont(int) to work in the case of freefonts, this should default to glcd font.
I'm not sure this is the correct way to do it, review by someone more knowledgeable is advised
|
|
|
I'm struggling with understanding the font handling when using the TFT_eSPI driver. I found this so far:
* The generator lets you set numbered fonts for title and items when using the TFT_eSPI driver. I chose '4' which is a nice size, sharp and proportional.
* These numbers are passed like so: installCoolBlueTraditionalTheme(renderer, MenuFontDef(nullptr, 4), MenuFontDef(nullptr, 4), true);
This stores the font-data (nullptr) and the font-magnification (4) in the renderer.
* From here on, drawText() calls fontPtrToNum(font, mag); [in tcMenuTfteSpi.cpp]
* fontPtrToNum() is defined in tcMenuTfteSpi.cpp as:
void TfteSpiDrawable::fontPtrToNum(const void* font, int mag) {
if(font == nullptr) {
tft->setTextFont((uint8_t) mag);
}
else {
tft->setFreeFont(static_cast<const GFXfont *>(font));
}
}
... so I assumed there's only a tft->setTextFont(mag); involved, no FreeFont.
However, when I comment out either
#define LOAD_FONT4
or
#define LOAD_GFXFF
in the User_Setup.h from TFT_eSPI, it either shows no letters on the display (first #define) or it won't compile (second #define, compilation error at the <cntst GFXfont*> in fontPtrToNum ).
What is going on here? Is it using the FreeFont, the TFT_eSPI numbered font, or a scaled font?
|
|
|
In the meantime I have a basic menu running on the STM32F103 + ST7789 (240x240), using tcMenuLib 2.1.3. (Using TFT_eSPI, of course). The menu runs MUCH smoother than the 1.7 + Adafruit_GFX!
Trying to figure out some things with the fonts, will keep you posted.
|
|
|
By the way, there's a typo in
tcMenu/xmlPlugins/core-display/tfteSpi/tcMenuTfteSpi.cpp : it includes #include <TfT_eSPI.h> in line 17; the f should be uppercase.
I found out since the generator generated this file including the typo, it's in resources/packaged plugins/initialPlugins.zip
|
|
|
Ok, thanks for your quick response!
|
|
|
Hi Dave,
Was browsing the MenuLib gihub the other day. I saw that a number of commits have been tagged 2.2. Also, in the Releases page there's a full 2.0 release, and an RC for the 2.1 release. However, on the tcMenu page I cannot find any info on 2.0+ [edit] I mean anything directly about Lib 2.0+, there's info about the designer being default 2.0+ [/edit]
So what's the actual status of the menu Lib?
I saw that TFT_eSPI support is going to be in 2.0+, I'm especially interested in that since in my main project I'm on an STM32F401CC with an ST7789 display which is ridiculously slow with stock Adafruit_GFX...
[edit] I think I posted a bit to soon, after a bit more reading the tcMenu github (especially the releases page https://github.com/davetcc/tcMenu/releases ) it's a lot clearer now! Tinkering with the TFT_ePSI driver using 2.1.3 as we speak.
|
|
|
Cool. I'm happy as it is but it makes for a more logical UI if this works.
|
|
|
|
|