DreamCheekyLED.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using System;
  2. using System.Diagnostics;
  3. using System.Threading;
  4. using HidSharp;
  5. using System.Collections.Generic;
  6. namespace DreamCheekyUSB {
  7. public class DreamCheekyLED : LEDBase {
  8. #region Constant and readonly values
  9. public const int DefaultVendorID = 0x1D34;
  10. public const int DefaultProductID = 0x0004;
  11. //Colors are capped at 60, so scale accordingly
  12. //Initialization values and test colors
  13. public const byte MaxColorValue = 60;
  14. public static readonly byte[] Init01 = { 0x1F, 0x02, 0x00, 0x5F, 0x00, 0x00, 0x1F, 0x03 };
  15. public static readonly byte[] Init02 = { 0x00, 0x02, 0x00, 0x5F, 0x00, 0x00, 0x1F, 0x04 };
  16. public static readonly byte[] Init03 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
  17. public static readonly byte[] Init04 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
  18. public static readonly byte[] CmdRed = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
  19. public static readonly byte[] CmdGreen = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
  20. public static readonly byte[] CmdBlue = { 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0x05 };
  21. public static readonly byte[] CmdOff = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
  22. #endregion
  23. private AutoResetEvent WriteEvent = new AutoResetEvent(false);
  24. private bool IsUnix;
  25. #region Constructors
  26. /// <summary>
  27. /// Default constructor. Will used VendorID=0x1D34 and ProductID=0x0004. Will throw exception if no USBLED is found.
  28. /// </summary>
  29. /// <param name="deviceIndex">Zero based device index if you have multiple devices plugged in.</param>
  30. public DreamCheekyLED(int deviceIndex = 0) : this(DefaultVendorID, DefaultProductID, deviceIndex) {
  31. }
  32. /// <summary>
  33. /// Create object using VendorID and ProductID. Will throw exception if no USBLED is found.
  34. /// </summary>
  35. /// <param name="vendorID">Example to 0x1D34</param>
  36. /// <param name="productID">Example to 0x0004</param>
  37. /// <param name="deviceIndex">Zero based device index if you have multiple devices plugged in.</param>
  38. public DreamCheekyLED(int vendorID, int productID, int deviceIndex = 0) {
  39. Trace.WriteLine("Instantiating HidDeviceLoader...");
  40. Loader = new HidDeviceLoader();
  41. Trace.WriteLine(String.Format("Enumerating HID USB Devices (VendorID {0}, ProductID {1})...", vendorID, productID));
  42. var devices = new List<HidDevice>(Loader.GetDevices(vendorID, productID));
  43. if (deviceIndex >= devices.Count) {
  44. throw new ArgumentOutOfRangeException("deviceIndex", String.Format("deviceIndex={0} is invalid. There are only {1} devices connected.", deviceIndex, devices.Count));
  45. }
  46. HidLED = devices[deviceIndex];
  47. if (!init()) {
  48. throw new Exception(String.Format("Cannot find USB HID Device with VendorID=0x{0:X4} and ProductID=0x{1:X4}", vendorID, productID));
  49. }
  50. }
  51. /// <summary>
  52. /// Create object using Device path. Example: DreamCheekyLED(@"\\?\hid#vid_1d34&pid_0004#6&1067c3dc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}").
  53. /// </summary>
  54. /// <param name="devicePath">Example: @"\\?\hid#vid_1d34&pid_0004#6&1067c3dc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"</param>
  55. public DreamCheekyLED(string devicePath) {
  56. Trace.WriteLine("Instantiating HidDeviceLoader...");
  57. Loader = new HidDeviceLoader();
  58. Trace.WriteLine("Enumerating all USB Devices...");
  59. var devices = Loader.GetDevices();
  60. Trace.WriteLine("Searching for device at {0}...", devicePath);
  61. foreach (var device in devices) {
  62. Trace.WriteLine("Enumerating all USB Devices..."+ device.DevicePath);
  63. if (device.DevicePath.Contains("vid_1d34")) {
  64. HidLED = device;
  65. }
  66. }
  67. if (!init()) {
  68. throw new Exception(String.Format("Cannot find USB HID Device with devicePath={0}", devicePath));
  69. }
  70. }
  71. /// <summary>
  72. /// Private init function for constructors.
  73. /// </summary>
  74. /// <returns>True if success, false otherwise.</returns>
  75. private bool init() {
  76. WriteEvent.Reset();
  77. if (HidLED == default(HidDevice)) {
  78. return false; //Device not found, return false.
  79. }
  80. //Device is valid
  81. Trace.WriteLine("Init HID device: " + HidLED.ProductName + "\r\n");
  82. return true;
  83. }
  84. #endregion
  85. /// <summary>
  86. /// Sends initialization commands to USB LED device so it is ready to change colors. LED will be turned off after calling Initialize.
  87. /// NOTE: Write command will automatically call Initialize.
  88. /// </summary>
  89. /// <returns>True if successfull, false otherwise</returns>
  90. internal override bool Initialize() {
  91. DeterminePlatform();
  92. bool bReturn = base.Initialize();
  93. if (bReturn) {
  94. //Note: Write will automatically open the device if needed.
  95. bReturn &= Write(Init01);
  96. bReturn &= Write(Init02);
  97. bReturn &= Write(Init03);
  98. bReturn &= Write(Init04);
  99. }
  100. return bReturn;
  101. }
  102. private void DeterminePlatform() {
  103. var platform = Environment.OSVersion.Platform;
  104. IsUnix = ((platform == PlatformID.MacOSX) || (platform == PlatformID.Unix));
  105. Trace.WriteLineIf(IsUnix, "Running on UNIX-like OS...");
  106. Trace.WriteLineIf(!IsUnix, "Running on Windows...");
  107. }
  108. public override bool Write(byte[] data) {
  109. if (!initialized) {
  110. Initialize();
  111. }
  112. Trace.WriteLine("\r\nWriting Data: {0} ", BitConverter.ToString(data));
  113. if (IsUnix) {
  114. Stream.Write(data);
  115. } else {
  116. var windowsData = new byte[9];
  117. data.CopyTo(windowsData, 1);
  118. Stream.Write(windowsData);
  119. }
  120. return true;
  121. }
  122. public override bool SetColor(System.Drawing.Color color) {
  123. Trace.WriteLine("\r\nSetColor: {0}", color.Name);
  124. return SetColor(color.R, color.G, color.B);
  125. }
  126. /// <summary>
  127. /// Set color using RGB. Values should range 0-255 and will be scaled to match USBLED output.
  128. /// </summary>
  129. /// <param name="red">0-255</param>
  130. /// <param name="green">0-255</param>
  131. /// <param name="blue">0-255</param>
  132. /// <returns>True if sucessfull</returns>
  133. public override bool SetColor(byte red, byte green, byte blue) {
  134. Trace.WriteLine(String.Format("\r\nSetColor (RGB): ({0},{1},{2})", red, green, blue));
  135. byte[] data = CmdOff.Clone() as byte[];
  136. // var t = (byte)(((float)Red / 255F)*60F);
  137. //Scale color values
  138. data[0] = ((byte)(((float)red / 255F) * MaxColorValue));
  139. data[1] = ((byte)(((float)green / 255F) * MaxColorValue));
  140. data[2] = ((byte)(((float)blue / 255F) * MaxColorValue));
  141. return Write(data);
  142. }
  143. }
  144. }