xoseperez / espurna

Home automation firmware for ESP8266-based devices
http://tinkerman.cat
GNU General Public License v3.0
2.99k stars 636 forks source link

Feit Electric Smart WiFi Bulb #1681

Open CalcProgrammer1 opened 5 years ago

CalcProgrammer1 commented 5 years ago

My parents got one of these bulbs at Christmas time and I was curious, so I bought some for myself. I already use Espurna on two AiLight compatible bulbs but these Feit bulbs are brighter and have a warm white channel, plus they're readily available in local stores. I took one apart and it uses an ESP8266EX microcontroller on a custom PCB. I haven't done much other than take some photos of the board yet but I would like to help support this bulb.

According to the silkscreen on the controller PCB, the following 8 pins are used to control the bulb:

IO4 IO14 IO5 IO12 IO13 GND VIN 3.3

The controller PCB attaches to a partially-potted main PCB via standoffs. A 90-degree board to board connector attaches to the top ring PCB, which contains what appears to be two high voltage LED chains (one warm white and one cold white) as well as a string of RGB LEDs attached to a SM16726B controller chip.

20190404_174909

20190404_174622

20190404_174655

20190404_182041

cbrightly commented 5 years ago

Thanks for your contribution! Have you had any further experience getting these bulbs off of the factory firmware?

CalcProgrammer1 commented 5 years ago

Tried to do some more reverse engineering today. I pulled out the ESP8266 board and powered it from an Arduino. The VIn pin seems broken...the bulb may be dead but if I can learn how it works I don't mind sacrificing it. I'm guessing VIn should work like on Arduino - >3.3V in to produce a regulated 3.3V, but that didn't happen. I tried putting 3.3 and 5V on the Vin pin but no voltage was present on the 3.3V pin. I then just wired to the 3.3V pin which seems to have powered up the ESP8266. I discovered the two pads on the back near the IO14 pin are serial TX/RX. I will try soldering wires to them and seeing if I get boot messages later. I also think the 4 pads on the other side are likely unused GPIOs. Hopefully that means I can put it in bootloader mode and flash Espurna.

20190922_203105

CalcProgrammer1 commented 5 years ago

Here's a bit of log from the serial output:

 ets Jan  8 2013,rst cause:1, boot mode:(3,0)

load 0x40100000, len 1396, room 16 
tail 4
chksum 0x89
load 0x3ffe8000, len 776, room 4 
tail 4
chksum 0xe8
load 0x3ffe8308, len 540, room 4 
tail 8
chksum 0xc0
csum 0xc0

2nd boot version : 1.4(b1)
  SPI Speed      : 40MHz
  SPI Mode       : QIO
  SPI Flash Size & Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000

OS SDK ver: 1.4.2(78f3caf) compiled @ Oct 23 2017 13:45:35
phy v[notice]user_main.c:294 SDK version:1.4.2(78f3caf)
[notice]user_main.c:298 fireware info name:esp_color_light_A70_hjqpd_5L_low version:1.1.7
[notice]user_main.c:301 tuya sdk compiled at Jun 27 2018 13:13:53
[notice]user_main.c:303 BV:5.29 PV:2.1 LPV:3.1
reset reason: 0
epc1=0x00000000, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000,depc=0x00000000
mode : softAP(86:f3:eb:41:0a:e0)
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
add if1
bcn 100
[notice]gw_intf.c:240 Authorization success
bcn 0
del if1
usl
mode : sta(84:f3:eb:41:0a:e0)
add if0
scandone
state: 0 -> 2 (b0)
[notice]mqtt_client.c:450 gw wifi stat is:5
state: 2 -> 0 (2)
reconnect
[notice]mqtt_client.c:450 gw wifi stat is:5
scandone
state: 0 -> 2 (b0)
[notice]mqtt_client.c:450 gw wifi stat is:5
state: 2 -> 0 (2)
reconnect
scandone
state: 0 -> 2 (b0)
[notice]mqtt_client.c:450 gw wifi stat is:5
[notice]wf_sdk_adpt.c:162 dhcp restart...
state: 2 -> 0 (0)
scandone
CalcProgrammer1 commented 5 years ago

Found GND, IO0, TX, and RX. Tested code upload, it is working! Now to flash Espurna.

CalcProgrammer1 commented 5 years ago

I was able to flash the module, but reassembling it into the light it seems dead. I think I fried the regulator on the board or something. No voltage on the 3.3V line. Luckily I had ordered two of these bulbs, so I tried to tuya-convert the second. That was successful and it is now running the AiLight build of Espurna (which controls absolutely nothing on this bulb, it just stays warm white). Now to try and figure out which pins control which channels. I'm guessing cold white and warm white are PWM and the RGB channels are on the driver chip. I may be able to figure out the pinout looking at the high voltage board.

mhightower83 commented 5 years ago

Here are some useful links, if you haven't found them:

This issue shows connections to the TUYA board: https://github.com/ct-Open-Source/tuya-convert/issues/99

On this page Search for BPA800 to find the pins assignments: https://github.com/ct-Open-Source/tuya-convert/wiki/Compatible-devices GPIO5=PWM1, GPIO12=PWM2, GPIO4=CLK, GPIO13=ENABLE, GPIO14=DATA(SM16716)

Be careful with overdriving the blub, it is a 9Watt bulb; however, there is nothing to stop you from going to 18Watts. I would not expect the unit to last long at that level. Use one of those power monitors to see what is drawn.

Also, the latest BPA800 blubs don't look like this one and are using an SM726 chip.

CalcProgrammer1 commented 5 years ago

I think I just bricked my second bulb :| I tried to make my own build of Espurna with platform.io and made a target like so:

// -----------------------------------------------------------------------------
// Feit Electric Smart WiFi Bulb
// -----------------------------------------------------------------------------

#elif defined(FEIT_ELECTRIC_SMART_LIGHT)

    // Info
    #define MANUFACTURER        "FEIT_ELECTRIC"
    #define DEVICE              "SMART_BULB"
    #define RELAY_PROVIDER      RELAY_PROVIDER_LIGHT
    #define LIGHT_PROVIDER      LIGHT_PROVIDER_DIMMER

    // Light
    #define LIGHT_CHANNELS      2
    #define LIGHT_CH1_PIN       12  // Warm
    #define LIGHT_CH2_PIN       5   // Cold
    #define LIGHT_CH1_INVERSE   0
    #define LIGHT_CH2_INVERSE   0

and a build configuration like so:

[env:feit-electric-smart-light-ota]
board = ${common.board_1m}
build_flags = ${common.build_flags_1m0m} -DFEIT_ELECTRIC_SMART_LIGHT
upload_port = ${common.ota_upload_port}
upload_flags = ${common.ota_upload_flags}

Uploaded the firmware.bin, now it just lights up both cold and warm LEDs and doesn't broadcast a WiFi SSID or connect to my router.

arihantdaga commented 4 years ago

I had a similar bulb. It has been working fine with espurna. I am able to control it, I replaced the flash with a 4MB flash with espurna flashed into it.

However I am having the issue in configuring(Bringing device into configuration mode) the device. With the original firmware, for getting device into configuration mode, we have to turn on and turn off the power switch 3 times. (Since there is no button on this bulb). I was thinking if this would be possible in Espurna. (I can see that we keep track of restarts in systemUnstable check), but that uses rtc memory, which won't last after a power cycle. So @mcspr Can you suggest something about how to implement this type of logic for bringing device into configuration mode.

mcspr commented 4 years ago

@arihantdaga Old counter just wrote to flash on each boot, perhaps easiest way is just do the same. Settings variable or byte at EEPROM_CRASH_COUNTER offset.

I wonder though, how do those bulbs know that you power-cycled 3 times. There are also some leftover pins, ref GPIO4=CLK, GPIO13=ENABLE, GPIO14=DATA(SM16716) mentioned above, maybe they do something? (...I wish tasmota templates were more verbose, need to go code spelunking again to understand those numbers :( )

arihantdaga commented 4 years ago

These GPIOs are connected only to the IC and for Light's operations. I saw schematics of one of the variant of these bulbs. There is no additional GPIO for checking the power.

By storing in EEPROM, I think it's fairly simple. I had an initial idea that if the device restarts within 3 seconds then in the custom_crash_callback we can increment the counter and whenever device restarts, we can check the counter - Very similar to systemCheckLoop.

But then I also saw this pull request on tasmota today for the same issue - https://github.com/arendst/Tasmota/commit/782563b3ae1301b91759bcdc8f7cfcea221f3be0 Issue - https://github.com/arendst/Tasmota/pull/6639

I think we can take some inspiration from this. I'll try to understand this code and write something compatible with Espurna.

mcspr commented 4 years ago

The main idea is:

Assume flash is default all ones an setting a bit to zero does not need an full sector erase

However, if is reusing eeprom sector for that, we need to take into the account crc calculation from the rotation library. Tasmota code uses the sector right before SPIFFS_end aka FS_end, periodically changing 4 byte number there to erase specific bits. There is also some magic involved by having that specific number 0xFFA55ABF

CalcProgrammer1 commented 4 years ago

I'm going to attempt to work on this bulb some more. I think I've managed to repair my board back to a working state. Had to hack in a new 3.3V regulator and the pad for the TX pin fell off so I had to do some mangling. Attached a pin header for easy access to the programming pins. I'm going to flash a generic build and then try to get the board back into the bulb. Now that I know how to 2 step OTA properly maybe this won't be so bad.

20200917_180159

apophisnow commented 2 years ago

Any chance you could label those pins in the image? I'm trying to flash the same bulb, and I'd like to do it without having to disassemble it if possible.

cbrightly commented 2 years ago

Any chance you could label those pins in the image? I'm trying to flash the same bulb, and I'd like to do it without having to disassemble it if possible.

See https://github.com/ct-Open-Source/tuya-convert/issues/99#issuecomment-529185264 for a photo with labeling.