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 nowIn 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.