The Test That Made Me Fucking Ecstatic

This code is for a test that uses the observer backpack that I discussed building in My Functional Test Rig. I had to write about it because it worked SO FUCKING WELL and I'm pissing myself with joy over it.

calming down now

In the source code, the object named observer is associated with the backpack, and the Arduino being observed is named arduino.

I begin with a utility method that constructs an instance of the observer. In it, I construct the object, initiate the connection, put all digital pins into input mode, and then ask them to report their status. Once it's set all that up, it returns a reference to the observer so that the test method could monitor it.

private static Arduino ConstructAndConfigureObserver(string serialPort)
{
    // Construct the observer
    var observer = new Arduino(serialPort);
    // Open the connection so we can begin sending messages
    observer.Connect();
    // Put everything into input mode
    for (var pinNumber = 2; pinNumber < 14; pinNumber++)
    {
        observer.Post(FirmataEncoder.BuildSetPinModeRequest(pinNumber, PinMode.Input));
    }
    // And start listening
    observer.Post(FirmataEncoder.BuildReportDigitalPortRequest(0, true));
    observer.Post(FirmataEncoder.BuildReportDigitalPortRequest(1, true));

    return observer;
}

Next I have the monitoring code. For the test, I'm going to set each of the digital pins high, one at a time, from pin 2 through pin 13. Using the observer, I watch as the values change in order. I handle seeing that everything happens in the correct order by keeping a few globals that contain the values I expect to see. The method below is the event handler that is executed each time a digital port report is received.

readonly object _editLock = new object();
private int _expectedPort = 0;
private int _expectedValue = 1;
private int _ignoreValue = 0;

private void WatchForDigitalPinCycle(object sender, FirmataEventArgs e)
{
    var message = e.Data as DigitalPortReport;
    Assert.IsNotNull(message);
    Assert.AreEqual(_expectedPort, message.Port);
    if (message.Value == _ignoreValue) return;

    Assert.AreEqual(_expectedValue, message.Value);
    lock (_editLock)
    {
        _ignoreValue = _expectedValue;
        _expectedValue <<= 1;
        if ((_expectedPort == 0) && _expectedValue == (1 << 7))
        {
            //switch port
            _expectedPort = 1;
            _expectedValue = 1;
        }
    }
}

Finally, we have the test itself. All it does is opens everything up and starts setting the digital pin values high one at a time.

[TestMethod]
public void CycleThroughDigitalPins()
{
    using (var arduino = new Arduino("COM6"))
    {
        arduino.Connect();
        using (var observer = ConstructAndConfigureObserver("COM3"))
        {
            observer.DigitalPortReportReceived += WatchForDigitalPinCycle;
            for (var i = 2; i <= 7; i++)
            {
                arduino.Post(FirmataEncoder.BuildSetPinModeRequest(i, PinMode.Output));
                arduino.Post(FirmataEncoder.BuildDigitalWriteRequest(0, 1 << (i - 2)));
            }
            for (var i = 7; i <= 13; i++)
            {
                arduino.Post(FirmataEncoder.BuildSetPinModeRequest(i, PinMode.Output));
                arduino.Post(FirmataEncoder.BuildDigitalWriteRequest(1, 1 << (i - 7)));
            }
        }
    }
}

Looking this over, I see that I might be ending the test before all of the values are received. I'll have to figure out how to end it correctly.

Last edited Jun 19, 2010 at 1:10 AM by RhyMednick, version 4

Comments

No comments yet.