logo elektroda
logo elektroda
X
logo elektroda
Dostępna jest polska wersja

Czy wolisz polską wersję strony elektroda?

Nie, dziękuję Przekieruj mnie tam

Feit Electric "Smart Color Chasing Strip Light" w/BK7231N and SM16703 SM16704

darconeous 9309 30
Best answers

What is the pinout and channel order for Feit Electric's BK7231N smart color chasing strip light, and how can it be driven in OpenBK?

The strip uses DOUT on P16, a 24V power-enable on P22, and the button on P24, and its segment channel order is R, G, B, warm white 1, warm white 2, cool white 1, cool white 2, with the white channels effectively giving higher brightness range [#20804661] The original SM16703 driver did not fit this hardware cleanly because it assumed 3 channels and showed bit-shift/buffer problems, so configurable channel count and mapping were suggested for 7-channel strips [#20804661] OpenBK later reported that the SPI DMA bug was fixed, and that SM16703P/WS2812B-style LEDs should work properly after updating [#20966214]
Generated by the language model.
ADVERTISEMENT
  • #1 20791392
    darconeous
    Level 3  
    Posts: 5
    Rate: 6
    Howdy. I just picked up a Feit Electric 20-ft LED chaser strip and promptly tore it down. Seemed to be using a BK7231N. The strip is RGBCW, but it is a little strange in that each segment has two chips: a SM16703 and a SM16704. This means there are, ua... 7 channels per segment, but I only see 5 being used. I haven't tried driving it yet, so I'm not sure what the channel order is yet.

    Bizarrely, the connector for the LED strip is the same as USB-C, even though it is very clearly NOT USB-C. They are only sending three signals over it: +24v, DOUT, and GND. I'm not yet sure how they are mapping those to the USB-C pins yet, so not sure if it would fry anything if someone decided to try to connect it to their computer. Very strange decision.

    In any case, I haven't tried changing the firmware yet, but it looks like all the important pins have nicely labeled test points.

    It was something like $25 at Costco.

    Feit Electric smart LED strip packaging. Feit Electric LED strip packaging with features. Close-up of a circuit board with various electronic components and a USB-C connector. Close-up of an LED connector with a USB-C-like end. LED strip connector resembling USB-C with three pins labeled G, ID, V+. LED connector resembling USB-C on a green PCB. Close-up of a BK7231N chip on a printed circuit board. PCB of Feit Electric LED strip with SM16703 and SM16704 chips visible. Close-up of SM16703 chip with AZYVA23 text on its surface. Close-up view of the SM16704PE chip with markings AZSFAB25. Close-up of a green circuit board with visible traces and pin labels. Close-up of a green circuit board with markings 24V and GND2 against a hand background.
  • ADVERTISEMENT
  • #2 20791759
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    I think that we have a SM16703 , so maybe, just make a 2MB flash backup and give it a try? I can try to guide you step by step with that.
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #3 20792424
    darconeous
    Level 3  
    Posts: 5
    Rate: 6

    Will do. Maybe the weekend before I can give it a shot. I had originally planned to just toss the controller and replace it with a PicoW, but seeing your firmware has made me reconsider.

    The SM16703 is the same as the SM16704, except with an extra channel. So I expect that the protocol should be the same except with 7 channels instead of 3 or 4.

    Maybe each segment can control two sets of W and C, but only one RGB? In that case, the channel order would be something like RGBWCWC, or RGBWWCC... I guess we will find out this weekend!

    Awesome work, by the way. Looking forward to digging into the details of your firmware.

    BTW: Is the BK7231N based on RISC-V? I kept trying to definitively hammer down the arch, but couldn't seem to find a decent datasheet.
  • ADVERTISEMENT
  • #4 20803236
    darconeous
    Level 3  
    Posts: 5
    Rate: 6

    Ok, I managed to get it flashed using the python command line tool on my Mac. I can now access the web interface without too much trouble. I did back up what I could of the firmware, but I'm not sure if I was able to extract it properly because it kept having CRC errors.

    Now I'm at the point where I need to figure out what the GPIOs are for the button and the data line. I was hoping there was a command in the OpenBK firmware that would allow me to dump the existing state of the pins so that I could at least have a straightforward path to identifying the button.

    Any suggestions or tips/tricks for how best to identify the right pins?

    Added after 18 [minutes]:

    Ah, I managed to find the GPIO finder. Pin 24 is the button. Will go looking for the other pins soon. I think there is a MOSFET for determining if power should go to the strip or not, as well as the actual data pin.
  • #5 20803289
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    Sorry for the late reply. If this device is using individually adressible LEDs, then data is always P16. This is because they are using SPI to push pixels with correct timings. Have you tried SM16703 driver?
    Helpful post? Buy me a coffee.
  • #6 20804661
    darconeous
    Level 3  
    Posts: 5
    Rate: 6
    Allright, here is the pinout:

    P16: DOUT (to DIN on the strip)
    P22: 24v Power Enable (Controls the +24v pin to the LED strip)
    P24: Button (low when pressed, high when not pressed)

    I've tried the SM16703 driver and it seems like there is a bit shift for some reason that causes the channels to not quite line up properly. But from what I can tell, the channel order is this:

    Channel 1: Red
    Channel 2: Green
    Channel 3: Blue
    Channel 4: Warm White 1
    Channel 5: Warm White 2 (Same LED as channel 4, but just additional brightness)
    Channel 6: Cool White 1
    Channel 7: Cool White 2 (Same LED as channel 6, but just additional brightness)

    So it seems like the RGB channels can go from 0-255, but the white channels can effectively go from 0-510.

    The SM16703 driver definitely seems buggy, even taking into account it is only intended for 3 channels instead of 7. It doesn't seem to clear out the buffer at initialization, so everything starts with random values unless you initialize them all explicitly. It also doesn't seem to prevent you from setting LED values that are larger than initialization, leading to some memory corruption that causes the device to get into a bad state. There also seems to be an odd bit-shift problem that I'm seeing where the channels don't quite line up bit-for-bit, so setting one channel to 255 seems to cause some of those bits to be set on the previous channel. Not sure why this is the case.

    But I can control the lights at least!

    For a generic driver I think you would want to have the following configuration options:

    1. Number of channels.
    2. Channel mapping. (RGB, BGR, WWRGBCC, etc)
    3. Maybe timing information so that it could also be compatible with neopixels?

    UPDATE: I haven't tested this yet, but I think the sort of changes we would want for the driver look something like this:

    
    diff --git a/src/driver/drv_sm16703P.c b/src/driver/drv_sm16703P.c
    index e0e011ce..0593dbd6 100644
    --- a/src/driver/drv_sm16703P.c
    +++ b/src/driver/drv_sm16703P.c
    @@ -22,12 +22,16 @@
     
     #include "drv_spidma.h"
     
    +#define SM16703P_MAX_CHANNELS		(8)
    +
     static uint8_t data_translate[4] = {0b10001000, 0b10001110, 0b11101000, 0b11101110};
     
    -UINT8 *send_buf;
    -struct spi_message *spi_msg;
    +UINT8 *send_buf = NULL;
    +struct spi_message *spi_msg = NULL;
     BOOLEAN initialized = false;
     uint32_t pixel_count = 0;
    +uint8_t channel_count = 3;
    +uint8_t channel_map[SM16703P_MAX_CHANNELS];
     
     static uint8_t translate_2bit(uint8_t input) {
     	//ADDLOG_INFO(LOG_FEATURE_CMD, "Translate 0x%02x to 0x%02x", (input & 0b00000011), data_translate[(input & 0b00000011)]);
    @@ -58,7 +62,7 @@ static void SM16703P_setMultiplePixel(uint32_t pixel, UINT8 *data) {
     
     	// Iterate over pixel
     	uint8_t *dst = spi_msg->send_buf + 2;
    -	for (uint32_t i = 0; i < pixel * 3; i++) {
    +	for (uint32_t i = 0; i < pixel * channel_count; i++) {
     		uint8_t input = *data++;
     		*dst++ = translate_2bit((input >> 6));
     		*dst++ = translate_2bit((input >> 4));
    @@ -66,14 +70,21 @@ static void SM16703P_setMultiplePixel(uint32_t pixel, UINT8 *data) {
     		*dst++ = translate_2bit(input);
     	}
     }
    -void SM16703P_setPixel(int pixel, int r, int g, int b) {
    -	translate_byte(r, spi_msg->send_buf + (2 + 0 + (pixel * 3 * 4)));
    -	translate_byte(g, spi_msg->send_buf + (2 + 4 + (pixel * 3 * 4)));
    -	translate_byte(b, spi_msg->send_buf + (2 + 8 + (pixel * 3 * 4)));
    +void SM16703P_setPixel(int pixel, int r, int g, int b, int w, int c) {
    +	translate_byte(r, spi_msg->send_buf + (2 + channel_map[0]*4 + (pixel * channel_count * 4)));
    +	translate_byte(g, spi_msg->send_buf + (2 + channel_map[1]*4 + (pixel * channel_count * 4)));
    +	translate_byte(b, spi_msg->send_buf + (2 + channel_map[2]*4 + (pixel * channel_count * 4)));
    +
    +	if (channel_count >= 4) {
    +		translate_byte(w, spi_msg->send_buf + (2 + channel_map[3]*4 + (pixel * channel_count * 4)));
    +	}
    +	if (channel_count >= 5) {
    +		translate_byte(c, spi_msg->send_buf + (2 + channel_map[4]*4 + (pixel * channel_count * 4)));
    +	}
     }
     
     commandResult_t SM16703P_CMD_setPixel(const void *context, const char *cmd, const char *args, int flags) {
    -	int pixel, i, r, g, b;
    +	int pixel, i, r, g, b, w, c;
     	Tokenizer_TokenizeString(args, 0);
     
     	if (Tokenizer_GetArgsCount() != 4) {
    @@ -86,32 +97,43 @@ commandResult_t SM16703P_CMD_setPixel(const void *context, const char *cmd, cons
     	g = Tokenizer_GetArgIntegerRange(2, 0, 255);
     	b = Tokenizer_GetArgIntegerRange(3, 0, 255);
     
    -	ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i", pixel, r, g, b);
    +	if (channel_count >= 4) {
    +		w = Tokenizer_GetArgIntegerRange(4, 0, 255);
    +	}
    +
    +	if (channel_count >= 5) {
    +		c = Tokenizer_GetArgIntegerRange(5, 0, 255);
    +	}
    +
    +	if (channel_count <= 3) {
    +		ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i", pixel, r, g, b);
    +	} else if (channel_count <= 4) {
    +		ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i W %i", pixel, r, g, b, w);
    +	} else {
    +		ADDLOG_INFO(LOG_FEATURE_CMD, "Set Pixel %i to R %i G %i B %i W %i C %i", pixel, r, g, b, w, c);
    +	}
     
     	if (pixel < 0) {
     		for (i = 0; i < pixel_count; i++) {
    -			SM16703P_setPixel(i, r, g, b);
    +			SM16703P_setPixel(i, r, g, b, w, c);
     		}
     	}
    -	else {
    -		SM16703P_setPixel(pixel, r, g, b);
    -
    -		ADDLOG_INFO(LOG_FEATURE_CMD, "Raw Data 0x%02x 0x%02x 0x%02x 0x%02x - 0x%02x 0x%02x 0x%02x 0x%02x - 0x%02x 0x%02x 0x%02x 0x%02x",
    -			spi_msg->send_buf[2 + 0 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 1 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 2 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 3 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 4 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 5 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 6 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 7 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 8 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 9 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 10 + (pixel * 3 * 4)],
    -			spi_msg->send_buf[2 + 11 + (pixel * 3 * 4)]);
    +	else if (pixel < pixel_count) {
    +		SM16703P_setPixel(pixel, r, g, b, w, c);
    +
    +		for (i = 0; i < channel_count; i++) {
    +			ADDLOG_INFO(LOG_FEATURE_CMD, "Raw Data CH%i 0x%02x 0x%02x 0x%02x 0x%02x",
    +				i,
    +				spi_msg->send_buf[2 + 0 + i*4 + (pixel * channel_count * 4)],
    +				spi_msg->send_buf[2 + 1 + i*4 + (pixel * channel_count * 4)],
    +				spi_msg->send_buf[2 + 2 + i*4 + (pixel * channel_count * 4)],
    +				spi_msg->send_buf[2 + 3 + i*4 + (pixel * channel_count * 4)]);
    +		}
    +	} else {
    +		ADDLOG_INFO(LOG_FEATURE_CMD, "Bad pixel index %i", pixel);
    +		return CMD_RES_BAD_ARGUMENT;
     	}
     
    -
     	return CMD_RES_OK;
     }
     
    @@ -120,30 +142,64 @@ static void SM16703P_Send(byte *data, int dataSize) {
     }
     
     commandResult_t SM16703P_Start(const void *context, const char *cmd, const char *args, int flags) {
    -
    +	int i;
     	Tokenizer_TokenizeString(args, 0);
     
     	if (Tokenizer_GetArgsCount() == 0) {
    -		ADDLOG_INFO(LOG_FEATURE_CMD, "Not Enough Arguments for init SM16703P: Amount of LEDs missing");
    +		ADDLOG_INFO(LOG_FEATURE_CMD, "Not Enough Arguments for init SM16703P: Pixel count is missing");
     		return CMD_RES_NOT_ENOUGH_ARGUMENTS;
     	}
     
     	pixel_count = Tokenizer_GetArgIntegerRange(0, 0, 255);
     
    +	if (Tokenizer_GetArgsCount() >= 2) {
    +		channel_count = Tokenizer_GetArgIntegerRange(1, 0, SM16703P_MAX_CHANNELS);
    +	} else {
    +		channel_count = 3;
    +	}
    +
    +	if (Tokenizer_GetArgsCount() >= 3) {
    +		for (i = 0; i < channel_count; i++) {
    +			channel_map[i] = Tokenizer_GetArgIntegerRange(2+i, 0, 8);
    +			if (channel_map[i] >= channel_count) {
    +				ADDLOG_INFO(LOG_FEATURE_CMD, "Bad channel index %i for channel %i", channel_map[i], i);
    +				return CMD_RES_BAD_ARGUMENT;
    +			}
    +		}
    +	} else {
    +		for (i = 0; i < channel_count; i++) {
    +			channel_map[i] = i;
    +		}
    +	}
    +
     	ADDLOG_INFO(LOG_FEATURE_CMD, "Register driver with %i LEDs", pixel_count);
     
    +	// Free the old buffer if one was allocated.
    +	if (initialized) {
    +		os_free(send_buf);
    +	}
    +
     	// Prepare buffer
    -	uint32_t buffer_size = 2 + (pixel_count * 3 * 4);			  //Add two bytes for "Reset"
    +	uint32_t buffer_size = 2 + (pixel_count * channel_count * 4);			  //Add two bytes for "Reset"
     	send_buf = (UINT8 *)os_malloc(sizeof(UINT8) * (buffer_size)); //18LEDs x RGB x 4Bytes
    -	int i;
     
     	send_buf[0] = 0;
     	send_buf[1] = 0;
     
    +	// Turn on all channels on all pixels at maximum brightness.
    +	// TODO: Is this REALLY what we want to do? Shouldn't we be
    +	//       be setting the initial value to be encoded zero bits
    +	//       instead of encoded 1 bits? Consider changing to
    +	//       0b10001000 after discussion.
     	for (i = 2; i < buffer_size; i++) {
     		send_buf[i] = 0b11101110;
     	}
     
    +	// Free the old buffer if one was allocated.
    +	if (initialized) {
    +		os_free(spi_msg);
    +	}
    +
     	spi_msg = os_malloc(sizeof(struct spi_message));
     	spi_msg->send_buf = send_buf;
     	spi_msg->send_len = buffer_size;
    



    This would allow you to initialize with a custom number of channels like this (7 channels, RGBWxCx)

    
    SM16703P_Init 10 7 0 1 2 3 5
    


    But if you don't specify the number of channels it assumes "3 0 1 2" (3 channels, RGB order).

    Again, I haven't tested the above code (not even sure if it compiles yet) but it should be a good start.

    Added after 11 [hours] 22 [minutes]:

    Argh... There seems something very strange with the SPI driver. I keep getting very strange offset/looping behavior on the SPI output, things like the channels being off by two or so, but still actually wrapping around in such a way that if you fill all of the pixels that all the pixels still get lit. The offset seems to change depending on the size of the buffer.

    My brain hurts too much to continue working on this tonight.


    UPDATE:

    Yeah, the SPI output isn't matching up with the data in the buffer:

    Oscilloscope screen showing SPI DMA test signal.

    You can see that gap in the middle: That's the "reset" pulse (extended to 7 bytes in my code) that is supposed to be at the start of the transmission. In other words, the whole transmission should just appear as a big block, not two blocks. For some reason, the "reset" pulse is in the middle!

    If I reduce the total number of lights to 2 (7 channels each) then I can reliably get the reset pulse at the start. I'm really confused why the SPI output isn't lined up with the order in memory. Any ideas?
  • #7 20807690
    darconeous
    Level 3  
    Posts: 5
    Rate: 6
    Well, out of frustration with the SPI DMA stuff, I tried to bitbang out the bits... But the shortest pulse I could muster was 2µs—way longer than the 0.3µs required. I might be able to improve that timing significantly by banging on the GPIO registers directly, which is the approach that the bitstream bit-banging method from Micropython does, and it manages to pull it off with the RISC-V variant of the ESP32.

    Is there anything I should know about how to increase my bit-banging rate, or is there some sort of fundamental limit that I'm going to end up running into?
  • #8 20807800
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    Sorry for the late reply, @darconeous . To the best of my knowledge, it is not possible to do bit bang on this platform, due to the flash instructions cache system, which is practically random. I tried this approach and failed in the past. I tried even with nop operators. The only way for that to work would be to use a ramfunc, which is a function that resides in RAM and is executed directly from RAM, but again, I've found a problem with creating my own ramfunc as well...
    https://github.com/openshwprojects/OpenBK7231T_App/issues/497

    Are you really sure that you're doing everything ok with the SPI? I haven't tried it myself yet except few tests with WS2812B but it still seemed to kind work.... I need to take out my scope to check, or we can ask @DeDaMrAz to check this as well and show here the waveforms.
    Helpful post? Buy me a coffee.
  • #9 20808053
    DeDaMrAz
    Level 22  
    Posts: 604
    Help: 34
    Rate: 129

    @darconeous

    Do you mind sharing the original FW dump?

    I found the same strip on eBay so I'll get that in a couple of weeks so we can test and support them fully.
  • #10 20808173
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    @DeDaMrAz we could just flash his backup on our CB3S and do the scoping with original firmware then
    Helpful post? Buy me a coffee.
  • #11 20810671
    paulcarhuff
    Level 1  
    Posts: 1

    I just want to thank you for even just trying with these. I appreciate these lights for the price, but the programmability from Feit's app leaves a bit to be desired. (Even if just a little)

    I am sometime in the near future planning to do some Neopixel programming, but I'm a baby when it comes to coding at this point. I used to use VB and JScript a touch during school but that was 20+ years ago!

    ANYHOW...
    I'm hopeful that one day I'll be able to "per pixel" control these lights. A decent price for a strip, a controller, a power supply, and a mostly functional app in my humble opinion. Pretty close to almost all my wants in the app, but not quite 100%

    The hardware is there!

    Added after 31 [minutes]:

    Hey, IDK if this matters, but most of the scenes in the Feit app seem to assume two strips are connected together. It was driving me mad all night till I just figured it out. But where things should be symmetrical even accounting for that, they are not always. Like there's an offset... idk, but when I realized that I thought someone else might make use of it.

    Thanks again!
  • #12 20843831
    missoulapc
    Level 1  
    Posts: 1

    Any further luck? I picked up a few of these at Costco. Flashed without a problem. Just trying to nail down how to get some light out of them.
  • #13 20844769
    DeDaMrAz
    Level 22  
    Posts: 604
    Help: 34
    Rate: 129

    @missoulapc

    We don't have that device at hand, so it is difficult to do anything about it right now. If somebody is willing to sell it and send it to us, we will gladly try to incorporate and support it.
  • #14 20851058
    CliffBraun
    Level 1  
    Posts: 1

    I have an extra one of these I could send somewhere if it would help.
  • #15 20851080
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    Where are you from? Depending on location, shipping to Poland may be expensive. Send me a PM if you're interested in helping us.
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #16 20868940
    kevdel
    Level 4  
    Posts: 4
    Rate: 4

    >>20808053

    Did you get a copy of the FW? I have one from a unit I bought last weekend.
  • #17 20868971
    DeDaMrAz
    Level 22  
    Posts: 604
    Help: 34
    Rate: 129
    kevdel wrote:
    >>20808053

    Did you get a copy of the FW? I have one from a unit i bought last weekend


    Post it here please.
  • #18 20869022
    kevdel
    Level 4  
    Posts: 4
    Rate: 4

    >>20804661
    By chance, have you tried ESPHome driver?
    https://esphome.io/components/light/fastled.html

    These seem to be limited to 3 channels for RGB... so maybe it's a start to the number you found

    Added after 2 [minutes]:

    >>20868971
    Attachments:
    • readResult_BK7231N_QIO_feitflasheroriginalfw_2023-18-12-14-03-35.bin (2 MB) You must be logged in to download this attachment.
  • #19 20869547
    kevdel
    Level 4  
    Posts: 4
    Rate: 4

    >>20868971

    If you ever need a homework to test on, then I'm happy to use mine to load dev solutions.
  • #20 20869549
    DeDaMrAz
    Level 22  
    Posts: 604
    Help: 34
    Rate: 129
    kevdel wrote:
    >>20868971

    if you ever need a hw to test on then I'm happy to use mine to load dev solutions.


    Thank you for commitment unfortunately we have to do tests locally so we can provide a solution. We appreciated greatly the backup you provided we are going to work with it and provide updates here.


    View of a smartphone app screen displaying LED lighting settings Chasing Tape Light. Microcontroller connected to a mobile device with an app screen showing device pairing.

    P24 is the switch on the device, used for pairing.

    @p.kaczmarek2 we should probably use our modified modules for testing, right?

    Thank you.
  • #21 20869629
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    P16 is a SPI output used for pixels data, we have modified modules for that:
    How to access hardware SPI port on CB2S? P16 (MOSI) GPIO breakout method
    It is not available on unmodified CB2S and not on CB3S. You need either the modification from link above or CBU for that
    Helpful post? Buy me a coffee.
  • #22 20869633
    DeDaMrAz
    Level 22  
    Posts: 604
    Help: 34
    Rate: 129
    p.kaczmarek2 wrote:
    P16 is a SPI output used for pixels data, we have modified modules for that:
    How to access hardware SPI port on CB2S? P16 (MOSI) GPIO breakout method
    It is not available on unmodified CB2S and not on CB3S. You need either the modification from link above or CBU for that


    I got it ready.
  • #23 20890614
    kevdel
    Level 4  
    Posts: 4
    Rate: 4
    By chance @DeDaMrAz , any update on the investigation? If there is anything I can do to help, then please let me know! Thanks!
  • #24 20931119
    Sarain
    Level 4  
    Posts: 3

    I've been following this thread with interest and I'm also curious if there are any updates on support.

    In the hope that these will eventually be supported, I took a small risk in buying a couple of these around Christmas time.

    I know this is volunteer work, so totally understand if it's not ready yet. Just wanted to check, since there haven't been any status updates in a while.

    Best Regards!
  • #25 20937193
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    darconeous wrote:

    UPDATE:

    Yeah, the SPI output isn't matching up with the data in the buffer:

    Oscilloscope screen showing SPI DMA test signal.

    You can see that gap in the middle: That's the "reset" pulse (extended to 7 bytes in my code) that is supposed to be at the start of the transmission. In other words, the whole transmission should just appear as a big block, not two blocks. For some reason, the "reset" pulse is in the middle!

    If I reduce the total number of lights to 2 (7 channels each) then I can reliably get the reset pulse at the start. I'm really confused why the SPI output isn't lined up with the order in memory. Any ideas?

    I can only confirm that I've spent a day testing the SPI DMA and I arrived at the same conclusion.

    There is some strange instability that causes a random lag in transfer.

    I have tried to fix it, by, for example, doing a NOP loop until SPI DMA send everything, but it still happens.

    See WS2812B test below, correct display:
    WS2812B LED strip connected to an oscilloscope, showing display irregularity.
    Randomly, SPI DMA display is broken:
    Rigol DS1054Z oscilloscope displaying a signal and a WS2812B LED strip.
    I do not know currently what causes this issue. We need more information, any help is wanted.
    Helpful post? Buy me a coffee.
  • #26 20966214
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    The SPI DMA driver bug has been fixed. The SM16703P/WS2812B/etc LEDs should work good now. Please update your devices. For scripting configuration, please see:
    OpenBeken WS2812B driver (compatible with SM16703P, etc) - short scripting presentation
    We can continue discussion there. The more advanced animation will be added soon, stay tuned!
    Helpful post? Buy me a coffee.
  • #27 21315554
    sasipraveen39
    Level 1  
    Posts: 1
    I have the same LED lights from Costco and have a lot of cut excess strips that I'm trying to solder together to form one long strip light. I'm attempting to solder the strip light directly to the controller. Does anyone know which pins on the USB-C SMD connector on the controller correspond to GND, 24V, and Dout? Thanks in advance.

    Close-up of a circuit board with a USB-C port and a LED strip labeled GND, 24V, and Dout.
  • #28 21315812
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    Do you have a multimeter? It should be very easy to check.
    Dout is P16, hardware SPI output.
    Please check this topic to see where P16 on QFN case is:
    BK7231 datasheet, pinout, programming, specification, wiki (BK7231T, BK7231N)
    Keep in mind that first pin is marked by a dot. Futhermore, you may double check it by looking at crystal oscillator pins.
    Helpful post? Buy me a coffee.
  • #29 21539283
    Sarain
    Level 4  
    Posts: 3
    I realize this thread is rather old but this seems to be the main one for discussing this particular Feit Electric branded LED strip. Happy to start a new thread for this if that would be better.

    Thanks to everyone involved in getting the SM16703 driver working on the BK7231N!
    I'm finally getting back to trying this out with a new OpenBK release (1.18.94) on these LED strips. I have things set up and mostly working in the sense that I can use a series of SM16703P_SetPixel commands to predictably control which LEDs come on.

    The problem I'm still having is that this strip uses both the SM16703 and SM16704, so 7 channels per segment, in a R G B WW WW CW CW pattern. The normal SM16703P_SetPixel command expects 3 channels (for RGB).

    So, I can run the following to set the first two segments to full Green (as an example):
    SM16703P_Init 4
    SM16703P_SetPixel 0 0 255 0
    SM16703P_SetPixel 1 0 0 0
    SM16703P_SetPixel 2 0 0 255
    SM16703P_SetPixel 3 0 0 0
    SM16703P_Start


    This is kind of annoying though, since the odd number of channels makes it hard to keep track of the position of each color at arbitrary points within the strip.

    Looks like @darconeous did some work towards supporting an arbitrary number of channels and channel mapping in drv_sm16703P.c from his post above. This isn't in the main repo builds though. For anyone still using these strips, have you found a good/better way to control them? If merging @darconeous changes into the latest version and building it myself is the answer, I can go that route. If there's a simpler route (or plans to support something similar), I can wait and/or potentially help out too.

    My ultimate goal is to use the new PixelAnim driver to animate this strip and control it from Home Assistant.
  • #30 21540498
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14622
    Help: 655
    Rate: 12639
    I would also like to extend PixelAnim driver to cover more strip types. I've recently ordered some RGBW strips from China but I didn't have time to play around with it yet, but maybe, we could work together on that. Do you know C programming?

    I can accept drv_sm16703P.c PR as long as it's not breaking any features and is structured in such a way that it will not hamper futher development...
    Helpful post? Buy me a coffee.

Topic summary

✨ The discussion centers on the Feit Electric 20-ft "Smart Color Chasing Strip Light" using a BK7231N microcontroller and dual LED driver chips SM16703 and SM16704 per segment, resulting in 7 channels (RGB + two Warm White + two Cool White) per segment. The LED strip uses a USB-C style connector carrying only +24V, DOUT (data out), and GND signals, with DOUT mapped to GPIO P16 using SPI for pixel data transmission. Challenges include identifying correct GPIO pins for button and power enable (P24 for button, P22 for 24V enable), and dealing with the SM16703 driver limitations, such as improper buffer clearing and channel misalignment due to the 7-channel configuration versus the driver’s 3-4 channel design. Attempts to bitbang the SPI data line failed due to timing constraints and flash instruction cache randomness on the BK7231N platform, making SPI DMA the preferred method despite occasional random lags and instability. Firmware dumping and flashing were performed with some CRC errors, but access to the web interface was achieved. Community efforts focus on improving OpenBK firmware support, including fixing SPI DMA bugs and extending drivers to handle the 7-channel RGBWWCW configuration. Collaboration on C firmware development and testing with original hardware is ongoing, with some users offering hardware samples for local testing. The Feit app’s limited programmability motivates the community to enable per-pixel control through custom firmware. The BK7231N is confirmed to be a RISC-V based MCU, complicating bitbanging approaches. The discussion also references ESPHome FastLED drivers as a partial starting point, though limited to 3 channels. Overall, the thread documents reverse engineering, firmware modification, and driver development efforts to fully support the Feit Electric RGBWWCW LED strip on BK7231N hardware using OpenBK firmware.
Generated by the language model.

FAQ

TL;DR: The Feit Electric 20-ft strip uses 7 channels per segment, and one expert found that “data is always P16” for the pixel output on this BK7231N design. This FAQ helps OpenBK users safely back up, flash, and map the controller while avoiding the older SPI DMA bug that broke SM16703P-style LEDs. [#20803289]

Why it matters: This thread turns a hard-to-drive Costco light strip into a documented OpenBK target with known pins, channel layout, and practical firmware limits.

Approach Hardware reuse Known result in thread Main limitation
Keep BK7231N + OpenBK Reuses original controller Web UI access, GPIO discovery, partial light control achieved 7-channel support needed for clean control
Replace with Pico W Replaces controller entirely Considered as a fallback Loses the convenience of the original BK7231N board

Key insight: The core blocker was not the strip hardware. The real issue was BK7231N SPI DMA instability, and later thread updates report that this driver bug was fixed, making SM16703P-class LEDs usable again. [#20966214]

Quick Facts

  • The controller was identified as BK7231N, the strip length was 20 ft, and the retail price mentioned was about $25 at Costco. [#20791392]
  • The strip sends only three signals over its fake USB-C-style connector: +24 V, DOUT, and GND. [#20791392]
  • Confirmed GPIOs are P16 = DOUT, P22 = 24 V power enable, and P24 = button, with the button reading low when pressed and high when released. [#20804661]
  • Actual per-segment layout is 7 channels: R, G, B, WW1, WW2, CW1, CW2. RGB runs 0–255, while each white pair effectively reaches 0–510 combined. [#20804661]
  • Bit-banging hit a timing wall: the shortest observed pulse was 2 µs, while the target protocol needed about 0.3 µs. [#20807690]

How do I flash OpenBK onto a Feit Electric Smart Color Chasing Strip Light with a BK7231N and make a safe 2MB firmware backup first?

Start by making a full 2 MB flash backup, then flash OpenBK with the Python command-line tool. The thread’s suggested path is: 1. Connect to the BK7231N test pads and read a 2 MB backup first. 2. Flash OpenBK using the Python CLI; one user did this successfully on a Mac. 3. Boot into the OpenBK web interface and verify access before changing GPIO roles. CRC errors were reported during backup extraction, so keep the raw dump even if parsing fails. [#20803236]

What are the GPIO pin assignments for the Feit Electric chaser strip controller, including the button, LED data output, and 24V power enable?

The confirmed pinout is P16 for LED data output, P22 for 24 V strip power enable, and P24 for the button. The button is active-low, so it reads low when pressed and high when idle. That mapping was explicitly tested on the Feit controller after flashing OpenBK. If you need only one starting point, use P24 first because it was verified through the GPIO finder before the full map was posted. [#20804661]

Why does the SM16703P driver on OpenBK show channel bit-shift or misalignment issues on this Feit Electric strip?

The driver showed misalignment because SPI output did not match the buffer layout during early testing. One tester saw channels shift by about two positions, values wrap around, and reset pulses appear in the middle of the transmission. He also noted the buffer was not cleared cleanly at initialization, which left random startup values. Those symptoms pointed to the transfer path, not only to the 7-channel strip format. [#20804661]

What is the actual channel order on the Feit Electric RGBCW chasing strip that uses both SM16703 and SM16704 chips?

The actual order is Red, Green, Blue, Warm White 1, Warm White 2, Cool White 1, and Cool White 2. That means each segment exposes 7 controllable channels, not standard RGB or RGBW. The white channels are paired per color temperature, so warm white and cool white each use two slots. In practice, RGB behaves like 0–255 per channel, while each white pair acts like an effective 0–510 range. [#20804661]

How can I configure OpenBK or drv_sm16703P.c to support 7-channel LED segments like RGB WW WW CW CW on this strip?

Use a modified drv_sm16703P.c that adds configurable channel count and channel mapping. The proposed patch introduced a maximum of 8 channels, dynamic buffer sizing, and a channel_map array so the driver no longer assumes fixed RGB. The example initialization was SM16703P_Init 10 7 0 1 2 3 5, intended for 10 pixels and a 7-channel layout. Later discussion in 2025 also suggested extending PixelAnim and accepting a clean pull request for broader strip support. [#20804661]

Why did SPI DMA on BK7231N cause random transfer lag or reset pulses appearing in the middle of the data stream, and what fixed it?

BK7231N SPI DMA had an instability that caused random lag during LED transfers. That lag moved the reset pulse into the middle of the stream and broke patterns even when the memory buffer looked correct. Later testing confirmed the same behavior on WS2812B, not only on this Feit strip. The thread then reported that the SPI DMA driver bug was fixed, and users were told to update because SM16703P, WS2812B, and similar LEDs should work correctly afterward. [#20966214]

What is SPI DMA, and why is it used to drive SM16703P, WS2812B, and similar addressable LEDs on BK7231N devices?

“SPI DMA” is a hardware data-transfer method that feeds SPI output from memory without constant CPU timing, which helps generate tightly timed LED bitstreams. It matters here because the pixel data line on this controller uses P16 as the SPI output, and OpenBK relies on that path for addressable LEDs. That approach is used because software bit-banging on BK7231N struggled to hit the required sub-microsecond timing. In this design, P16 was identified as the pixel data path used for SM16703P-class output. [#20869629]

What is a ramfunc on BK7231N firmware, and why does it matter when trying to bit-bang very fast LED protocols?

“ramfunc” is a function placed in RAM so it executes directly from RAM, avoiding flash-fetch delays that disturb precise timing. It matters on BK7231N because the platform’s flash instruction cache introduces effectively random timing jitter. One developer said bit-banging was not feasible on this platform for that reason, even after trying nop delays. He noted that a working RAM-resident implementation would be the only plausible route for stable, very fast LED pulses. [#20807800]

What’s the difference between SM16703 and SM16704 in these Feit Electric strip segments, and how does that affect driver support?

SM16704 was described here as the same basic protocol family as SM16703, but with an extra channel. That matters because each strip segment contains both chips, creating a total of 7 channels instead of the 3 or 4 that many drivers expect. As a result, a plain RGB-oriented SM16703P implementation can light the strip, but it cannot represent the full per-segment layout cleanly. Driver support must handle arbitrary channel counts and mapping. [#20792424]

Pico W replacement vs keeping the original BK7231N with OpenBK — which approach makes more sense for controlling this Feit Electric strip?

Keeping the original BK7231N with OpenBK makes more sense if you want the fastest path to a working controller. The strip was flashed successfully, the web interface worked, and the key pins were identified without replacing hardware. A Pico W replacement was considered at first, but that became less attractive once OpenBK showed promise. Choose Pico W only if you want a full custom controller stack; choose OpenBK if you want to reuse the board and stay close to the existing hardware. [#20792424]

How do I identify the button pin and data pin on a BK7231N board using the OpenBK web interface and GPIO finder?

Use the OpenBK web interface first, then test pins with the GPIO finder. The practical sequence in the thread was: 1. Flash OpenBK and open the web UI. 2. Use the GPIO finder to locate the button; it identified pin 24. 3. Check the LED data line next; for individually addressable LEDs on this platform, the guidance given was that data is always on P16. That method quickly narrowed the controller to P24 for the button and P16 for pixel output. [#20803289]

Why is bit-banging the LED protocol on BK7231N so difficult compared with using hardware SPI, especially for 0.3 µs timing?

Bit-banging is difficult because the measured pulse width was about 2 µs, while the target timing was roughly 0.3 µs. That is almost seven times slower than needed. The platform also suffers from flash-cache timing jitter, which makes instruction timing unstable even if the code looks tight. Hardware SPI avoids much of that CPU timing problem by shifting data from a peripheral instead of relying on precise software loops. [#20807690]

What’s the best way to use PixelAnim or Home Assistant with a Feit Electric strip that has 7 channels per segment instead of standard RGB?

The best path is to extend the SM16703P driver, then expose that support to PixelAnim. A 2025 user reported that basic control worked on OpenBK 1.18.94 with repeated SM16703P_SetPixel commands, but that method was awkward because the strip uses 7 channels per segment in an R G B WW WW CW CW pattern. The maintainer said he wanted PixelAnim to cover more strip types and was open to a pull request that preserves existing behavior. That makes driver extension the clean route for Home Assistant use. [#21540498]

How should I map the fake USB-C style connector on the Feit Electric controller to GND, +24V, and DOUT when soldering the strip directly?

Map the connector by measurement, not by USB-C assumptions, because it is explicitly not real USB-C. The thread confirms that only three signals are present on that connector: GND, +24 V, and DOUT. It also confirms that DOUT originates from P16 on the controller. For direct soldering, first trace P16 with a multimeter, then identify the +24 V rail and ground on the board. Do not plug this connector into a computer because the thread warned that the pin mapping is nonstandard. [#21315812]

Why do some Feit app scenes look offset or behave as if two strips are connected together on this Smart Color Chasing Strip Light?

Some Feit app scenes appear offset because the app seems to assume two strips are chained together. One user said that realization explained why several scenes looked wrong all night. He also observed that even patterns that should have stayed symmetrical still showed an offset, which suggests the stock effect logic may not line up perfectly with the strip’s actual addressing. That behavior is useful evidence when comparing app behavior against OpenBK pixel mapping. [#20810671]
Generated by the language model.
ADVERTISEMENT