2 using System.Collections.Generic;
5 using DirectOutput.General.Generic;
6 using System.Threading;
8 namespace DirectOutput.Cab.Out.AdressableLedStrip
26 #region ISupportsSetValues Member
33 public void SetValues(
int FirstOutput, byte[] Values)
35 if (FirstOutput >= LedData.Length)
return;
36 if (FirstOutput < 0)
return;
37 int CopyLength = (LedData.Length - FirstOutput).Limit(0, Values.Length);
38 if (CopyLength < 1)
return;
42 Buffer.BlockCopy(Values, 0, LedData, FirstOutput, CopyLength);
43 UpdateRequired =
true;
50 private byte[] LedData =
new byte[0];
52 private byte[] OutputLedData =
new byte[0];
55 private int _ControllerNumber = 1;
63 public int ControllerNumber
65 get {
return _ControllerNumber; }
66 set { _ControllerNumber = value; }
70 private int _NumberOfLeds = 1;
78 public int NumberOfLeds
80 get {
return _NumberOfLeds; }
83 _NumberOfLeds = value.Limit(0, 4006);
84 LedData =
new byte[_NumberOfLeds * 3];
85 OutputLedData =
new byte[_NumberOfLeds * 3];
92 private object UpdateLocker =
new object();
93 private bool UpdateRequired =
true;
100 private readonly
int[] ColNrLookup = { 1, 0, 2 };
109 IOutputNumbered ON = (IOutputNumbered)Output;
110 int ByteNr = ON.
Number - 1;
111 ByteNr = (ByteNr / 3) * 3 + ColNrLookup[ByteNr % 3];
119 if (LedData[ByteNr] != ON.
Value)
121 LedData[ByteNr] = ON.
Value;
122 UpdateRequired =
true;
129 Log.
Exception(
"WS2811StripController {0} with number {1} has received a update with a illegal or to high output number ({2}).".Build(Name, ControllerNumber, ON.
Number), E);
136 private void AddOutputs()
138 for (
int i = 1; i <= NumberOfLeds * 3; i++)
142 Outputs.Add(
new LedStripOutput() { Name =
"{0}.{1}".Build(Name, i), Number = i });
158 Log.
Write(
"WS2811StripController {0} with number {1} initialized and updaterthread started.".Build(Name, ControllerNumber));
165 public override void Finish()
167 FinishUpdaterThread();
168 Log.
Write(
"WS2811StripController {0} with number {1} finished and updaterthread stopped.".Build(Name, ControllerNumber));
174 public override void Update()
178 UpdaterThreadSignal();
184 #region UpdaterThread
189 private void InitUpdaterThread()
192 if (!UpdaterThreadIsActive)
194 KeepUpdaterThreadAlive =
true;
197 UpdaterThread =
new Thread(UpdaterThreadDoIt);
198 UpdaterThread.Name =
"WS2811StripController {0} named {1} updater thread ".Build(ControllerNumber, Name);
199 UpdaterThread.Start();
203 Log.
Exception(
"WS2811StripController {0} named {1} updater thread could not start.".Build(ControllerNumber, Name), E);
204 throw new Exception(
"WS2811StripController {0} named {1} updater thread could not start.".Build(ControllerNumber, Name), E);
213 private void FinishUpdaterThread()
215 if (UpdaterThread != null)
219 KeepUpdaterThreadAlive =
false;
220 lock (UpdaterThreadLocker)
222 Monitor.Pulse(UpdaterThreadLocker);
224 if (!UpdaterThread.Join(1000))
226 UpdaterThread.Abort();
228 UpdaterThread = null;
232 Log.Exception(
"A error occured during termination of WS2811StripController updater thread.", E);
233 throw new Exception(
"A error occured during termination of WS2811StripController updater thread.", E);
242 public bool UpdaterThreadIsActive
246 if (UpdaterThread != null)
248 if (UpdaterThread.IsAlive)
260 private void UpdaterThreadSignal()
263 lock (UpdaterThreadLocker)
265 Monitor.Pulse(UpdaterThreadLocker);
270 private Thread UpdaterThread {
get;
set; }
271 private object UpdaterThreadLocker =
new object();
272 private bool KeepUpdaterThreadAlive =
true;
277 private WS2811StripControllerApi Controller = null;
282 private void UpdaterThreadDoIt()
284 if (Controller == null)
286 Controller =
new WS2811StripControllerApi(ControllerNumber);
287 if (!Controller.DeviceIsPresent)
289 Log.
Warning(
"WS2811 Strip Controller Nr. {0} is not present. Will not send updates.".Build(ControllerNumber));
295 OutputLedData.Fill((byte)0);
296 if (Controller != null)
298 Controller.SetAndDisplayData(OutputLedData);
300 while (KeepUpdaterThreadAlive)
307 UpdateRequired =
false;
309 Buffer.BlockCopy(LedData, 0, OutputLedData, 0, LedData.Length);
312 if (Controller != null)
315 Controller.SetAndDisplayData(OutputLedData);
319 if (KeepUpdaterThreadAlive)
321 lock (UpdaterThreadLocker)
323 while (UpdateRequired ==
false && KeepUpdaterThreadAlive)
325 Monitor.Wait(UpdaterThreadLocker, 50);
332 OutputLedData.Fill((byte)0);
333 if (Controller != null)
335 Controller.SetAndDisplayData(OutputLedData);