Pages

Tuesday, June 13, 2017

Importing the Salesforce Summer 17 (v40.0) Tooling and Metadata APIs to .NET

The Salesforce Summer '17 release includes the return of an old friend in both the Tooling and Metadata APIs. After refreshing to the latest WSDLs and making sure the project builds it starts producing errors like the following with calling the API:

error CS0029: Cannot implicitly convert type 'XYZ.SalesforceConnector.SalesforceTooling.NavigationMenuItem' to 'XYZ.SalesforceConnector.SalesforceTooling.NavigationMenuItem[]'

I say it's an old friend, because I've seen this before with the Partner API when it transitioned to Winter '15 (v32.0) for the QuickActionLayoutItem. It's also cropped up with Winter '13 (v29.0). Thankfully the same fix that was applied in those cases will also work here.

The problem is the navigationLinkSet property that gets generated with a multidimensional array return type. The type for the corresponding XmlArrayItemAttribute is incorrect.

Before Fix

/// 
[System.Xml.Serialization.XmlArrayItemAttribute("navigationMenuItem", typeof(NavigationMenuItem), IsNullable=false)]
public NavigationMenuItem[][] navigationLinkSet {
    get {
        return this.navigationLinkSetField;
    }
    set {
        this.navigationLinkSetField = value;
    }
}

After Fix

/// 
[System.Xml.Serialization.XmlArrayItemAttribute("navigationMenuItem", typeof(NavigationMenuItem[]), IsNullable=false)]
public NavigationMenuItem[][] navigationLinkSet {
    get {
        return this.navigationLinkSetField;
    }
    set {
        this.navigationLinkSetField = value;
    }
}

The same fix needs to be applied to both the Tooling API and the Metadata API.

Monday, June 12, 2017

Controlling analog PWM servos from a Raspberry Pi

As part of a project I'm working on I needed a way to generate motion from my Raspberry Pi. It needed to be a precise variable motion rather than the all or nothing type motion of a straight DC motor. I opted to go with PWM (Pulse Width Modulation) based servos as I'm familiar with them and have some on hand for RC planes. Stepper motors or a DC motor with a rotary encoder were other options, but I have neither in my spare parts bin.

So PWM servos it is. Now, how to control them from the Pi? Getting the Pi to feed the hard real-time response requirements of a servo motor directly can be difficult, so I opted instead to offload the task to an Adafruit 16-Channel PWM / Servo HAT.

Some assembly required

Software

Because I'm a .NET person I used Windows IoT to program the Pi. Adafruit even provide the AdafruitClassLibrary for Windows IoT. The rough code, less exception handling.

var i2cSettings = new Windows.Devices.I2c.I2cConnectionSettings(0x40);

var gpio = Windows.Devices.Gpio.GpioController.GetDefault();

Pca9685 hat = new Pca9685(0x40);
await hat.InitPCA9685Async();

hat.SetPWMFrequency(50);

ushort servoMinPulseLength = 150;
ushort servoMaxPulseLength = 600;

hat.SetAllPWM(0, servoMinPulseLength);

           
while (true)
{
    hat.SetAllPWM(0, servoMinPulseLength);

    await System.Threading.Tasks.Task.Delay(500);

    hat.SetAllPWM(0, servoMaxPulseLength);

    await System.Threading.Tasks.Task.Delay(500);
}

The exception handling turned out to be one of the harder parts of getting this to work. I kept getting debug messages like Value cannot be null.:I2C Write Exception: {0}. Not very helpful. Once I found the corresponding Github project and worked directly from the source the problem was easier to isolate. They are catching the majority of the exceptions in their code and dumping them out to the debug log and then carrying on. This was causing all sorts of problems, with the first occuring in the `InitPCA9685Async` call. The ultimate resolution was to up the Microsoft.NETCore.UniversalWindowsPlatform NuGet package to at least 5.2.2.

After that I just needed to set sensible values for the PWMFrequency and minimum and maximum pulse lengths. Most of the demo code I've seen has a default frequency of 1000. That seemed way to high and the servos became a jittery mess. The general consensus for an analog RC servo is somewhere in the 30Hz to 60Hz range. Some good reading on the difference between PPM and PMW.

The Result

All going well I'll have more posts soon to bring this together with the other parts I'm working on.