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

tcMenu Arduinio library » AnalogMenuItem Rendering

Author: Jaco van Zyl
15/02/2021 13:27:51
I understand the AnalogMenuItem is unsigned 16bits Max value 65535.
When I increase the value beyond 15 bits 32767 the value displayed becomes negative and starts at 0.
The value 32768 will display as -0 on the LCD but printing it to the serial port it is correct.

#include "src/CYCLE_menu.h"
uint16_t Cycles = 0;

void setup() {
    setupMenu();
    Serial.begin(115200);
}

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

void CALLBACK_FUNCTION onCycle(int id) {
    // TODO - your menu change code
    
}

void CALLBACK_FUNCTION onIncCycle(int id) {
    // TODO - your menu change code
    Cycles=32768;
    menuCYCLE.setCurrentValue(Cycles,true);
    Cycles = menuCYCLE.getCurrentValue();
    Serial.println(Cycles);
  }

[Thumb - TcMenu1.png]
Filename TcMenu1.png
Description No description given
Filesize 48 Kbytes
Downloaded 55974 time(s)
[Disk] Download

[Thumb - TcMenu2.png]
Filename TcMenu2.png
Description No description given
Filesize 34 Kbytes
Downloaded 54694 time(s)
[Disk] Download


Author: davetcc
15/02/2021 14:39:45
Normally analog items are usually in the range of a few thousand. IE, either for a value to be displayed on the screen or for a value that needs to be editable with a rotary encoder or up down buttons.

To be honest we'll need to test them for such large values on a few boards and then feed back here.

Author: davetcc
15/02/2021 14:40:35
BTW For very large values, you can also use editable large number, or float menu items.

Author: davetcc
17/02/2021 16:00:52
We've looked into this now and can report back that AnalogMenuItem has a maximum positive value of 32767 for display. This is because even though the underlying value is unsigned short, the rendering is done using a whole and fraction, which has a maximum range of 15 bits for the whole number.

However, we already have two custom types for very large numbers. So we don't recommend the use of AnalogMenuItem for ranges of above a few thousand, as they become difficult to edit.

There are two existing options:

* For read-only display values that exceed the range of a signed short where absolute accuracy is not needed - use FloatMenuItem, can take advantage of up to 9 significant digits.

* For read-only or editable values that exceed the range of a signed short where absolute accuracy must be maintained (IE floating point cannot be used)- use EditableLargeNumberMenuItem, can take advantage of up to 12 digits with complete accuracy. It is stored as BCD. The editing of extremely large values is possible, a digit at a time.

Author: davetcc
17/02/2021 16:05:52
So in your case, you'd probably change menuCycles to an editable large number. It could then have a range of up to 9 whole digits, and also fractional digits if you needed it. It can be either positive and negative, or positive only.

Author: Jaco van Zyl
17/02/2021 19:09:13
Thanks Dave, for all the information. I appreciate it. I will definitely change it. Can a FloatMenuItem be displayed with no decimal places?

Author: davetcc
18/02/2021 08:44:02
I don't think it can do 0 decimal places at the moment, the assumption was that people who needed an absolutely accurate value used large number, because floating-point values on any CPU are not accurate. https://dzone.com/articles/never-use-float-and-double-for-monetary-calculatio. In particular they cannot represent certain values and then you end up with the nearest interpretation. However, we'll make it possible to set it to 0 decimal places in the 2.0 release as it's trivial to do.

Many times people don't understand floating point types and expect accuracy.

The best type to use for very large whole numbers is editable large number, if you don't want it editable, then set it readonly. See https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/menu-item-types/largenum-menu-item/ that covers this type in detail. In your case, you would just set the whole number, clear the fraction and the negative flag would be false.



Eg something like:

LargeFixedNumber* numCycles = menuCycles.getLargeNumber();
numCycles->setWhole(myNewCycles);
numCycles->setFraction(0);
numCycles->setNegative(false);




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