public IOExpander(string portName)
: base(portName, 0)
{
this.DigitalInputs = new PhysicalDevice.DigitalInput[3];
for(int index = 0; index < this.DigitalInputs.Length; index++)
this.DigitalInputs[index] = new PhysicalDevice.DigitalInput();
this.DigitalOutputs = new PhysicalDevice.DigitalOutput[4];
for (int index = 0; index < this.DigitalOutputs.Length; index++)
WireupOutput(index);
this.Motor = new PhysicalDevice.MotorWithFeedback((target, speed, timeout) =>
{
SendSerialCommand(string.Format("M,{0},{1},{2:F0},{3:F0}", 1, target, speed * 100, timeout.TotalSeconds));
});
this.changedPixels = new HashSet<byte>();
this.cancelSource = new System.Threading.CancellationTokenSource();
this.firstChange = new System.Diagnostics.Stopwatch();
this.pixelData = new byte[4 * 50];
for (int i = 4; i < this.pixelData.Length; i += 4)
this.pixelData[i] = 32;
this.senderTask = new Task(x =>
{
byte[] bytesToSend = null;
while (!this.cancelSource.IsCancellationRequested)
{
lock (lockObject)
{
if (this.changedPixels.Any())
{
this.firstChange.Stop();
this.sentUpdates++;
log.Info("Sending {0} changes to IOExpander. Oldest {1:N2}ms. Recv: {2} Sent: {3}",
this.changedPixels.Count, this.firstChange.Elapsed.TotalMilliseconds,
receivedUpdates, sentUpdates);
if (this.changedPixels.Count <= 2)
{
foreach (var channel in this.changedPixels)
{
int dataOffset = 1 + channel * 4;
var shortSend = new byte[] { (byte)channel,
this.pixelData[dataOffset + 0],
this.pixelData[dataOffset + 1],
this.pixelData[dataOffset + 2]};
SendSerialCommand((byte)'R', shortSend);
}
}
else
{
// Send everything
bytesToSend = new byte[this.pixelData.Length];
Array.Copy(this.pixelData, bytesToSend, this.pixelData.Length);
}
this.changedPixels.Clear();
}
}
if (bytesToSend != null)
{
// Takes about 40 ms to send the data for all pixels
SendSerialCommand((byte)'R', bytesToSend);
bytesToSend = null;
} else
System.Threading.Thread.Sleep(10);
}
}, this.cancelSource.Token, TaskCreationOptions.LongRunning);
this.senderTask.Start();
Executor.Current.Register(this);
}