The previous post discussed Blockly and Swagger Controller Setup methods that take an Device Type enum as a parameter. It manifests as a dropdown list of the device enum literals. How can that be applied for any Controller Method that can use other enum types as parameters, manifesting as dropdown lists in Blockly Blocks and Swagger Methods?

Context
With the Blockly blocks generated from the controller SoftataGPIOADController, you enter the values, such as a pin number and the code needs to validate them. An additional controller GroveGroveController has been added that mirrors the SoftataGPIOADController functionality. enums are used as parameters for GroveGroveController rather than numeric values. An object block is generated for each enum type used as a controller parameter. This makes things simpler because parameters are selectable and valid as you can only select literals in an enum list.

In what follows, this might all seem like a bit of hotchpotch but it does work!

Other enum types as Blockly parameters

The approach as per the previous post can also for be used for other parameters so as the aid selection and can constrained using an enum list.

  • enum analoginputs: byte {A0, A1, A2}
  • enum serial: byte {com1, com2}
  • enum GroveGPIOPins { p16,p17,p18, p119,p20,p21}
  • enum DigitalPinMode { Input , Output }
  • enum PinState { Low,High}
  • enum ADCResolutionBits { Bits10, Bits12 };
  • enum AnalogDevice { LightSensor, SoundSensor, Potentiometer, Other, Undefined} … etc

These then can be selectable in relevant blocks.

Set Grove Pico GPIO Digital Pin/Pin Mode

The Grove RPi Pico Shield in simple use limits GPIO to pins 16 to 21. So assign pn numbers to the literals thus:

   public enum GroveGPIOPins { p16=16,p17=17,p18=18, p19=19,p20=20,p21=21}
   public enum DigitalPinMode { Input , Output }

These enum create the GroveGPIOPins and DigitalPinMode Blockly blocks in the Objects that can be used with the block created by this Controller method:

    [Route("SetDigitalPinModeGrove")]
    [HttpPost]
    public IActionResult GroveDigitalSetPinMode(GroveGPIOPin pin, DigitalPinMode mode)
    {
        byte pinn = (byte)pin);
        SoftataLib.Digital.SetPinMode(pinn, (PinMode)mode);
            return Ok($"Pin:{pinn} Mode:{(PinMode)mode}");
    }

And so you get a dropdown list of valid GPIO pins for the Grove Pico shield and the two options for pin mode (Input or Output).

There is a problem though. This has been logged on the NetCoreBlockly site at Ordinals use the order in the list, not any assigned value. #174.

Following on from issue: #174 Given an enum type as parameter to a Controller can the enum literals show rather than the ordinal? which is closed.,

When the ordinals are used to set a value and a specific enum value is chosen then you get its order from zero in the list, not any assigned value. For example:

        public enum GroveGPIOPin { p16, p17, p18, p19, p20, p21 }
        public enum GroveGPIOPinX { pp16=16, pp17=17, pp18=18, pp19=19, pp20=20, pp21=21 }

When either is used as a parameter for a controller, you get values 0 …5 for both. Not 16 to 21 for the second enum type.

Further more, it’s taking that order number and trying to cast it to one of the enum ordinals and generally failing. For example using GroveGPIOPinX as a controller method parameter, if pp16 is used as the input to a block, it is been passed as 0 being first in the list then the controller tries to cast it thus (GroveGPIOPinX )0 which fails as 0 is not an ordinal in GroveGPIOPinX .

Whilst this is not a breaking issue, it might be confusing for those not knowing this.

Work around: Provided all values as sequential by one. You just add the expected first value to the value given for the selected enum. That is for GroveGPIOPin just add 16 within the controller.

[Route("SetDigitalPinModeGrove")]
[HttpPost]
public IActionResult GroveDigitalSetPinMode(GroveGPIOPin pin, DigitalPinMode mode)
{
    byte pinn = (byte)(16 + (byte)pin);
    SoftataLib.Digital.SetPinMode(pinn, (PinMode)mode);
        return Ok($"Pin:{pinn} Mode:{(PinMode)mode}");
}

Or a bit more formally for the byte value of the pin:

    byte pinn = (byte)((byte)GroveGPIOPinX.p16 + (byte)pin);

Not plucking the 16 out of thin air!


 TopicSubtopic
   
 This Category Links 
Category:Softata Index:Softata
  Next: > Softata
<  Prev:   Softata