The Softata API both in the Arduino sketch and its .NET library has been refactored to remove device specific information from the top and intermediate levels of the API making device extensibility much simpler.

Softata API Changes

The object of the current activity with Softata is to separate the hardware connectivity and maipulation into a separate library that is then included into the Softata RPi Pico W sketch. The aim is to bury all of the hardware specific code into that library and to abstract or generalise all calls to it by the sketch. Whislt the sketch initialisation is actioned, or orchestrated in the sketch, the library has three main classes:

  • Actuator
  • Sensor
  • Display.

Specific hardware then implemented as a subclass of one of these. For example, there is a Relay class and a Servo class as subclasses of the Actuator class. Each of the 3 parent classes define a generic set of methods and properties that all subclasses must implement. SoftataDevice methods either return a true or false (i.e. fail) as for device setup calls, return a value as for sensor queries or return a Tristate value. If there is a generic method that makes no sense in a subclass then the subclass now returns a “not implemented” message without causing failure. Previously, such a scenario caused a sketch failure.

enum Tristate {_nok=0,_ok=1,notImplemented=-1, _nan = -2, invalidParams =-3};

Non-data SoftataDevice method results

  • _nok means a fail
  • _ok means all good
  • notImplemmented means as such but doesn’t cause a sketch failure
  • _nan if for sensor value failures. Not currently used.
  • invalidParams means as such but doesn’t cause a sketch failure

The Display class has a Misc method. This is implemented in a device’s subclass with a range of submethods specific to the device. Home is a generic Display method (implemented by all displays, including not implemented option) whereas blinkon/blinkoff are Misc subcommands specific to the LCD1602 display. Actuators don’t have device specific sub-methods like displays but there is a querable filter that indicates which group of actuator generic methods are implemented … _Byte wide writes versus bit-wise. The Servo only accepts angle value writes as a byte, whereas the relay accepts only bit-wise set/clear/toggle calls. Sensors don’t have any sensor specific sub-methods but there is a query to get a list of the sonsor’s properties. When a sensor is read, it returns all of the current values of the each property unless a specific property is asked for.

To add a new device to the library, you only need to implement its class as a subclass of one the 3 parent classes, implementing the classes generic methods and properties. There should be no need for code modification in the sketch.

The Softa-ta repository presents some apps to exploit the Softata code running on a RPI Pico W. The service presents as a remote service that the apps can access over WiFi. The client apps are;

  • C# Console App
  • Blazor App
  • Blockly app

This Sofata functionality is encapsulated into a .NET class that these 3 apps all use to remotely communicate with the Arduino hardware. The 3 apps are a work in progress needing to be updated for the latest version of the Arduino code. The Console app has been progrssively updated such as:

The top level code, these apps, is being revamped with a view to limiting the device specific meta-information needing to be stored in the .NET class. The objective is make this info querable from the low level classes remotely via the sketch. Hence, adding new devices should not require any code adjustments in these apps. Indeed, adding new devices should not require any code changes to the sktech. For example, originally there was an enums list of sensors in the C# library that mirrored the enum list in the Arduino code. In calling a device method, the app transmitted the ordinal for a specific sensor which was then matched with the list in the arduino code, and the correct sensor class was actioned. You can now query the sketch for an ordered list of sensors and use a selected sensor’s order to send back to the sketch to identify which class to specific sensor class.

With this newer version of the API, the app makes a query to get an ordered list of generic commands for a device type, once the device is selected. The returned data is a name for each command and its ordinal which are placed in a dictionary. Top level code then queries the dictionary for a comamnd based upon its name or part thereof returning its ordinal value whcih is then used in the call to the sketch. A second dictionary is created for use in menus that select commands for a previously selected device, that has been instatiated. This removes device methods from the dictionary that are not needed once the device is instatiated in the top level app. These commands include setup and getting the list of comamnds (which for simplicity is always the first (zeroth) command). These commands are identified by starting with a capital letter, whereas all other comamnd start with a lowercase letter.

Actuator commands have an a_ or A_ prefix
Displays commands have a d_ or D_ prefix
Sesnsor comamnds have an s_ or S_ prefix

#define ACTUATOR_COMMANDS C(A_getCmdsCMD)C(A_getDevicesCMD)C(A_getPinsCMD)C(A_setupDefaultCMD)C(A_setupGeneralCMD)C(a__getValueRangeCMD)C(a_writeDoubleValueCMD)C(a_writeByteValueCMD)C(a_writeWordValueCMD)C(a_SetBitStateCMD)C(a_SetBitCMD)C(a_ClearBitCMD)C(a_ToggleBitCMD)C(a_GetnumbitsCMD)C(a_GetInstanceValueRangeCMD)C(a_GetActuatorCapabilitiesCMD)

Actuator Generic Commands

Nb: In the Arduino code, a macro is used to turn this definition into an enum list and another macro turns into a matching ordered array of strings.

Also, a small number of commands have 2 underscores. These, whilst returning a response specific the actual device in question, are queried of the device class rather than an actual instance as they are the same for all instances of th e device:

  • a__getValueRangeCMD
  • s__getPropertiesCMD
  • d__miscGetListCMD

In the Console app, they are listed as selectable commands for a device instance but could be queried from the device class without needing a device instance.

Further

As mentioned previously, in a previous iteraction in the Conole app, some device functionality was dependant upon the enum for the device. This included a device type class being implemneted in the .NET library. There is/was a .NET class for each of the Actuator, Display and Sensor. These included specific methods that mirrored those presented by the Arduino service. A later version modified this such that required data for a service call was determined and actioned by string comparisons. For example, with Actuators, the name of the instatiated device was determined and this was used to select what data was required and prompted for. The Servo just required an angle, the QuadRelay required a bit or byte value etc. As part of this verion to abstract things as much as is possible, much of the relience of the these classes has been removed and calls are now made direct from the app. Now, only the Display Misc commands make use of a specific class in the .NET library.

API Method Call

Once a method for an instantiated device has been selected and the required data has been marshalled, the call from the the Console app is:
Except for Display Misc calls which still remain relatively specific.

// data is the marshalled data. If length is 0 then there is none so make it null.
if (data.Length == 0)
{
    data = null;
}
// Normally targetDeviceIndex is 0xff, means ignore it and use linkedListIndex, ie use instantiated index
// For specific devicetype.device commands use its devicetype.device index.
byte targetDeviceIndex = 0xff;
if (stringlist.Any(s => s.Contains(TargetCommand.Item)))
{
    targetDeviceIndex = (byte)TargetDevice.Index;
}
string response = softatalib.SendTargetCommand((byte)TargetDeviceType.Index, (byte)pinn, (byte)TargetCommand.Index, targetDeviceIndex, linkedListNo, data);

Nb: All calls from the Console app for instantiated device methods pass through this same lines of code, except for the Misc commands.

2Dos

  • Implement this functionality the Blazor and Blockly apps.
  • Add a new device to test the simplicity of the process.

 TopicSubtopic
<  Prev:   ConsoleTextFormat
   
 This Category Links 
Category:Softata Index:Softata
<  Prev:   Softata