Mi-Light/Limitless LED are a type of RGB(W) LED lamps with standard light bulb sockets and a proprietary 2.4GHz radio control protocol
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
Okay, I've created some github projects and pushed my source so far. This is only what I have now, but I intend to make it usable.
First up: https://github.com/henryk/milight-reverse-engineering simply contains all the little tools and some of the notes I developed while doing the actual reverse engineering. I don't believe that it's useful to anyone, but you never know. This is totally undocumented and unsupported, and in some cases has commented-out functionality from different phases of the process. YMMV.
Then there's my currently most stable code in https://github.com/henryk/openbeacon-ng/tree/openmili (in firmware/nRF51/pca10031-openmili). This is actually the openbeacon-ng project by my friend Milosch Meriac, but it does have a build system for the nRF51 that is not as full-on retarded as the official Nordic SDK, and also allows for easier code sharing. At some point this should somehow move into the actual project described next.
Finally, there's the OpenMili project: https://github.com/henryk/openmili. This is supposed to be the actual project that people want to use. I have a grand mental plan, but there's only the Arduino proof-of-concept code in there as of now.
The idea is to have proper layers of abstraction and build upon them, allowing mix-and-match as needed. Some of the comments on this http://hackaday.io project indicated that they were/are working along similiar lines, but do have a real PL1167 (or compatible). So the middle layer will be a virtual PL1167 abstraction, that can either shell out to a real PL1167 (I may need help here, since I don't have one to test on) or an emulation on a Nordic chip. As I've said before I want support for both the nRF51[48]22 and nRF24L01(+) chips on the layer below that. Above that would be a thin shell for Mi-Light 2.4GHz frames so that a simple serial protocol will allow to make useful use of the hardware from a host application. Then the first primary goal is to have a host application that fully replaces a Mi-Light Wi-Fi gateway, possibly with slightly better timing, and, most importantly, configurable IDs. (First idea: open multiple UDP ports, each port will send with a different ID; Second idea: also open TCP ports for reliable communication.)
Then, far off in the future I see the possibility of a more advanced firmware implementation with vastly improved timing and features: interleaving multiple commands to different bulbs when sending, maybe performing color animations autonomously, receiving and reporting commands sent by other remotes when idle.
When entering a short test sequence on my remote this is what my receiver displays (a dot means an exact repetition of the previous packet):
All on: 07 B0 F2 EA 35 90 01 B9 AC F9 .......................... 07 B0 F2 EA 35 90 00 B9 74 E0 .. Color red: 07 B0 F2 EA 04 90 0F BA 6E 01 07 B0 F2 EA 04 90 0F BB E7 10 07 B0 F2 EA 04 90 0F BC 58 64 07 B0 F2 EA 04 90 0F BD D1 75 07 B0 F2 EA 04 90 0F BE 4A 47 07 B0 F2 EA 04 90 0F BF C3 56 07 B0 F2 EA 04 90 0F C0 B3 DD 07 B0 F2 EA 04 90 0F C1 3A CC 07 B0 F2 EA 04 90 0F C2 A1 FE 07 B0 F2 EA 04 90 0F C3 28 EF 07 B0 F2 EA 04 90 0F C4 97 9B 07 B0 F2 EA 04 90 0F C5 1E 8A 07 B0 F2 EA 04 90 0F C6 85 B8 07 B0 F2 EA 04 90 0F C7 0C A9 07 B0 F2 EA 04 90 0F C8 FB 51 07 B0 F2 EA 04 90 0F C9 72 40 07 B0 F2 EA 04 90 0F CA E9 72 07 B0 F2 EA 04 90 0F CB 60 63 07 B0 F2 EA 04 90 0F CC DF 17 07 B0 F2 EA 04 90 0F CD 56 06 07 B0 F2 EA 04 90 0F CE CD 34 07 B0 F2 EA 04 90 0F CF 44 25 07 B0 F2 EA 04 90 00 CF 8C A6 ............................ Group 1 on: 07 B0 F2 EA 04 91 03 D0 4E 3E ............................. 07 B0 F2 EA 04 91 03 D1 C7 2F ............................. Group 1 white: 07 B0 F2 EA 04 91 13 D2 CD 88 ............................. 07 B0 F2 EA 04 91 13 D3 44 99 ............................. Color green: 07 B0 F2 EA 7D 91 0F D4 EC 72 07 B0 F2 EA 7D 91 0F D5 65 63 07 B0 F2 EA 7D 91 0F D6 FE 51 07 B0 F2 EA 7D 91 0F D7 77 40 07 B0 F2 EA 7D 91 0F D8 80 B8 07 B0 F2 EA 7D 91 0F D9 09 A9 07 B0 F2 EA 7D 91 0F DA 92 9B 07 B0 F2 EA 7D 91 0F DB 1B 8A 07 B0 F2 EA 7D 91 0F DC A4 FE 07 B0 F2 EA 7D 91 0F DD 2D EF 07 B0 F2 EA 7D 91 0F DE B6 DD 07 B0 F2 EA 7D 91 0F DF 3F CC 07 B0 F2 EA 7D 91 0F E0 4B 05 07 B0 F2 EA 7D 91 0F E1 C2 14 07 B0 F2 EA 7D 91 0F E2 59 26 07 B0 F2 EA 7D 91 0F E3 D0 37 07 B0 F2 EA 7D 91 0F E4 6F 43 07 B0 F2 EA 7D 91 0F E5 E6 52 07 B0 F2 EA 7D 91 0F E6 7D 60 07 B0 F2 EA 7D 91 0F E7 F4 71 07 B0 F2 EA 7D 91 0F E8 03 89 07 B0 F2 EA 7D 91 0F E9 8A 98 07 B0 F2 EA 7D 91 00 E9 42 1B ............................ Group 1 off: 07 B0 F2 EA 7D 91 04 EA B9 4E .............................
I already know that the first byte is length, the last two bytes are CRC and the one before that is a packet ID that is incremented for each distinct packet (but kept the same for resends). That leaves 6 bytes in the middle: In my first preliminary assessment they seem to be:
This is not a proper "command" set. This is just the current state of the remote control, transmitted in the most unimaginative way possible. By looking at the lower nibble of the CMD byte I can map it to the buttons on the remote as follows:
Now you know why they can't have more channels or additional features: There simply aren't any button codes left. Two more rules seem to apply:The value of the sliders are as follows:
There's...
Read more »Based on what I knew so far I could a) describe the Mi-Light frame format (if not the contents) and b) try to map this to the nRF51 or nRF24 frame format. Way back in 2011 the neighbourly Travis Goodspeed described how to achieve promiscuous sniffing with the nRF24L01+. Even though I didn't use this technique here (having done both SDR and logic analyzer sniffing instead), you should read his post, since it contains some basic knowledge that also applies to the PL1167 format.
Below is the framing I deduced for both nRF51422 (in little endian mode) and nRF24L01+ (which seems to operate in big endian), illustrated using an example from my received data:
Read more »I also wanted to sniff the communication between the micro controller and radio IC, but couldn't get the case of the remote control open. At the next opportunity I brought the Mi-Light Wi-Fi controller with me and got that open more or less easily:
Inside wasn't much: a main board and, as I'd read before in the openhab group, a Wi-Fi daughter board connected to that, both with simple wire antennas.
I knew that the connection between the boards wasn't interesting, since it only contains an UART with the command set I already know. I also know that that command set isn't related (in any obvious way) to the on-air protocol. That leaves me with a conclusion: The unmarked chip in the top left must be a microcontroller that implements the actual protocol and transmits commands to the PL1167 chip to the right of it. The PL1167 chip's leads seemed a little small to try to connect a logic analyzer, so instead I connected it to the microcontroller. I didn't know the pinout (except that center right is ground), so I just connected probes at random, hoping to catch something interesting (the probe at the bottom of the image is connected to ground).
Counting counter clockwise from the marking on the microcontroller I got probes onto 1, 2, 3, 4, 8, 10, 13, and 14. I was using a Saleae Logic with their beta software for Linux (for some reason the 'stable' version would crash rather reliably). I also had the RF receiving set up, though it turned out that I didn't really need it:
And yep, sure enough, I got all four wires required for SPI among my sniffed traces, and can see some action when the device boots:
I had to play with the SPI settings to get this right (CPOL=0, CPHA=1), but it matches up with what the data sheet told me. Here you can see it writing the "Register Optimum Values" from the user manuals right after boot:
I exported the data from the Logic software as a CSV file and wrote a small python tool to decode and interpret the data, this is what happens on boot:
1.17814875: Write reg 0 -> 6F E0 1.17824850: Write reg 1 -> 56 81 1.17834825: Write reg 2 -> 66 17 1.17844775: Write reg 4 -> 9C C9 1.17854750: Write reg 5 -> 66 37 1.17864725: Write reg 7 -> 00 4C channel 76 (2478)MHz 1.17874700: Write reg 8 -> 6C 90 1.17884675: Write reg 9 -> 48 00 1.17894650: Write reg A -> 7F FD 1.17904625: Write reg B -> 00 08 1.17914575: Write reg C -> 00 00 1.17924550: Write reg D -> 48 BD 1.17934525: Write reg 16 -> 00 FF 1.17944500: Write reg 17 -> 80 05 1.17954475: Write reg 18 -> 00 67 1.17964450: Write reg 19 -> 16 59 1.17974425: Write reg 1A -> 19 E0 1.17984375: Write reg 1B -> 13 00 1.17994350: Write reg 1C -> 18 00 1.18004325: Write reg 20 -> 48 00 preamble length: 3 bytes, syncword length: 32 bits, trailer length: 4 bits, data type: NRZ, FEC: None 1.18014300: Write reg 21 -> 3F C7 1.18024275: Write reg 22 -> 20 00 1.18034250: Write reg 23 -> 03 00 1.18044225: Write reg 28 -> 44 02 1.18054175: Write reg 29 -> B0 00 CRC on, first byte is length, FW_TERM_TX, initial CRC data: 00 1.18064150: Write reg 2A -> FD B0 1.18074125: Write reg 2B -> 00 0F 1.39462075: Read reg 0 -> 6F E0 1.39473375: Read reg 1 -> 56 81 1.39484675: Read reg 2 -> 66 17 1.39495975: Read reg 4 -> 9C C9 1.39507300: Read reg 5 -> 66 37 1.39518600: Read reg 7 -> 00 4C channel 76 (2478)MHz 1.39529900: Read reg 8 -> 6C 90 1.39541200: Read reg 9 -> 48 00 1.39552525: Read reg A -> 7F FD 1.39563825: Read reg B -> 00 08 1.39575125: Read reg C -> 00 00 1.39586425: Read reg D -> 48 BD 1.39597725: Read reg 16 -> 00 FF 1.39609050: Read reg 17 -> 80 05 1.39620350: Read reg 18 -> 00 67 1.39631650: Read reg 19 -> 16 59 1.39642950: Read reg 1A -> 19 E0 1.39654250: Read reg 1B -> 13 00 1.39665575: Read reg 1C -> 18 00 1.39676875: Read reg 20 -> 48 00 preamble length: 3 bytes, syncword length: 32 bits, trailer length: 4 bits, data type: NRZ, FEC: None 1.39688175: Read reg 21 -> 3F C7 1.39699475: Read reg 22 -> 20 00 1.39710800: Read reg 23 -> 03 00 ...Read more »
The first step in reverse-engineering any radio protocol is to listen to it on the air. The advent of software-defined radio makes this much, much, easier than before. For this project I've used a nuand bladeRF board and the GNURadio software stack, specifically gnuradio-companion.
The first task I set out to achieve was finding the frequency the devices communicate on. From the data sheet I knew that there are 128 channels in 1MHz spacing starting at 2.402GHz. In GRC I connected the bladeRF source to a FFT display with peak hold mode and then pressed buttons on the Mi-Light remote, positioned directly next to the antenna, while switching through receiving frequencies. I found that something would happen on 2.411GHz every time I touched the remote.
Next I wanted to look at the recorded signal more closely in the swiss army knife of signal analyzing: baudline, but for reasons that are not entirely clear to me I couldn't get the raw recording to load in baudline (or it would always crash immediately). Well, OK then, on to some speculative signal processing in GRC: I assumed amplitude modulation, because that's what all my previous RFID projects used, and so I connected a Frequency Xlating band pass filter and a simple complex-to-mag block in between the signal source and a scope. If I made the band pass narrow enough, I would get something akin to a data signal in the scope, but it didn't look pretty.
I re-checked the PL1167 data sheet, which I should have done before, and there it was spelled out rather clearly: The chip uses GFSK, a type of frequency modulation. Yes, if you put a narrow band pass on one of the frequency bands used by FSK you will get something similar to the original signal. But that's not the proper way to decode FSK. Truth be told, I don't know the proper way to decode GFSK, but I've seen someone on the internets use a quadrature demod block for the purpose, and sure enough, it seemed to work.
Now that I had a demodulated signal, I simply saved that as a .wav file and could look at it in baudline at my leisure. I identified a 10101010… preamble used to prep the receiver and could deduce the bit timing (4 samples per bit, or, at my sample rate of 4MHz, 1 Mbit/s – I could have gotten that from the data sheet).
I wrote Python code that consumes the recorded samples, looks for a strong signal and the preamble and then decodes the signal into bits that are written to stdout:
So that looks quite good already: Aligning on the first 111 tells me that most of the received data is identical, except for some changing bits at the end. Visually I identified a counter at the end, followed by 16 bytes that seemed to change at random (most likely a CRC). Aligning it so that the counter wasn't split between bytes, decoding as little endian (I got that from the counter), gave me a list of bytes transmitted:
47 B1 58 52 07 B0 F2 EA 76 10 01 8A 22 C5 FF 03 00 00 00 00 47 B1 58 52 07 B0 F2 EA 76 10 01 8A 22 C5 FF 03 00 00 00 47 B1 58 52 07 B0 F2 EA 76 10 01 8A 22 C5 FF 03 00 00 00 00 47 B1 58 52 07 B0 F2 EA 03 10 0F 8B A9 7A FF 03 00 00 00 47 B1 58 52 07 B0 F2 EA 03 10 0F 8C 16 0E FF 03 00 00 00 00 47 B1 58 52 07 B0 F2 EA 03 10 0F 8D 9F 1F FF 07 00 00 00 47 B1 58 52 07 B0 F2 EA 03 10 0F 8E 04 2D FF 03 00 00 00I already could tell: Most commands are sent as ~30 copies (with same counter value). Except for color/brightness changing, that seems to be streamed (with a new counter value per transmission) as long as the finger is on the wheel, and then when taking the finger off the wheel the end is repeated (with same counter value) again ~30 times.
Hardware
I have bought a set from Amazon: 4 Mi-Light bulbs (E27, 6W), remote control, and Wi-Fi gateway. The components perform as advertised: using the remote control is reliable and immediate, lamp brightness is ok, colors are great. There's a big disappointment though: These aren't RGBW lamps! These are, to coin a phrase, HV⊕V lamps: You can have them either in color or in warm white mode, and in color mode you can only set hue and value (brightness), while in warm white mode you can only set the brightness. You cannot change the saturation and you cannot combine white and colored LEDs.
Software
As documented elsewhere, the Wi-Fi gateway creates its own password-less Wi-Fi network to which you can connect and has a web interface with username/password admin/admin through which you can join it to your home Wi-Fi network. (Actually, my access point lets me create multiple virtual SSIDs that can be mapped to VLANs and I did so here: The Mi-Light Wi-Fi gateway is connected to a special separated network and does not have internet connectivity.) I've never used the accompanying phone app.
Instead I'm using the Wi-Fi gateway with the WifiLight module for FHEM (a home automation framework I use). This works mostly reliably, but the delay/refresh rate is awful. I'm using the same module with an LD382 Wi-Fi LED strip controller which can easily sustain one command every 150ms. With the Mi-Light gateway it's more like one command per second.
Existing Documentation
LimitlessLED (one of the names under which Mi-Light bulbs are sold) publishes a lengthy and not well organized developer page with lots of information and something they call OpenSource API. What it is though is a listing of all the commands that you can send to the Wi-Fi gateway, and that's already a big help. Besides the FHEM module mentioned above, there already is a lot of code in all the programming languages of the world (including PHP und bash) to send commands to the gateway.
In the openhab (which is another home automation framework) Google Group there is a thread from someone who has opened their bridge, discovered that it consists essentially of two boards (a Wi-Fi to UART side, and an UART to proprietary 2.4GHz side) and replaced the Wi-Fi connection with a wired LAN connection for better reliability. This thread contains a lot of information: It lists the 2.4GHz chip for the proprietary RF system as a PL1167 and even has data sheets for the PL1167. The protocol on the UART connection is simply the same protocol as on the Wi-Fi: the Wi-Fi→UART converter is a dumb standard component that is not Mi-Light specific.
Some of this information was previously collected and linked to from https://wikidevi.com/wiki/MiLight, there's also a link to a Mi-Fi bulb teardown.
Create an account to leave a comment. Already have an account? Log In.
Hi All,
I love the Milight Gateway Emulator for ESP 8266. Test it now with 32 bulbs and work great. Maybe a idea to make the WebUI better? Give Device ID a Name. So i add "0xAAAA" and want give this the name "Livingroom" When you press the pull down you get a nice list of all Device ID's with a nice name: Livingroom, Bedroom, Kitchen.. etc you name it.
Keep up the good work!!!
Is it somehow possible to flash the original gateway with an alternative firmware that will expose a REST API?
You hacked remote controller. I play with receiver (RGBW LED strip controller) and logic analyzer. I found something interesting. uC in loop set 3 different sync patterns by commands:
0x24147A; 0x27258B; //old RGBW remote, sync pattern 258B147A
0x247236; 0x271809; //new RGB-CCT, sync pattern 18097236
0x249AAB; 0x27BCCD; //third type remote? sync pattern BCCD9AAB?
There are actually 9 different frequencies, 3 for each sync pattern. Plus receiver do something funny after receives packet, probably retransmit it.
3rd one is a known type.. RGB.. you are missing a 4th one (0x050A, 0x55AA)
Thanks for answer. I searched but cannot found RGB remote. Can You send me model or link? Only thing I found so far is FUT089 - 8 zone remote compatible with CCT and RGB-CCT light bulbs. Strange thing.
I not miss 4th type. RGBW receiver miss it. I not have single color nor CCT equipment so I can skip that sync pattern.
Hello to All.
Really really nice peace of work.. I just have one question. Is it possible to use with one receiver RGBW and CC/CW remote controller? (To do not use one nRF24 for RGBW and second one to CC/CW). Thanks a lot for answer..
I think I managed to reverse the 9-byte protocol used by the new RGB+CCT protocol. Details here:
I'm implementing within the Arduino SDK for esp8266 here:
https://github.com/sidoh/esp8266_milight_hub
(PL1167/MiLight radio code adapted from Henryk's original)
Hi Chris,
pretty impressive work....
I has been a while since I looked at it, but back then I missed your data analyzing gift.
I haven't tried your gateway app yet, as I haven't got any nRF board - instead I used the PL8900 receiver but it is compatible with the LT1167. I have bad experiences with the nRF transcievers.
I will look into using this transciever instead.
Again .... impressive work. :)
I have a GTOP (China brand) remote controller and LED driver. This is the web site in Chinese: https://detail.1688.com/offer/521325933241.html?spm=a2615.2177701.0.0.lgJKNj
As describe in the web site. The controller is using 2400-2483.5Mhz frequency using GFSK. Working range is about 20-30 meters. It has a similar looks as mi-light remote controller.
I have tried using NRF24l01+ with Raspberry Pi 2 trying to listen to any signal sent from the GTOP remote controller. Apparently, it fails. I have no clue at all.
I notice the NRF24l01+ is using 16000 crystal. I open the GTOP remote controller and notice it is using 12000 crystal. I am not sure if the crystal specification is the cause of the failure.
Is there any good way to get mimic the GTOP remote controller? Can NRF24l01+ communicate with GTOP led controller?
I've partially decoded the protocol but still need to setup and modify the code so that it can work properly. My findings are based on the SPI communication to the PL1167 chip, the actual on-the-air data might be different:
bytes 1,2 = [0a,ff] - remote ID?
byte 3 = [8] + button:
1=?
2=ch 3 on
3=ch 1 on
4=brightness up
5=?
6=ch 3 off
7=ch 1 off
8=warmer
9=ch 4 on
a=ch 2 on
b=cooler
c=?
d=ch 4 off
e=ch 2 off
f=bright down
byte 4,5,6 = [b5,04,01]
byte 7 = brightness
byte 8 = color temperature (0x00 cool, ~0x37 warm)
bytes 9,10 = CRC/toggle based on byte 3?
Example messages:
full spi message for ch1 on: 34.80.80 32.0a.ff 32.83.b5 32.04.01 32.02.1a 32.26.af 07.01.14
***ch1 on 0a.ff 83.b5 04.01 02.1a 26.af
***ch1 off 0a.ff 87.b5 04.01 02.1a 66.af
***warmer again 0a.ff 88.b5 04.01 02.09 6a.eb
***warmer again 0a.ff 88.b5 04.01 02.0a ea.eb
***ch2 on 0a.ff 8a.b5 04.01 80.2d 6a.a9
***ch2 off 0a.ff 8e.b5 04.01 80.17 6a.8d
***ch2 off again 0a.ff 8e.b5 04.01 80.17 6a.ad
***ch3 on 0a.ff 82.b5 04.01 80.32 68.8d
***ch4 on 0a.ff 89.b5 04.01 80.32 48.9c
***bright up 0a.ff 84.b5 04.01 81.32 40.9c
The last two bytes are confusing, it seems to toggle byte 9 or 10 between two values when the same key is pressed, however it scrambles either 9, or 10, or both when another key is pressed. It doesn't seem to take into account what the actual data is.
I have to dig up an nrf24l01 to test this, otherwise I would have to lift the keyboard decoder chip from the remote PCB or cut its power trace, since it interferes when trying to talk to the RF chip. I have 4 of these remotes, but only on one of them there is a 2-chip solution, in the other 3 it's all a single chip that includes the keyboard matrix decoder and the RF TX.
I also had a problem but now my remote is detected:
"If you want to change the above software to work with the CW WW remote
you need to change retval = _pl1167.setSyncword(0x147A, 0x258B); on
line 42 of MiLightRadio.cpp to retval = _pl1167.setSyncword(0x050A,
0x55AA); and in addition change the channels static const uint8_t
CHANNELS[] = {9, 40, 71}; to 4, 39 and 74."
on top, do the following:
In PL1167_nRF24.cpp:
add:
#define DEBUG_PRINTF
(so you can see what happens)
Is this project still alive and moving somewhere? Would love to see this working with RGB warm white....thx...willem
I have RGB+CCT (RGB-WW-CW) bulbs with a new remote controller.
So I look at the Source code and change some things... (so I get Debug Infos on serial)
I find out that the the lenght of Packet is 9 (the old remote has 7)
if I change the line (retval = _pl1167.setMaxPacketLength(8e);) to the val 10 I can see the send data from the new remote...
Preamle, sync, Paketlength is O.K.
and CRC work fine and always O.K.
But the data has 2 byte more and change every transmitting (with some resends).
If anybody has a Idea to make the data more readable, I can change the source....
Here my serial output with Key Zone 1 OFF:
----------------------------------------------------------------
Zone1 off mit Android app: (min 3x send)
Packet transformed: Preamble:AAAA Sync:7A148B25 FB-ID:75 Data-Length:07 Data:B8 E9 59 2B 00 04 81 CRC-soll:2C74 --> CRC-ist:2C74
Data: 10111000 11101001 01011001 00101011 00000000 00000100 10000001
FB01 FB02 FB03 Val1 Val2 Button packetID
Zone1 off mit neuer Remote: (min 3x send)
Packet transformed: Preamble:AAAA Sync:7A148B25 FB-ID:95 Data-Length:09 Data:63 91 24 03 07 E4 7E 1B 92 CRC-soll:3325 --> CRC-ist:3325
Data: 01100011 10010001 00100100 00000011 00000111 11100100 01111110 00011011 10010010
Packet transformed: Preamble:AAAA Sync:7A148B25 FB-ID:95 Data-Length:09 Data:5C 77 3F 4C C2 2E 3C C2 8C CRC-soll:1CA7 --> CRC-ist:1CA7
Data: 01011100 01110111 00111111 01001100 11000010 00101110 00111100 11000010 10001100
Packet transformed: Preamble:AAAA Sync:7A148B25 FB-ID:95 Data-Length:09 Data:FD B2 7E DD B5 97 76 B6 81 CRC-soll:C4B1 --> CRC-ist:C4B1
Data: 11111101 10110010 01111110 11011101 10110101 10010111 01110110 10110110 10000001
Packet transformed: Preamble:AAAA Sync:7A148B25 FB-ID:95 Data-Length:09 Data:35 7A 46 15 7D 5F 2D 7E F0 CRC-soll:379A --> CRC-ist:379A
Data: 00110101 01111010 01000110 00010101 01111101 01011111 00101101 01111110 11110000
Cheap batches of relabelled Mi-Lights https://www.mydealz.de/deals/fernbediente-lightme-led-varilux-classic-a60-65-w-e27-eur544-659-bei-conrad-815067 of the "WW" ("dual-white") kind have rekindled interest in this project and http://fablab.ruc.dk/controlling-the-mi-light-from-arduino/ as well as the Pi 1 & 2 wirings documented by http://torsten-traenkner.de/wissen/smarthome/openmilight.php and https://www.raspberrypi.org/magpi/pi-mi-light/.
For now sudo openmilight as by Torsten seems to detect & display no keys from the WW remotes at all (even after sudo modprobe spi_bcm2835 in spite of dtoverlay=spi-bcm2835-overlay already in a jessie Pi's /boot/config.txt): Apparently only https://github.com/miek/milight and https://github.com/pmoscetta/authometion-milight try to handle WW.
What kind of captures could one provide to help merge the RGBW and WW protocols into one version of openmilight (or just to see the WW remotes physically received by the nRF24L01+ in the first place)?
I am trying to figure out a way to control my RGB+CCT (RGB-WW-CW) bulbs which have the new protocol and new remote controller.
The code for this project doesn't work, and I don't know where to start.
So instead I have been trying to figure out how the remote control works.
It seems to use two capacitive touch controller ICs, 12 channel each. One controller for the bottom 4 light-group on/off switches (8 channels of the controller), plus the mode/disco buttons or whatever they are, and then another identical controller for the top half which includes the main on/off, the wheel, and two sliders (brightness, white colour temp, oh and saturation on the RGB+CCT remote).
Actually I am doing my testing on the older RGBW remote that everybody already has - because I need to keep using my RGB+CCT remote for the house.
The chips and the board are almost an exact fit for the Atmel AT42QT2120 controller (chip is a 20-lead soic), board design fits the specification, and I can see separate i2c coming from each chip, to the 10 pin header of the RF board (the same header that the WiFi bridge uses for a UART connection), however the pin-outs don't match the Atmel chip, and the i2c address doesn't match either. I can't find any other 12 channel capacitive touch controller ICs that come in 20 pin packages though... even the diagrams for the wheel and slider in the Atmel manual are identical to how this PCB is designed.
My electronics and logic/protocol knowledge is very little (first time I've tried to understand how i2c actually works, or use a logic analyzer.. only bought it yesterday) and although I can see some stuff, I'm a little stuck as to where to go next. I presume something 'wakes' the circuits so that there's not a constant power drain. I need to find that, trigger it, then try to spit some i2c stuff down the bus.. maybe ?
This is what I have from last night. I only had a few pins connected up then. Now I have all 8 channels of my logic analyzer hooked up to the header on the RF module so things may get easier.. plus the remote is put back together, just has wires coming out of the back now..
Anyway, this is for the existing RGB+W remote, but the build of the RGB+CCT remote looks the same, so if I can make this work, I will be able to make it work for the RGB+CCT remote.
pin 10 of sensor and 6 of header is ground
header pin 1 is VDD
pin 8 of lower sensor goes to pin 4 of header
pin 12 of lower sendor to pin 3 of header
pin 11 of lower sensor to pin 2 of header
pin 8 of upper sensor goes to pin 8 of header (goes low just before.. must be activating micro/radio or could be guard)
pin 12 of upper sensor goes to pin 9 of header (sda)
pin 10 of upper sensor goes to pin 10 of header (scl) bottom right
all on gives
read to 0x53
0x02 +ack
0x00 +
0x01 +
0x00 +
0x55 +nak
followed by
read to 0x53
0x02 +ack
0x00 +
0x00 +
0x00 +
0x55 +nak
all off gives
read to 0x53
0x02 +ack
0x00 +
0x02 +
0x00 +
0x55 +nak
followed by
read to 0x53
0x02 +ack
0x00 +
0x00 +
0x00 +
0x55 +nak
(all from the upper 20-pin touch sensor).
Confirm that the lower touch-sensor outputs identical-ish i2c to different pins of the RF-board header.. those pins above that I haven't labelled.
I've just done more testing, and if I ground pin 8, the one that I said 'goes low just before i2c data', then it does wake the microcontroller, and cause it to trigger a read of addres 0x53, with the sensor ICs returning zeros because no buttons are actually being touched. This is promising. Same for another pin for the separate i2c bus.
What's also confusing me, is that the SCL clock seems to run at 27KHz, which is unusually slow for i2c, I think?
Anyway I have a ds1054z scope coming, and an arduino to act as an i2c slave... something to play with :)
Hi Carl,
the RGB+CCT bulbs uses different sync words and channels for communication.
Furthermore they use a different protocol - still seems to be one way - but it is scrambled somehow.
I have two remotes, and can tell from picking up frames from them, that the protocol still uses a remote ID (2bytes?) and a frame ID (which increments with each different keypress).
Can you link me to some docs on how you were able to sniff the packets from the remote for these new bulbs?
Hi Jared,
at http://authometion.com/forum/viewtopic.php?f=2&t=639 I posed some extra info...
Hi Woodster.
I haven't done any more on this since I wrote the above.. needed to refocus my life again :-)
I just bought a HackRF. Wonder if I can discover anything useful with that?
I did get as far as making a dual-channel i2c slave (it runs two independent i2c buses in slave mode both at the same address of 0x53), which could emulate the two capacitive touch sensors in the remote control, and take their place and communicate to the microprocessor in the remote. I used a Feather M0 arm arduino thing.
My i2c packets weren't right though, or rather not in the expected order and frequency etc (my programming skills are bad, so I was just looping and spitting out the same packets lots of times, and had to recompile every time I wanted to try out a new i2c packet), but I was able to turn the bulb on, make it flash, make it go blue (this was a regular RGBW bulb though, but remember I am instead replacing the touch-sensors in the remote control, rather than understanding the milight protocol itself). Anyway I was able to get these things to happen, but unpredictably, and I have since not been back to the project.
I now have a HackRF and am curious if I can learn anything useful.
What's stopping me from just recording and replaying the packets? Is there a rolling code (other than the incrementing frame id)?
If it's of interest, this is as far as I got with the arduino thing:
Well this is interesting...
I just captured 2.47GHz with the HackRF, while dimming up and down, and then I replayed the capture, and I can repeatedly dim up and down my RGB+CCT lights.. *some of them*
I have a combination of FutLight RGB+CCT downlights (the 6w ones), and a 24v MiLight RGB+WW+CW box (receiver/controller) which I have connected to some long PCB strip lights (for my kitchen top under cupboard things).
Well, using the RGB+CCT remote, I captured with HackRF, and when I replay, the counter top lights respond. So the MiLight box is responding.
I think the downlights might just need a different frequency, as the remote transmits on a few frequencies at the time time.. maybe..
So I know I am working in the analog RF domain here.. dumping out a 10MHz band that just happens to have the remote commands in it somewhere, but it seems to be working, to a point, so far.
Woohoo it works.
HackRF records 2.47GHz, with some gain settings, and I can replay a dim-up-dim-down, as many times as I want..
I suppose it'd be useful to decode my 'dim' capture somehow.
Hi there,
I would like to sniff traffic from WWCW bulbs (not RGBW).
However, the Henryk's code is not able to show that.
How can I modify the source code in order to sniffing RF data by using a Raspberry Pi ?
Best Regards,
Jerome
Has anyone tried to unlink the bulb?
I don't get it...
Cheers Julian
Thanks for the wonderful writeup. Just want to mention that you can use the nRF24 radio to 'syn' (or link) the LED bulb. That is, you can control the bulb even without ever using a remote/WIFI controller. You simply transmit the code that corresponds to the link action (i.e., pressing ON button for a particular channel). For example, sending "B0 F2 EA 04 91 03 D0 " (format: ID1, ID2, ID3, VAL1, VAL3, CMD, SEQ; note CMD=03 corresponds to pressing channel 1 ON) right after you turn on the LED power will set the remote ID to B0 F2 EA. Tested to work on a brand new, never synced/linked MI bulb.
Hi There,
I have had a look a the new dual white RGB led, and it uses a different protocol.
I think it has an expanded protocol compared to the old bulbs, still one way, still the same RF chip, but different channels and sync words.
The repeat and channelhopping seems to be the same, and the sync process between the remote and the bulb is the same.
I have looked further into the data being sent - and it seems there is a pattern as long as the first byte (index 0) is the same.
The following frames has been picked up when pressing on channel 1 on a LOT of times.
The frame seems to be scrambled somehow - but it looks like the bytes at index 6 and eight are the only ones changing when the byte at index 0 is the same. So when looking at the old protocol, these bytes might be the "frameID".
As it is still oneway - and the bulb learns the remoteID when using different remotes, then the "key" has to be sent in the frame.
A long press also changes another byte, index 4, and that is also a bit like the old protocol.
0xb1 0x06 0x8d 0x56 0xc9 0xa8 0xcd 0xca 0xa9
0xb1 0x06 0x8d 0x56 0xc9 0xa8 0xcb 0xca 0xa7
0xb1 0x06 0x8d 0x56 0xc9 0xa8 0xff 0xca 0x4b
0xb1 0x06 0x8d 0x56 0xc9 0xa8 0xea 0xca 0x46
0xb1 0x06 0x8d 0x56 0xc9 0xa8 0xdb 0xca 0x37
0xb1 0x06 0x8d 0x56 0x49 0xa8 0x42 0xca 0x9e long press / repeat
0xb3 0x41 0xd7 0x20 0x37 0x95 0xf0 0xcb 0x31
0xb4 0x1f 0x24 0x37 0xaa 0x15 0xf3 0xaa 0xfe
0xb4 0x1f 0x24 0x37 0xaa 0x15 0x30 0xaa 0x33
0xb4 0x1f 0x24 0x37 0xaa 0x15 0xdc 0xaa 0xef
0xb4 0x1f 0x24 0x37 0xaa 0x15 0xb6 0xaa 0xc1
0xb4 0x1f 0x24 0x37 0xaa 0x15 0xac 0xaa 0xbf
A different key gives this frame:
0xb1 0x06 0x8d 0x56 0xc9 0xa5 0x87 0xc7 0x5d different key than "ch1 on"
Anyone up for a challange to find the "key"?
Martin
just received a bunch of these bulbs & remotes, having not realised the wifi bridge isn't out yet :( did you manage to get any further or have any more notes?
I've started to document the dual-white protocol here: https://github.com/miek/milight
Hi Mike, you can find additional info and a library for arduino that supports both rgb and dual white at https://github.com/pmoscetta/authometion-milight
The new rgb + dual white are different though..
Ah sorry, I misread your post - didn't notice it was RGB + dual white (where do you get those? they sound good). Cheers for the link!
They can be found at http://www.limitlessled.com/shop/rgbw-ww-cw-light-bulb/ or http://www.aliexpress.com/item/2-4G-Wireless-E27-8W-RGBWW-Color-Temperature-Dimmable-2-in-1-Smart-MiLight-LED-Bulb/32611916280.html?spm=2114.01010208.3.1.9wchnU&ws_ab_test=searchweb201556_8,searchweb201602_4_10037_10017_10021_507_10022_10032_10009_10020_99...
amongst others... futlight.com seems to be the oem manufacturer, and they have some other products coming up. Guess they will use the same protocol as these bulbs.
Hi. I have made some small changes to Henryk's code to get it working on an ESP8266 with an nRF24L01+. I am using the v 2.0.0-RC2 of the ESP8266 software . Since then jensh made an update to make pgm_read_byte() and pgm_read_word() usable from c files merge #1170.
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/pgmspace.h
I have not tried that yet. The pin definitions are as follows.
#define CE_PIN 2
#define CSN_PIN 15
The SPI is as per usual MISO = 12; MOSI = 13; SCK = 14;
The whole things works in that i can read RF messages and also write them to get standard mi-light bulbs operating. However there is one instruction from RF24.cpp file line 747 which has a pgm_read_byte instruction. When this is executed the ESP8266 resets. If i just comment out the line the program works fine. Anyone have any idea why this should be happening.
Okay, i've done some research and traced out the bulb-side board, and I noticed they're using the STM8's four-channel TIM1 for the PWM outputs. This uses all the same pins as the native SPI interface, so I guess they must be bit-banging the SPI link between STM8 and PL1167. I found a few tutorials for the STM8 including SPI bit-banging made by user Nevyn on the netduino forums, they will probably prove very useful. http://forums.netduino.com/index.php?/topic/5260-application-development-on-the-stm8s/
The STM8/PL1167 combo seems to be pretty common around Alibaba and DHgate, but I can't find much in the way of sample code, and most of them are using native SPI anyway. But I also found this one board (link below) that looks like it's pretty much the *exact* same circuit as in the Milights. I've asked the seller for code examples (posing as a development engineer for a major project) but he won't send me any unless i order a production sample for 20 usd (almost worth it!).
They seem to be the only supplier so i guess they're careful about giving out their code, to prevent people from cloning their board.
Also, sorry Henryk for hijacking your thread, if I do actually start working on this I'll start my own separate Hackaday project.
edit: Project started: https://hackaday.io/project/8758-hacking-the-milight-wireless-bulbs
So, in essence this protocol can never support RGB colors? Bummer. So now hacking the actual bulbs is looking more and more attractive. They're pretty simple really, there's just the same PL1167 transceiver and an STM8S003F3 microcontroller doing PWM on the four (RGBW) LED channels. So we could either reprogram that setup or replace it altogether with a custom system, like an nrf24 + atmega or something.
Here's my look inside two different MiLight bulbs (teardown starts at 3:00):
Has anybody figured out how to write RGB, HSV or HSB values to it? The protocol only uses color and brightness which is highly limited.
Seems like it's just not supported. It's like they made the remote first and devised a very limited RF protocol implementing nothing more than what's on the remote, and then they made the WiFi bridge emulating a remote as an afterthought.
I'm currently looking into reprogramming the bulbs to use a better protocol (check out my Hackaday project), and maybe replacing the WiFi chip in the bridge with an ESP8266 (but still using the PL1167 transceiver from the bridge). Programming tools for the STM8 microcontroller that's in my bulbs* can be sourced very cheaply on Ebay, and the circuit seems pretty straightforward so I think it can probably be done. Then we could do a ton of cool stuff too like letting the bridge keep track of bulb settings changes even while they're powered down, and updating the bulb as soon as it comes online again.
*the STM8 controller and PL1167 transceiver is not used in all Milights - I've seen other controller/transceiver combos implementing the same protocol in other Milight branded bulbs.
Become a member to follow this project and never miss any updates
Interesting, i was going to look at the MiLight SYS lighting, which appears to be the same except they use a single wire to connect to the light (0v, 24vDC, data) to send the light signals (for 5 colors), the SYS is part of there DMX range, they do have a wireless component but its not compatible with the controllers here....
Any idea if anyone has worked on the SYS range?