Message |
|
The issue is: Using the Encoder to operate the menu does not work: The display shows no move of the cursor to submenus or similar, a test using the Encoder Button for a callback also failed.
Ah, I think I see how you're using it now. I assume you've told the designer UI not to automatically create any rotary encoder or input device on your behalf, and instead you've created them manually yourself in the main setup method.
edit - If this is the case just make sure that you have "no input" selected in the designer.
If that is the case, you just need to ensure that when the rotary encoder changes that you tell menuMgr about it, by calling the following from your encoder change callback when the menu is active:
void onEncoderChange(int newValue)
{
menuMgr.valueChanged(newValue); // as you are managing things manually, you need to let menu manager know when this changes, unless you've taken over display
}
I see you're also managing the button yourself too, same applies here. When the menu is active and the button is released, call:
void onReleased(uint8_t pin, bool held) override {
Serial.println("Released ");
menuMgr.onMenuSelect(wasHeld); // as you are managing things manually, you need to let menu manager know when this changes, unless you've taken over display
}
This will allow you to keep control of the rotary encoder and select button, but at the same time allow the menu manager to handle the events when it's active.
|
|
|
Also, one last thing, you shouldn't need to set the pin modes on the encoder and switches yourself, the library will do it for you. Also you can't take a listener on the switch that is on the encoder, it's used by tcMenu internally, and a switch can only have one listener.
There are two ways you can get around this.
1/ in the takeOverDisplay rendering callback, the two parameters are the position of the encoder, and the button press state is one of the following values:
RPRESS_NONE = 0,
RPRESS_PRESSED = 1,
RPRESS_HELD = 2
2/ You could handle the button yourself, in that case I'd recommend setting up the encoder and switch in your own code and following the section on setting up the menu control manually in this guide: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menumanager-and-iteration/
|
|
|
Also in terms of having to take over the display just to get better fonts and drawing. That shouldn't be needed from 2.0 onwards, the UI is completely skinnable, and can even be re-skinned while it's running, or custom per submenu or item.
|
|
|
I think I can see what's wrong, you are setting up the multiIO AFTER setupMenu(). However the switches and rotary encoder initialisation happens in setupMenu. Try moving it just after Wire.begin(). In fact for safety setupMenu should be after Wire.begin too.
TcMenu i can only operate if i do not use setupRotaryEncoderWithInterrupt(encoderAPin, encoderBPin, onEncoderChange, HWACCEL_REGULAR);
Using that setup of the Encoder does have as consequence the Encoder does not react in TcMenu.
I suspect this is the above. However, I'm not really sure what you mean by you can't use that function? Can you not use the function because it doesn't work, or for some other reason?
IoAbstractionRef multiIoENC = ioFrom8754(0x20, 2); i need for TcMenu, without there's no reaction in the Menu, with it does run like a charm.
Being confused a bit as i cannot get an idea how the pins are defined then.
The code you provided in the orginal post looks right to me in terms of setup but just in the wrong place. Try moving before setupMenu.
How to setup the Encoder in an multiIoAbstraction for TcMenu
As above.
and another Renderer as e.g. using an standard 1366 library ( E.g. Adafruit ) ?
You can use any library that's compatible with Adafruit_GFX or you can use U8G2. When 2.0 comes out, we'll also support TFT_eSPI and LTDC frame buffer. You'd just use the custom Adafruit_GFX renderer option. In that case you create the variable yourself and just tell tcMenu the variable name you've created, and the class / include header name.
|
|
|
You can schedule and cancel in any order, but you're better not relying on cancel for regular operation. It's a very heavy operation that has itself to wait for scheduling. There is no guarantee that it will happen before the next execution.
Cancelling a task involves scheduling a task for immediate execution that will go through the running queue and remove the task that is to be scheduled.
It's better when the event timing changes often to use the schedule once as shown in my example. You could also use a polling event as described in the task manager docs.
|
|
|
What I would do in your case is use scheduleOnce as follows, then it will always use the correct time:
void myTimerTask() {
// other work to be done
taskManager.scheduleOnce(menuTime.getCurrentValue(), myTimerTask, TIME_SECONDS);
}
myInitialisation() {
taskManager.scheduleOnce(menuTime.getCurrentValue(), myTimerTask, TIME_SECONDS);
}
|
|
|
|
|
|
Is there a way that one can see a list of the names of the "functions" scheduled?
Short answer: You can see the task states (what's scheduled basically) but not the function names.
Longer answer: There is not really an easy way to do that, as RTTI (runtime type information) is not enabled on any embedded framework I've used (to reduce memory footprint). The only other way we could do it is by capturing __LINE__ and __FILE__ but that would be hideously expensive adding very high overhead to every task.
There is a function show what the state of each task slot is, but it only shows if it is running, waiting etc.
char* checkAvailableSlots(char* slotData, size_t slotDataSize) const;
Each slot is output in turn, so a trick you could use is to log each ID you get back from creating tasks, each one is an offset in that list of slots.
|
|
|
We have released the first public beta of 2.0 including libraries and everything needed to try it. There is a Linux, Win7, and Win10 build available now. Up until now, most Mac users have not requested a BETA version so we usually just test these internally.
FIRST NOTE that this is a BETA version and is for evaluation only, never bake in a beta version and expect to find issues.
To try the beta version:
Step 1 - download the BETA UI and library from https://www.thecoderscorner.com/products/apps/tcmenu-designer/
Step 2 - Java version, when the root item is selected switch the stream to BETA, choose update plugins
Step 2a - UWP/Win 10 - open settings, switch stream to BETA, choose update plugins
Step 3 - replace your tcMenu library with the beta version of tcMenu that is on the above-linked page.
The expectation is that there are a few issues still in there, please report anything found here. Currently tested to some extent:
- AVR (Uno, MEGA2560)
- SAMD (MKR1300)
- ESP (Heltek Wifi ESP32, AZ Delivery DevKit ESP32, Node MCU ESP8266)
- ST mbed (STM32F439, STM32F429)
- Nano 33 BLE
Known issues:
* The new renderer is sometimes redrawing too much screen area.
* Scrolling on a list item sometimes exceeds the list range.
* Touch screen manager not respecting read-only flag on items.
* Memory footprint not yet optimized, using > 15K more than before for graphical displays, fixes will feed through during beta.
|
|
|
Ah I see, apologies there I misunderstood the question.
The best example to look at is simpleU8g2, it is pretty much the minimum code to start a menu and also load and save from eeprom.
https://github.com/davetcc/tcMenuLib/blob/master/examples/simpleU8g2/simpleU8g2.ino
In summary from the above linked sketch:
Function setup() has the calls needed to both initialise the EEPROM and to load the values back. Or for clarity BEFORE calling setupMenu() you should:
EEPROM.begin(512); // prepare ESP rom for 512 bytes
menuMgr.setEepromRef(&arduinoEeprom); // set it on menu manager
After calling setupMenu you would then load values back.
menuMgr.load();
Function onSaveSettings() has the code needed to save to the rom. Or to be clear:
menuMgr.save();
EEPROM.commit();
|
|
|
There is no way that we can automatically save on power down, you would need to detect power loss in your PSU and handle it. Also, don't forget that on ESP boards the EEPROM is a flash emulation, it requires a call to its commit() method after menuMgr.save() has been called.
Event callbacks do not send the value, they send only the ID of the changed item, instead you just get the value directly from the menu item. EG if you have a root level analog item called Volume, you'd do menuVolume.getCurrentValue() to get it's value.
-- copied from an earlier post:
The best place to save is either to provide a save function somewhere on the menu, or to detect the power down state and then save during the power loss detection. See this page.
https://www.thecoderscorner.com/electronics/microcontrollers/psu-control/detecting-power-loss-in-powersupply/
You can also run a timer, once every few minutes and detect if anything has been committed using a commit handler, if it has then save the changes to ROM. See the commit handler docs: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menumanager-and-iteration/
However, never attempt to save to EEPROM in a callback, it will destroy your ESP's flash in days with a rotary encoder.
|
|
|
To be honest, this looks more like a board incompatibility than a problem with the designer. As both generate the same code for remote connectors, first I would check you are targetting the same board.
BluePill is not a configuration that we test with, and I suspect there is something non-standard about its USB serial interface.
We test with:
AVR: Uno, Mega
SAMD: MKR, Xio
ESP: ESP32 and ESP8266
STM32F4: mbed framework with ST boards
Nano 33 BLE
It will probably work with many other boards, but the serial can be tricky because there are many implementations and no standard defined. Can you check if framework versions or board types differ between the two?
|
|
|
My challenge is that when I schedule the "Display Sensors function" that should update the display only when the menu is inactivated, the display is distorted with a mix of the sensor display and the menu.
It sounds like you're updating the display outside of the rendering callback. You must never draw to the display outside of that callback because you'd otherwise risk multiple commands being sent to the LCD at once.
How do I test if the menu is active and ensure that the "Display Sensors function" does not run while the menu is open?
The best way to do that is invert the logic, put all the drawing code for this only in the take over display callback, and the sensor function just stores this state into a variable somewhere (that would then be read by your drawing code).
|
|
|
See the 2.0 release thread, just left a comment there.
|
|
|
TFT_eSPI is working on master, but master is not yet fully tested for all cases, we are about to do a large commit onto master within the next day or so. At that point, it will be feature complete for 2.0 and many of the in-flight issues will be fixed. Changing from one renderer to another is almost automatic in the designer UI. In 2.0, the biggest change will be the way the rendering classes work, they are skinnable at the cost of a little more memory. We need to go back and optimise this a bit for AVR, but for ESP32 it will be absolutely fine.
For ESP32 it's been through a number of tests as we have two boards and it's one of two core dev envs for me. 1. A AZdelivery DevKit dual core with an ESPprog debugger, touch screen, 320x240 display using TFT_eSPI. We also have another single core board with a similar display, rotary encoder and Adafruit for rendering. Be aware that documentation (other than Doxygen comments in code) is not ready for 2.0 yet.
You can easily switch to the 2.0 plugins in designer, change the library version stream from stable to beta from the settings. However, at that point, you'll need to get the master branch of tcMenu. And that needs 1.7.5 of IoAbstraction minimum.
I will announce here once the new beta UI is built and the tcMenu library beta code is done. It may be worth waiting a day or two for that to be honest.
|
|
|
|
|