The base class Grove, besides 2 static methods, only has Setup() methods and DeviceType property. The device specific classes descend from this and so polymorphism is used in the software.

class Grove
{
    public:
    static bool SetI2CPins(int i2c);
    static String GetListofDevices();
    virtual bool Setup();
    virtual bool Setup(byte * settings, byte numSettings=1);
    DeviceType deviceType;   
    protected:     
};

enum DeviceType{sensor,display,analog,actuator}

The other four classes, each a separate device type, are derived from the Grove base class, and so they can be called to set up in the Grove context. (Once instantiated, but then assigned as a Grove instance.) These other classes then add methods relevant to the device type, although each actual instance of a device type won’t actually implement all of the methods. Displays which have a lot of specific functions have a Misc method to which are passed commands specific to the device type instance class.

Also again making use of polymorphism, because each specific instance of a device type is descended from that device type’s base class, it can be assigned as an instance of that device type base class and so much functionality for that type can be called generically. That makes adding more devices of that type simple.

When, for example, a BME280 sensor is instantiated as part of a Setup() call to the Arduino app, it is added to the Sensors linked listed returning its index in the list. This linked list is of Sensor type and so any sensor descended from the Grove Sensor class can be added. Subsequent calls to the app use the index to get a a reference to the sensor instance and so the Sensor methods ReadAll() or Read() can be called without knowing what type of sensor has been invoked.

    Grove_Sensor * grove_Sensor = GetSensorFromList(other);
    byte property = pin;
    double value = grove_Sensor->Read(property);
    if (value != DBL_MAX) //DBL_MAX is error condition
    {
        String msgGetOne = "OK:";
        msgGetOne.concat(value);
        client.print(msgGetOne);
    }

Similarly, polymorphism is used with Displays. All displays have a Misc() method but the Misc subcommands are different for each display. But for a display subcommand, a call is made to the Display.Misc method with suitable data, without knowing the type of display. That detail is implemented in the actual display class.

    int index=other;
    Grove_Display * grove_Display = GetDisplayFromList(index);
    byte miscCMD = otherData[1];
    byte * miscData = NULL;
    byte miscDataLength = otherData[0]-1;
    if (miscDataLength>0)
    {
        miscData = otherData +2;
    }
    if(grove_Display->Misc(miscCMD,miscData,miscDataLength))
    {
         client.print("OK:");
    }

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