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

tcMenu Arduinio library » A few questions about MultiIo, mixed input types, and 30-second refresh issue

Author: milesg
08/10/2021 23:38:50
Hi Dave and all else reading.

I don't want to flood the board with multiple threads, but I don't know if you like to have too many questions asked in one spot. I'll try to keep it brief for now.

Firstly; Thank you for working on these wonderful libraries. The IOAbstraction has already helped me simplify and unify my project dramatically. When I started looking into making a menu system for my project I was blown away find tcMenu and see that it's made by the same person! Serendipity! The documentation is quite good and even though I'm on the low end of intermediate skill level for this stuff, I'm almost always able to figure things out so far. Execept....

Question1:
Before working on the menu system, I had manually setup all my IO with MultiIO and using the tcMenu GUI setup my IO reference and pin numbers (starting at #100 as in the example INO.) This works, but ONLY if I go into the *Project_name*_menu.h and change the line:

extern IoAbstractionRef multiIO;

to:
extern MultiIoAbstractionRef multiIo;


Is there a way to do this so I don't have to edit this file every time I generate new code from the TcMenu UI? Perhaps something I can call in my main INO so I don't have to touch the things I'm not supposed to?

Question 2:
I would ideally like to use UP/DOWN/ENTER buttons to navigate the menu, and use the encoder to change the values. I have some menu items which can have high values (0-20,000, or 0-360degrees in 1/10 degree increments) that would be best served with a sensitive/accelerated knob, but I like the more tactile inputs for menu navigation because it's too easy to fly past options when using the knob. How might I get both functionalities like this?

Question 3:
If I leave any menu or sub-menu item selected, and don't touch anything, the screen (ILI9341) will refresh and put the cursor back on the first item on the top-menu 30 seconds after my last input. Is there a way to stop this behavior?
EDIT: Did some digging and found the setResetIntervalTimeSeconds() function. Okay, so I can set it to 60sec max. but it still seems strange to have it just happen on fixed timer no matter what.

Bonus Bug Report:
In TCMenu GUI Ver. 2.2.3 The Up and Down fields are reversed from the code output when using the UP/DOWN/ENTER button option with a MCP23017 (Not sure if it happens with other input configs, but this is what I'm using for testing)
If I put '2' in the Up field and '10' in the Down field, the code comes out:
menuMgr.initForUpDownOk(&renderer, &menuToasterPower, 2, 10, 4);

instead of:
menuMgr.initForUpDownOk(&renderer, &menuToasterPower, 10, 2, 4);


Only a minor inconvenience to switch my pin numbers in the project and forget it, but seems like it'd be an easy fix.

Thank you so much for your time/help.

Author: davetcc
10/10/2021 09:44:14
Wow quite a long post, hopefully I've got everything here..

Question1:


If I'm honest I've never tried a multiIO with TcMenu, but a MultiIO reference should be compatible with a regular IO reference. IE MultiIoAbstractionRef should be compatible with IoAbstractionRef.So you would just declare your device in the sketch and reference it as usual. Does this not work in practice?

Question 2:


This is possible, in fact, you can take complete control of the input facilities yourself. This is how keyboard support and touch works. See the section on manually controlling input in: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menumanager-and-iteration/

Question 3:


It should only happen when the menu is touched to be honest, it is to reset the menu so that it is in a good state if another users comes to start using the system at some point later. Many use this to display a screen saver or splash screen. If the menu hasn't been touched, it shouldn't reset. If it does reset under non-touch conditions, there's a bug that needs to be fixed. Are you asking to be able to turn off this behaviour?

Bug report:


Thanks, I'm in the middle of a taskmanager and tcMenu patch release. I'll fix the plugin XML.

Author: milesg
10/10/2021 19:15:05
Hey Dave, You got everything. Thank you so much smilie

Answer 1: Does this not work in practice?


Unless I change the line mentioned in my first post, I get this error during compilation:

conflicting declaration 'MultiIoAbstraction* multiIo'


Here's the relevant part of my main sketch (I commented the line near the top where the conflict occurs):
#include "Valve_Controller_Master_menu.h"
#include 
#include 
#include
#include 

#define expanders 100 // start our expanders on pin 100
MultiIoAbstractionRef multiIo = multiIoExpander(expanders); //<--Conflicting with this line

/**************** PIN MAP ***********************
All pin numbers defined here with friendly names 
(on Teensy or expanders) used to address them.
Pins used for Serial and Wire functions do not 
need to be defined here. ***********************/

//A Bunch of PIN# declarations omitted here

/************** END PIN MAP ******************/

uint8_t EncoderValue = 0;


// When any switches are pressed, this function will be called.
void onSwitchPressed(uint8_t key, bool held) {
  /* Uncomment below for debugging*/
  //Serial.print("Switch "); 
  //Serial.print(key);
  //Serial.println(held ? " Held down" : " Pressed");
}

//When the encoder is turned, this function will be called.
void onEncoderChange(int newValue) {
  EncoderValue+=newValue;
  /* Uncomment below for debugging*/
  //Serial.println(EncoderValue);
}


void setup() {
  setupMenu(); // Start the Menu Business
  Wire.begin();
  /* Uncomment below for debugging*/
  //Serial.begin(115200);

  // I/O set up...
  multiIoAddExpander(multiIo, ioFrom23017(0x20, ACTIVE_LOW_OPEN, exp1_int), 16); // Add the primary expander for Front Panel Buttons/Encoder, Interrupt on Pin 5
  multiIoAddExpander(multiIo, ioFrom8574(0x21, exp2_int), 8); // Add secondary expander for Dual Axis Controller buttons and 2x LEDs, Interrupt on Pin 6

  switches.initialiseInterrupt(multiIo, true); // Make these Pins work as interrupts (pullup enabled)

  for (int i=0; i<24; i++) { // Setup all the pins
    if (i==2 || i==4 || i==8 || i==10) { // Do nothing. These pins set up in TcMenu or Pin 108 is set up below with Pin 109.
    } else if (i==9) {
      setupRotaryEncoderWithInterrupt(encoder_a, encoder_b, onEncoderChange, HWACCEL_REGULAR, QUARTER_CYCLE); // Setup Pins 108-109 as encoder input
    } else if (i==16 || i==17) { //These two are LED outputs for Axis Selection
      ioDevicePinMode(multiIo, expanders + i, OUTPUT);
    } else { // Everything else becomes a button input
      switches.addSwitch(expanders + i, onSwitchPressed);
      ioDevicePinMode(multiIo, expanders + i, INPUT_PULLUP);
    }
  }  
  // I/O set up done.
  
}

void loop() {
  taskManager.runLoop();
}



Answer 2 You can take complere control...:


Awesome, I'll check it out. In short, I'm assuming I just add the relevant commands to my onEncoderChange function for using the knob, but let the tcMenu generated code handle the buttons as they are already?

Answer 3: Are you asking to be able to turn off this behaviour?


Yes, that is what I was asking. I was having some glitchy behavior where it was happening while I was clicking through menu items or changing values, but I've stripped things down and it's working normally. Must have been something wrong with what I was doing in my main sketch that was conflicting somehow. I'm fine with it acting normally, but would be curious to know if there's an easy way to disable it for future reference.

Bug report:


Thank you!

Author: davetcc
12/10/2021 08:05:00
In terms of the IoAbstraction, try:

MultiIoAbstractionRef multiIo = multiIoExpander(expanders); //<--Conflicting with this line
IoAbstractionRef multiIoRef = multiIo;


Then for the IO reference just put in "multiIoRef" instead. That should work as a MultiIoAbstractionRef should be directly castable to IoAbstractionRef

Author: davetcc
12/10/2021 08:17:13
For the reset feature I've added logic for it as it is trivial. If you wanted it now you could try the below. If it works when I test it, it will go into the next release.

In tcMenu library, BaseRenderers.h take a backup just in case and add the following method directly after method setResetIntervalTimeSeconds

/** 
     * Completely turn off the reset interval so there will never be a reset. 
     */
    void turnOffResetLogic() {
        resetValInTicks = MAX_TICKS;
    }

Author: davetcc
12/10/2021 08:19:20
Lastly, for overriding the input facilities. Given that you intend to override the way input works, it's best to complete control IMHO. But realistically it's up to you in terms of what works.

I would set the code generator to "no input required". Then I would manually handle all the buttons and rotary encoders yourself, calling the menu manager functions as per the above guide.

Author: milesg
12/10/2021 17:18:07
Thank you for the very helpful information.

Regarding the multiIO conflict, it appears that your suggestion works perfectly. As it turns out, I was testing my code yesterday with your last suggestion (complete control/no input required) and that gave me much better results and completely bypassed the conflict I was having anyway. So both options are totally workable, but I think you're correct; with overriding my inputs, your last suggestion is simple, clean and keeps all my input-code in one, editable place so I can tweak things to my heart's desire.

I've come to terms with the menu reset timer, but I'm glad it'll become an option in future releases. I'll be sure to check it out!

Thanks again. I'm well on my way now smilie




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