DreamCheekyLED.cs 6.9 KB

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