2 using System.Collections.Generic;
24 private int[] NumberOfLedsPerStrip =
new int[8];
32 public int NumberOfLedsStrip1
36 return NumberOfLedsPerStrip[0];
40 NumberOfLedsPerStrip[0] = value;
50 public int NumberOfLedsStrip2
54 return NumberOfLedsPerStrip[1];
58 NumberOfLedsPerStrip[1] = value;
69 public int NumberOfLedsStrip3
73 return NumberOfLedsPerStrip[2];
77 NumberOfLedsPerStrip[2] = value;
87 public int NumberOfLedsStrip4
91 return NumberOfLedsPerStrip[3];
95 NumberOfLedsPerStrip[3] = value;
105 public int NumberOfLedsStrip5
109 return NumberOfLedsPerStrip[4];
113 NumberOfLedsPerStrip[4] = value;
124 public int NumberOfLedsStrip6
128 return NumberOfLedsPerStrip[5];
132 NumberOfLedsPerStrip[5] = value;
142 public int NumberOfLedsStrip7
146 return NumberOfLedsPerStrip[6];
150 NumberOfLedsPerStrip[6] = value;
160 public int NumberOfLedsStrip8
164 return NumberOfLedsPerStrip[7];
168 NumberOfLedsPerStrip[7] = value;
173 private string _ComPortName;
181 public string ComPortName
183 get {
return _ComPortName; }
184 set { _ComPortName = value; }
188 private int _ComPortTimeOutMs = 200;
197 public int ComPortTimeOutMs
199 get {
return _ComPortTimeOutMs; }
202 if (value.IsBetween(1, 5000))
204 _ComPortTimeOutMs = value;
208 _ComPortTimeOutMs = 200;
209 Log.
Warning(
"The specified value {0} for the ComPortTimeOutMs is outside the valid range of 1 to 5000. Will use the default value of 200ms.".Build(value));
224 return NumberOfLedsPerStrip.Sum() * 3;
235 if (ComPortName.IsNullOrWhiteSpace())
237 Log.
Warning(
"The ComPortName has not been specified");
241 if (!SerialPort.GetPortNames().Any(PN => PN == ComPortName))
243 Log.
Warning(
"The specified Com-Port {0} was not found. Available com-ports: {1}".Build(ComPortName,
string.Join(
", ", SerialPort.GetPortNames())));
247 if (NumberOfLedsPerStrip.Any(Nr => Nr < 0))
249 Log.
Warning(
"At least one ledstrip has a invalid number of leds specified (<0).");
256 SerialPort ComPort = null;
257 int NumberOfLedsPerChannel = -1;
263 throw new Exception(
"Comport is not initialized");
268 int SourcePosition = 0;
269 for (
int i = 0; i < 8; i++)
271 int NrOfLedsOnStrip = NumberOfLedsPerStrip[i];
272 if (NrOfLedsOnStrip > 0)
274 int TargetPosition = i * NumberOfLedsPerChannel;
275 CommandData =
new byte[5] { (byte)
'R', (byte)(TargetPosition >> 8), (byte)(TargetPosition & 255), (byte)(NrOfLedsOnStrip >> 8), (byte)(NrOfLedsOnStrip & 255) };
277 ComPort.Write(CommandData, 0, 5);
278 ComPort.Write(OutputValues, SourcePosition * 3, NrOfLedsOnStrip * 3);
282 AnswerData =
new byte[1];
286 BytesRead = ComPort.Read(AnswerData, 0, 1);
290 throw new Exception(
"A exception occured while waiting for the ACK after sending the data for channel {0} of the TeensyStripController.".Build(i + 1), E);
292 if (BytesRead != 1 || AnswerData[0] != (byte)
'A')
294 throw new Exception(
"Received no answer or a unexpected answer while waiting for the ACK after sending the data for channel {0} of the TeensyStripController.".Build(i + 1));
296 SourcePosition += NrOfLedsOnStrip;
300 CommandData =
new byte[1] { (byte)
'O' };
301 ComPort.Write(CommandData, 0, 1);
304 AnswerData =
new byte[1];
308 BytesRead = ComPort.Read(AnswerData, 0, 1);
312 throw new Exception(
"A exception occured while waiting for the ACK after sending the output command (O) to the TeensyStripController", E);
314 if (BytesRead != 1 || AnswerData[0] != (byte)
'A')
316 throw new Exception(
"Received no answer or a unexpected answer while waiting for the ACK after sending the output command (O) to the TeensyStripController");
364 DisconnectFromController();
366 string[] PortNames = SerialPort.GetPortNames();
367 if (!PortNames.Any(PN => PN == ComPortName))
369 throw new Exception(
"The specified Com-Port '{0}' does not exist. Found the following Com-Ports: {1}. Will not send data to the controller.".Build(ComPortName,
string.Join(
", ", PortNames)));
372 ComPort =
new SerialPort();
373 ComPort.ReadTimeout = ComPortTimeOutMs;
374 ComPort.WriteTimeout = ComPortTimeOutMs;
378 ComPort.PortName = ComPortName;
382 throw new Exception(
"A exception occured while setting the name of the Com-port '{0}'. Found the following Com-Ports: {1}. Will not send data to the controller.".Build(ComPortName,
string.Join(
", ", PortNames)), E);
391 throw new Exception(
"A exception occured while trying to open the Com-port '{0}'. Found the following Com-Ports: {1}. Will not send data to the controller.".Build(ComPortName,
string.Join(
", ", PortNames)), E);
398 ComPort.ReadExisting();
400 bool CommandModeOK =
false;
401 for (
int AttemptNr = 0; AttemptNr < 20; AttemptNr++)
404 ComPort.Write(
new byte[] { 0 }, 0, 1);
406 if (ComPort.BytesToRead > 0)
408 int Ret = ComPort.ReadByte();
412 CommandModeOK =
true;
415 else if (Ret == (
int)
'N')
418 CommandModeOK =
true;
427 ComPort.Write(
new byte[3 * 1000], 0, 3 * 1000);
431 ComPort.ReadExisting();
436 Log.
Exception(
"Could not put the controller on com-port {0} into the commandmode. Will not send data to the controller.".Build(ComPortName));
437 DisconnectFromController();
445 ComPort.Write(
new byte[] { (byte)
'M' }, 0, 1);
446 byte[] ReceiveData =
new byte[3];
451 BytesRead = ReadPortWait(ReceiveData, 0, 3);
455 throw new Exception(
"Expected 3 bytes containing data on the max number of leds per channel, but the read operation resulted in a exception. Will not send data to the controller", E);
461 throw new Exception(
"The TeensyStripController did not send the expected 3 bytes containing the data on the max number of leds per channel. Received only {0} bytes. Will not send data to the controller".Build(BytesRead));
463 if (ReceiveData[2] !=
'A')
465 throw new Exception(
"The TeensyStripController did not send a ACK after the data containing the max number of leds per channel. Will not send data to the controller");
467 int MaxNumberOfLedsPerChannel = ReceiveData[0] * 256 + ReceiveData[1];
469 if (NumberOfLedsPerStrip.Any(Nr => Nr > MaxNumberOfLedsPerChannel))
471 throw new Exception(
"The TeensyStripController boards supports up to {0}} leds per channel, but you have defined up to {1} leds per channel. Will not send data to the controller.".Build(MaxNumberOfLedsPerChannel, NumberOfLedsPerStrip.Max()));
477 NumberOfLedsPerChannel = NumberOfLedsPerStrip.Max();
478 ushort NrOfLeds = (ushort)NumberOfLedsPerChannel;
479 byte[] CommandData =
new byte[3] { (byte)
'L', (byte)(NrOfLeds >> 8), (byte)(NrOfLeds & 255) };
480 ComPort.Write(CommandData, 0, 3);
481 ReceiveData =
new byte[1];
485 BytesRead = ReadPortWait(ReceiveData, 0, 1);
489 throw new Exception(
"Expected 1 bytes after setting the number of leds per channel, but the read operation resulted in a exception. Will not send data to the controller.", E);
492 if (BytesRead != 1 || ReceiveData[0] != (byte)
'A')
494 throw new Exception(
"Expected a Ack (A) after setting the number of leds per channel, but received no answer or a unexpected answer. Will not send data to the controller.");
499 CommandData =
new byte[1] { (byte)
'C' };
500 ComPort.Write(CommandData, 0, 1);
501 ReceiveData =
new byte[1];
505 BytesRead = ReadPortWait(ReceiveData, 0, 1);
509 throw new Exception(
"Expected 1 bytes after clearing the buffer of the TeensyStripController, but the read operation resulted in a exception. Will not send data to the controller.", E);
512 if (BytesRead != 1 || ReceiveData[0] != (byte)
'A')
514 throw new Exception(
"Expected a Ack (A) after clearing the buffer of the TeensyStripController, but received no answer or a unexpected answer. Will not send data to the controller.");
517 CommandData =
new byte[1] { (byte)
'O' };
518 ComPort.Write(CommandData, 0, 1);
519 ReceiveData =
new byte[1];
523 BytesRead = ReadPortWait(ReceiveData, 0, 1);
527 throw new Exception(
"Expected 1 bytes after outputing the buffer of the TeensyStripController to the ledstrips, but the read operation resulted in a exception. Will not send data to the controller.", E);
530 if (BytesRead != 1 || ReceiveData[0] != (byte)
'A')
532 throw new Exception(
"Expected a Ack (A) after outputing the buffer of the TeensyStripController to the ledstrips, but received no answer or a unexpected answer. Will not send data to the controller.");
568 private int ReadPortWait(byte[] Buffer,
int BufferOffset,
int NumberOfBytes)
571 byte[] ReadBuffer =
new byte[1];
572 for (
int ByteNumber = 0; ByteNumber < NumberOfBytes; ByteNumber++)
578 BytesRead = ComPort.Read(ReadBuffer, 0, 1);
581 catch (TimeoutException TE)
583 throw new Exception(
"A TimeoutException occured while trying to read byte {0} of {1} from Com-Port {2}.".Build(ByteNumber + 1, NumberOfBytes, ComPort.PortName), TE);
587 throw new Exception(
"A exception occured while trying to read byte {0} of {1} from Com-Port {2}.".Build(ByteNumber + 1, NumberOfBytes, ComPort.PortName), E);
592 throw new Exception(
"A exception occured while trying to read byte {0} of {1} from Com-Port {2}. Tried to read 1 byte, but received {3} bytes.".Build(
new object[] { ByteNumber + 1, NumberOfBytes, ComPort.PortName, BytesRead }));
595 Buffer[BufferOffset + ByteNumber] = ReadBuffer[0];
599 return NumberOfBytes;
override void ConnectToController()
This method is called when DOF wants to connect to the controller.
The TeensyStripController is used to control up to 8 WS2811/WS2812 based ledstrips with up to 1100 le...
override void DisconnectFromController()
Disconnects from the controller.
static void Warning(string Message)
Writes a warning message to the log.
override bool VerifySettings()
Verifies if a valid ComPortName has been set and if the number of outputs per channel is >=0...
override void UpdateOutputs(byte[] OutputValues)
This method is called whenever new data has to be sent to the output controller. Implement the commun...
A simple logger used to record important events and exceptions.
This abstract class implement the full base logic for a output controller with a separate thread for ...
void SetupOutputs()
Manages to output object of the output controller. Use the GetNumberOfConfiguredOutputs() method to d...
override int GetNumberOfConfiguredOutputs()
This method returns the sum of the number of leds configured for the 8 output channels of the Teensy ...
static void Exception(string Message, Exception E=null)
Writes a exception message to the log.