Jump to content
Corsair Community

HowTo: HD120 RGB Custom Lighting Controller

Recommended Posts


This is currently a DO IT YOURSELF project working with low voltage and sensitive electronics. This is not in any way endorsed by Corsair and will probably void the living bajeebers out of your warranty. And the dead bajeebers too.


In the current state, some knowledge of electrical work and safety is necessary.


In short: Know stuff or you might break things, including yourself.





October 11, 2019 Update

After not committing any code for all this time, I am sunsetting this project. The code will remain available for anybody who wants to use it or improve on it. I may pick it back up in the future (would that make it a new day?) but at this point I do not foresee doing so now that Corsair has capable controllers available in retail.


I applaud the folks at Corsair for coming out with a highly-capable controller. After hearing from somebody who worked there and went on to become my coworker afterward ("Wait, YOU'RE Kitdragon?!"), I'm happy I was able to provide inspiration to your teams for the project. Keep up the awesome work, design cool new things, and have fun!


January 4, 2018 Update

The thread is getting Very Long, so this portion consolidates some of the information.

  • The project should use a "Leonardo" style Arduino. The chip on that kind of board has integrated UART handling and will not drop serial information. While other Arduino boards may work, if you encounter problems with them, I will simply advise you to use a supported board. Appropriate boards are, for example, the Pro Micro or Beetle board, basically anything sporting an ATMega32u4 AVR.
  • You (currently) will need to know how to compile and upload sketches to the Arduino. Knowing how to do small (or large) changes to sketches is also strongly recommended.
  • The firmware I developed is located at https://github.com/Charixfox/HD120-Controller. Ongoing development is occurring (very) slowly.
  • The Ground and Data pins are the only pins that should be connected between the Arduino and the LED hub. Connecting the 5V is a Bad Idea with most motherboards these days.
  • There are a few PC programs that have been developed by other users on their own time to communicate with the firmware. One such is at http://forum.corsair.com/forums/showpost.php?p=924826&postcount=190 on this thread.
  • I absolutely suck at video editing, so I have not yet successfully made an instructional video.
  • If the fans light up at all, something worked right. The LEDs will not light if they get only power and no signal. Getting them to light up The way you want requires a USB connection to the computer.
  • Since this project first started, Corsair did finally come out with a few controllers that are less-sucky. The Lighting Node Pro and Commander Pro work with Link to do blinkenlights.
  • No, I will not ever support or advocate "Temperature-based lighting" for one very simple reason: This project is meant to have INTERESTING, FLASHY lighting. Like RGB Overload. Temperature-based colors have the following: One color. If it changes, your computer is going to die. That is not interesting or flashy. That is "Not dying" or "Dying-so-I-Don't-Want-To-See-This". This doesn't stop anybody else from making a system that will send commands to interrupt the normal operation of the lights and make them scary-colored when your computer is burning parts of itself up.
  • All of the above are mutable due to the fact that there is rarely such a thing as "Not possible" or "never" or "always". Can it be done? Maybe. Will it be worth it? Maybe. Will it be easy or difficult? Maybe.


January 30, 2017 Update

Current Status:

- I have installed an Arduino Pro Micro into the housing for the original controller and stolen the original controller's cable. This unit is a good size and has some advanced capability for future use. The Arduino is connected to the hub and to a Micro USB to Motherboard Header cable.

- Code for simple firmware for the Arduino is located at https://github.com/Charixfox/HD120-Controller and I will hopefully be able to work more on this moving forward. The person who has the fans installed in her case right now is perfectly happy with Angry Myia Mode (don't ask about the name. Just don't. It has to do with Blue Fizzies being stabbed to death) so development and testing is somewhat hindered by no longer having easy access to the hardware and I'm reluctant to invest another $90 or $180 in three to six more fans just to code more things that might never be used.

- With a small bit of effort this project -can- technically be done without solder. The structural integrity is not guaranteed however.



SP120 RGB fans are fan-addressable UCS1903 controller chips, so with some minor code changes, the same or similar code can be used on them.


More things coming soon!


Original information

I'm not the first person to try to figure out what's going on with the HD120 RGB fans and their beautiful LEDs, but the other person who did apparently posted asking if he could say it and then never returned. Sadness was the result.


First, the basic findings so far...


When I saw that the lighting was 12 Individually-Addressable RGB LEDs, my heart lit up and I got excited. Individually-addressable means that each one could have its own color and be at my every whim! However the basic controller that comes with it is rudimentary to say the least (when being kind to it).


I tried some searching in various places and, as usual, Google thought it was going to be smart and guessed what I meant, then fed me the most advertisingliscious results it could. And here on these forms, well, I told the story above.


Right. Time to take matters into my own hands and open up some stuff. We'll skip the mistakes I made and get right into the results. One of the things I needed to determine was what kind of LED packages were used in the lighting system. There are two common Digitally-Individually-Addressable (DIA) LED systems that exist today, so I hoped that it would be one of those. The two are WS2812 (which is a single SMC package that contains a WS2811 controller and RGB LEDs in one package) and APA102.


The normal Controller for this fan set has two parts: The hub that six fans and the "remote" module plug into, and the remote module that has buttons on it to change the Mode, Color, and Speed.


The fan itself has two separate 4-Pin IIC female connectors. One is a normal double-thick block 4-Pin PWM 12V fan connector. The other is a clip-bearing 4-Pin LED Lighting connector.



The fan works on 12V PWM.

The LEDs work on 5V and single-line digital serial.


The fact that there were four pins instead of six combined with the "You must connect the fans to the ports in order for the lights to all work" to tell me that the candidate was WS2812. Not quite as capable as APA102s, but half the cost and less-complex.


The next bit of fun was getting into the control modules. Four screws on the hub and two on the button remote, both under the sticky pads. This contained the important information that strengthened some of my suspicions.


The hub takes +5v and Ground from the SATA connector to power the controller and the LEDs. The remote has three wires going to the hub, so either it had to be using a digital signalling to logic hardware in the hub or the logic hardware had to be in the remote. Turns out it's in the remote. One ATMEL 2mbit EEPROM and an unmarked 8-pin processor chip work with 5V and Ground and have a single line out for the digital data signal.


Each port on the hub has +5V and Ground, and then Data Out (from the hub to the fan) and Data In (From the fan to the hub so it can be passed to the next fan). The data signal from the remote is passed to Port 1 on the hub, then the Data In (I prefer to call Data Return) on the port is passed to the Data Out on the next port, and so on through all six.


Pinout for the LED connector on the fan -WIRES TOWARDS YOU, CLIP FACING UP-:

Ground Data Out Data Return +5V


That's part of the important part.


(This means that plugging this into a 12V PWM Fan controller will fry it like a doughnut. Mmmm... Doughnuts... Blah, now I want doughnuts.)


Next up, an Arduino Mega 2560 was loaded up with FastLED and advised that this was WS2811 Control type, 12 LEDs, and GRB. A basic "demo/test pattern" program was loaded onto the Arduino.


In summary, some wiring with pins, some resistors (for safety), a nice big capacitor (also for safety) and a 5V power supply later and...


Success! Muahahahahahahaha!


The LEDs are most likely WS2812 SMC modules and at least are communication-compatible with such.


I did note that the LED arrangement on the HD120s is... slightly evil. *Sigh*


12 LEDs can be best arranged "on the hour" or "on the half hour". These are "On the half hour", so there are three on each quarter of the ring, and consider them "In the hour" of the full hour before them. This allows the break between two colors to be on the hour.


Addressing them though, looking at the back of the fan, upright (Labeled sticker will be upright and cables come in to the upper section of the left side)...

LED 1 is at the 10:30 position. So 1 and 2 are on the upper left, followed by 3-8 on the right, going clockwise (when looking at the back, so counter-clockwise and on the left when looking at the front), then 9-12 bringing up the left and finishing at 9:30.This means programmatically aligning things in the quadrants becomes more of a pain since it isn't easily split into 1-3, 4-6, 7-9. 10-12.


Image courtesy of timr:



There is no "plug detection". No way to know whether a port has a fan plugged in. So any custom control needs to be specifically set to have the correct number for the fans that you have, or 72 max.


The LEDs HAVE NO DEFAULT COLOR WHEN POWERED ON. Their default is "off", so without data, nothing!


I'm going to go ahead and try to get some video of the work here, as well as see if I can put together a full 6-fan array and get video of that.


Got questions? Ask! I'll answer if I can. ^.^


Edit April 24 2017:

Realized I should put the new version video here. This is a much-newer version than the video in the next post down. Enjoy!


[/ame] Edited by Charixfox
Sunset October 11 2019
  • Confused 1
Link to comment
Share on other sites

  • Replies 271
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Next segment of progress...


I have gotten some Arduino Mini Pros (they cost about $7 each) and a Mobo header to USB Micro and made everything work on that. The original controller guts have been removed from the plastic housing and after a few small bits of plastic coming out to make space and some soldering on the board (I really should have put some strain relief on it, so hopefully I won't move it around too much inside the system) I now have a little controller box with only one screw out of two (ahh well) and a USB connection instead of working buttons. :)


It can technically run one fan's lights off USB power alone if I keep the intensity limited to 37.5% (96/256 brightness) but can't run two unless I reduce the brightness to about 30% (76/256). The SATA power connector -must- be connected and powered up first if more than 500mA of power is drawn or it'll very happily fry the controller board from trying to power too many lights from the USB. No way around that that I know of unfortunately. T^T )


Next comes some coding into the controller to make it Do Things. I'm making use of the FastLED library and will be using normal serial connections to the computer at the moment for control. This means no "User Friendly" control method yet unfortunately. In the future I might explore Node-Pixel but the idea of a web page controlling the case lighting is actually kind of creepy. <.<

Link to comment
Share on other sites

if more than 500mA of power is drawn


USB 3.0 can supply 900ma and maybe you can tell you are connected to a USB 3.0 port.


I guess I should get the bits and then get SIV to talk to it. What do I need and how would I download your firmware?

Link to comment
Share on other sites

USB 3.0 can supply 900ma and maybe you can tell you are connected to a USB 3.0 port.


500mA draw off the USB port is a limitation of the Arduino, not the USB port.


Just to put things in perspective, each LED at full brightness will draw 60mA, so one fan at full brightness, full white would be 720mA. Six fans at bright white would be 4,320mA, and even those 3A "Super-Power USB" ports would be overloaded.


I guess I should get the bits and then get SIV to talk to it. What do I need and how would I download your firmware?


Parts-wise in use:

- Kookye Micro Pro Arduino clone (Amazon or other supplier)

- Three blobs of solder to connect the three-wire cable that I cannibalized from the original controller

--- Ground to GND, +5 to RAW (Since power will be coming -in- on the cable), Data to Pin 3


Firmware-wise isn't fully developed yet. I've only run the "100-line demo" code from the FastLED examples. I'm still trying to decide how to best do this. So you'd need the Arduino IDE (from arduino.cc, not arduino.org) and use the library manager to install the FastLED library.


I have to test a thing that might correct the odd LED mapping and if it works (It would be using an undocumented behavior of the FastLED library) then I'll have some good info.


I had two options on the main loop on the controller:

1: Autonomous.

- Check for serial data for wake and send ACK if got wake

-- Receive new directions and modified stored flags

- Use stored flags or Progmen default to change LED values.

- Remap the stupid alignment (if possible - still haven't checked)

- Display the things and go back to the top.


2: 100% Software Controlled

- Wait for monolithic packet of LED data because the computer does all the fancy calculations and just sends a string of data over serial

-- If the packet isn't broken, put it into the pixel data.

- Display the things and go back to the top

Link to comment
Share on other sites

Thank you for the information. I think the sensible option is to power the LEDs from the SATA connector as they are by default.


What device does Windows see this as? Is http://www.ebay.co.uk/itm/141962370191 what I need? I guess I should get a couple, plug them in and look.


I was hoping for a HID device and ideally I would send the usual 64 byte HID packet with RGB values for the LEDs I wished to change. I was thinking in terms of a 4 byte header:

  1. Protocol Version - 0x10 - V1.0
  2. Reserved or maybe checksum
  3. Packet type - 1 set LED colours
  4. Count of per LED data blocks - 1 to 15 though I suspect I would only send up to 12.

and then up to 15 x 4 byte per LED data blocks:

  1. LED index (0 to 71)
  2. LED Red Value
  3. LED Green Value
  4. LED Blue Value

I just got the IDE from https://www.arduino.cc/en/Main/Software

Edited by red-ray
just got the IDE
Link to comment
Share on other sites

IIRC, the PWM is out of phase so alternates between colors, since there is a similar thing that is sold that uses the same LEDs in a 30-LED strip and runs wholly off USB.


Yes, that EBay listing is precisely what I got off Amazon. In my case, it was Amazon US and five of them for $28.


And yes, it looks like they might be able to be HID.

Link to comment
Share on other sites

Perhaps rather than using four bytes per LED, perhaps have a fan ID (offest = fanID * 12 on the controller side) followed by plain old 3-byte 0-11. This allows you to not spend as much transfer and address only fans that you want to change, though you can't fit two fans into the mix.


One very important thing to consider is that when writing out to the LEDs, IIRC the controller will drop all data sent to it while it turns off interrupts to write out, so do keep that in mind.

Link to comment
Share on other sites

Assuming we can make the device HID then the transfer rate should be 12Mb/sec so saving the odd byte in a packet has little benefit. I also suspect I will wish each LED to be a different colour so as things get hotter more and more LEDs will change from say Blue to Green to Red.


To deal with interrupts being disabled I am inclined towards:

  1. Receive the setup packet
  2. Disable Interrupts
  3. Write to the LEDs
  4. Enable Interrupts
  5. Send a success/fail packet.

It's also possible if we can use HID rather than virtual COM port there will not be a data overrun issue at all.


I would also like a method to request the firmware version.


I assume we could connect such as http://www.ebay.co.uk/itm/132030120812 WS2811 5050 RGB LEDs or http://www.ebay.co.uk/itm/262559814200 WS2812B 5050 RGB LEDs, am I correct and which one?


I adjusted the SIV code and most of the support is now there. To test it I used a Corsair Link PMBus Bridge (old Link Commander) to pretend to be the Micro Pro Arduino. I found one device with 72 fans to be cumbersome, so I presented it as 6 fans each with 12 LEDs. All I need now is some hardware to arrive and some firmware.



Edited by red-ray
SIV screen shots
Link to comment
Share on other sites

The bottleneck will be the Arduino AVR. Tight and efficient code is important in that. Limited memory space and program space. About 27kb free for code and 2.5kb of RAM, and the processor runs at a whopping 16 MHz.


Looks like other folks have fought to make the Arduino Micro accept data from the computer on HID. The core Arduino library has the USB functionality and it normally doesn't handle PC -> Device HID. Somebody did some modifications at http://forum.arduino.cc/index.php?topic=256542.0 to get it to be otherwise.


With the FastLED library, the LED write command is a blocking command that disables interrupts, so just a plain old FastLED.show() will handle the interrupts, writing to the LEDs and then re-enabling the interrupts afterward. You could definitely do this manually if you like. Folks have determined some much simpler code to handle writing out to these kinds of LEDs that takes advantage of the wiggle room in the protocol to allow interrupts to occur if the handler is fast enough and such.


I'll have to look up the specs on the Micro. The USB handling is built into the AVR so it might not suffer from the single-byte serial buffer that others do. In retrospect, this makes the extra $2 for the Micro a better solution than the Nano as well.


Use the WS2812B when possible. The control chips are the same, but the package integrity and reliability is better. Either one would work though technically.


A chunk of my goal is to get things working for interesting lighting more than temperature indication. On a good day, temp indication lighting should be pretty boring. So things like spinners, multi-fan coordination, cross fades, possibly sound-based things or whoknowswhat. In my case, the spirit is willing, but the code is weak. <.<

Link to comment
Share on other sites

Where did you get the Windows driver from please? Thus far I have not found one for Windows 7 x64 SP1 or any other version of Windows. I tried as per https://www.arduino.cc/en/Guide/DriverInstallation with no luck. Does dism /online /get-drivers /format:table list any Arduino drivers and if so what is the .INF file called.


When I plugged the device in I checked the USB interface descriptors' with SIV and it has a HID one :sunglasse. Do you devices report the same interfaces?


The USB firmware is slightly dodgy and I suspect would fail https://msdn.microsoft.com/en-gb/library/windows/hardware/dn423380(v=vs.85).aspx. This is all too common and my H80iGT Cooler is similar.




Edited by red-ray
Link to comment
Share on other sites

Normally when you install the Arduino IDE, it will prompt to install several device drivers manually with the "Are you Suuuuuure you trust these people?!" warnings that Windows gives. If these are missed and time out, declined, or otherwise not-done, it won't be happy. Directions for manual installation are included at:


Interpolate the installation location, since the guide was made back when it installed under the user directory, which it does not always do anymore.


The USB will normally present itself as a Serial port unless/until you open other USB functions on the AVR using firmware code. Check Windows Device Manager -> Ports when it is plugged in to see if it's expressing.


I'm going to to edit the original thread and see if I can change the title. This is not really a how-to yet.

Link to comment
Share on other sites

I'm going to to edit the original thread and see if I can change the title. This is not really a how-to yet.


You can't, only admins can change the thread title after it's created. You can change the first post title, but not the thread title.


I tried as per https://www.arduino.cc/en/Guide/DriverInstallation with no luck.

Does dism /online /get-drivers /format:table list any Arduino drivers and if so what is the .INF file called.


I have already done as in the thread you specified and as I specified this did not work.


What does dism report on your system please?


I just extracted the .ZIP file rather than installing as I did not and do not what it installing lots of things on my system.

Edited by red-ray
Link to comment
Share on other sites

I had no problem changing the title.:)


Anyway, if you just grabbed the zip file, it contains a single directory arduino-1.8.1 that contains a subdirectory drivers. Unfortunately I'm on Windows 10 and I don't have any Windows 7 machines handy to test against.


Arduino-related hardware drivers:


oem65.inf | arduino-org.inf | No | Ports | Arduino Srl (http://www.arduino.org) | 2/27/2014 |

oem66.inf | adafruitcircuitplayground.inf | No | Ports | Adafruit Industries LLC | 2/25/2016 | 6.2.2600.0

oem67.inf | arduino_gemma.inf | No | libusb-win32 devices | libusb-win32 | 4/21/2015 |

oem68.inf | genuino.inf | No | Ports | Arduino LLC (http://www.arduino.cc) | 10/25/2015 |

oem71.inf | arduino-org.inf | No | Ports | Arduino Srl (http://www.arduino.org) | 3/19/2015 |

oem72.inf | arduino.inf | No | Ports | Arduino LLC (http://www.arduino.cc) | 11/24/2015 |

oem73.inf | genuino.inf | No | Ports | Arduino LLC (http://www.arduino.cc) | 1/7/2016 |

oem74.inf | linino.inf | No | Ports | Linino | 1/13/2014 |


All of the above are located in the drivers directory. The Leonardo/Micro specifically uses:

oem72.inf | arduino.inf | Arduino LLC (http://www.arduino.cc) | 11/24/2015 |


Also keep in mind that if the bootloader is faulty or the hardware is faulty it won't show. That's why I usually try to avoid eBay for AVRs.

Link to comment
Share on other sites

You can change the first post title, but not the thread title.
I had no problem changing the title.:)


You have changed the post title, not the thread title which is still "HowTo: HD120 RGB Custom Lighting Controller".


Thank you for the name of the .INF file. Once I knew this I managed to force install a driver. The reason it did not automatically install is that there is a bug in the .INF file. It contains:


%leonardo.sketch.name%=DriverInstall, USB\VID_2341&PID_8036&MI_00


When it should contain:


%leonardo.sketch.name%=DriverInstall, USB\VID_2341&PID_8036


I suspect I will develop and sign my own installation files.


As to why it worked on W10 I don't as yet know and will check once I boot up my W10 x64 RS2 Build 15014 system

Link to comment
Share on other sites

Need I say more given the two images?


On W10 I did not need to install any drivers at all.


Windows 7 x64 Ultimate V6.01 Build 7601 SP1




Windows 10 x64 Professional V10.00 Build 15019 RS2





Edited by red-ray
Fix images
Link to comment
Share on other sites

Weird Forums are Weird. :)


I can see the images now. Wouldn't it be nice if computers Just Worked?


The basic build on my side is installed in a 570X RGB case because the person I was programming it for got impatient, so there are only two basic functions so far and fan control is through serial monitor. <.< It's all kind of fun trying to squeeze everything into 28.8k of code and 2.5k of RAM.


How goes progress on your side?

Link to comment
Share on other sites

Yes. I suspect it was down to finger trouble. At this end I have not done much, I got distracted adding Corsair Vengeance LED DIMM LED control support to SIV and then by X99/X79 system IMC SMBus TSOD/CLTT issues.


I should have some time tomorrow and wonder please can I try you firmware? I am also none too sure what I need to do to load it and any pointers would be good.


Which pin is the LED control pin?

Link to comment
Share on other sites

The LED Control pin will be the digital pin that you connect the LED Data line to on the Arduino.I'll see about posting my firmware to git.


As for loading the firmware, that is an Arduino question, but I'll summarize here:

Run Arduino IDE

Under Tools -> Board: Select Arduino Leonardo (for the Micro or Pro Micro)

Connect board to computer via USB

Under Tools -. Port: Select correct serial port for board


Place sketch (firmware program code) into code window


The firmware requires the FastLED Library. Sketch Menu -> Include Library -> Manage Libraries

"Filter your search" for FastLED and click it, then Install.



Personally, I always Verify first (Which just compiles it)

Click "Upload Sketch" to compile it and upload it to the Arduino.


Change code portions if needed (for example, the data pin is defined as 3, but if you physically connect it to pin 4, use that instead)


You might want to consider trying the Arduino Basics "Blink" Tutorial for basic firmware understanding. :)

Link to comment
Share on other sites

This thread is exactly what I was looking for!


Do the SP120s have the same controller as the HDs? I can't seem to locate that info anywhere.


Also, below is a link to a diagram that shows the LED positions on the HDs (because it's easier to understand the weird layout visually than reading through the explanation).



Link to comment
Share on other sites

  • Create New...