I don't see how you're associating "3" with the value. Can you, or anyone explain that?
The MOV in the fourth (last) rung uses the 3 as an indirect* address into the array Width_Actual[], where
- Width_Actual[1] = Actual_Normal_Width
- Width_Actual[2] = Actual_Wide_Width
- Width_Actual[3] = Actual_Custom_Width
This is what I was suggesting in an earlier post; it's extensible, and there could easily be several customs, with only one rung required for each.
I think this is what you have been asking for from the OP: the one rung, with the MOV at the end, is all that is required to actually load the value, instead of one rung per Actual_*_Width; there will always be one rung per PB to detect the press of course**
* or maybe it's "indexed?" I am not fluent with the jargon
** unless there is some fancy bit twiddling: The PBs could flip bits in a DINT (you suggested that option in
post #4) that is used as the indirect address, and the indirect addresses with valid values*** could be 1, 2, 4, 8, ..., with all other address set to -1, and the last move is only performed if the value at the indirect address is not -1. So if someone pressed PB Normal and Custom at the same time, the DINT would be 1+4=5, and Width_Actual[5] would have been loaded with the value -1, and the final COP or MOV into VFD_Values[0] would not be done on that scan. Another way would be to only do the COP/MOV if there was only one bit set in the DINT; that way you would not have to set all the unused positions in the Width_Actual[] array to a known invalid value. Yes this wastes a lot of space in Width_Actual[], but memory is usually cheap.
*** Width_Actual[1] would be .005; Width_Actual[2] would be 0.011; Width_Actual[4] would be the current Custom value