logo elektroda
logo elektroda
X
logo elektroda

Custom UART programmer over Wi-Fi for BK7231 and other platforms - first version

p.kaczmarek2  11 1818 Cool? (+4)
📢 Listen (AI):

TL;DR

  • A custom Wi-Fi-based UART programmer flashes BK7231 and similar IoT chips using a second Wi-Fi module instead of a USB-to-UART adapter.
  • OpenBeken runs a TCP-to-UART bridge on port 8888, while Tasmota-style commands start the bridge, set baud rate, and pulse a GPIO to CEN/reset.
  • The flasher supports 921600 baud and commands for reading, writing, verifying, and testing flash at addresses like 0x11000 or 0x0.
  • WiFiProgram verified flash by writing, reading back, and comparing data, including a 1MB random-data memory test.
  • Timing is still imperfect: getting BK7231 'bus' mode is slow, Wi-Fi retransmissions were needed, and BK7231T bootloader editing at offset 0 is risky.
Generated by the language model.
CB2S module wired to Arduino Wemos D1 WiFi development board .
We have practically always used a simple USB to UART converter based on the popular CH340 chip to program IoT devices. Recently, however, I realised that you could just as well program wirelessly using a second Wi-Fi module and a UartTCP driver with an additional script that either resets the module or sets the boot state, depending on the platform. This is a potentially attractive and simple solution, as it does not require implementing the programmer from scratch, simply redirecting the UART traffic. Here I will present the first version of this mechanism.

The old programming method .
Up to now, we have connected the chip to be programmed to the computer via the USB port on the UART, and then our flasher communicates with it via this port. Depending on the type of MCU being programmed, we also had to short-circuit the boot pin to ground or power, for example, or reset the chip. It looked more or less like this:
Connection diagram for programming an IoT module using a USB to TTL adapter .
(although this 5 V could be taken from the 5 V pin from the USB to TTL converter).

New programming method .
The new idea is to replace the USB to UART converter with a second Wi-Fi module with already pre-loaded our firmware , compiled with the UART driver enabled on TCP. It should be noted here that this method requires soldering wires to the device to be programmed anyway. It does, however, have other advantages:
- you do not need a USB to UART converter
- you can program the hardware without connecting it to a PC/laptop, so there is no risk of short-circuiting - you can power the programmed hardware from the mains
- potentially boot mode control and resetting are easier - not every USB to UART converter has extra RTS/DTR lines, and the Wi-Fi module has many IOs we can use
This is what an example connection looks like - the CB3S on the board from the Arduino Wemos is the programmer, and the CB2S hanging on the wires is the chip being programmed. Of course, you can do it the other way round - use an additional small CB2S soldered to the device to program it with. You just need to connect properly:
- RX to TX (usually RX1, TX1)
- TX to RX (usually RX1, TX1)
- common ground
- common supply 3.3 V
- any GPIO configured as "Relay" in OBK from programmer to CEN pin of the chip being programmed (to reset)
CB2S module wired to Arduino Wemos D1 WiFi development board .
Wemos D1 board with signal wires attached, placed on a wooden surface .

Implementation details .
Pass this paragraph if you are only interested in results!
We already have in OpenBeken the TCP to UART bridge driver - when started, it opens a port on TCP port 8888, and everything that goes into that port is passed to UART port 1 of the Wi-Fi module. The same works in the other direction too. This was already used in our redesign of the Zigbee gateway .. This could potentially carry the programmer's data over the network.
The OBK also, of course, has programmable GPIO operations, so we can have control over resetting and CEN of the chip.
The only thing left is to plug in the flasher, the source code can be found here:
https://github.com/openshwprojects/BK7231GUIFlashTool
First of all, the flasher must take the IP address and port of the device-programmer instead of the COM port. This is not a problem, however, you need to somehow run the controller on this programmer. The Tasmota command interface will be used for this. An example command is sent as a GET request like this:

http://192.168.0.212/cm?cmnd=add_dimmer%20-10
.
In a similar way, a command can be sent that starts the TCP driver on the UART and sets the baud. In my C# it looks like this:
Code: C#
Log in, to see the code
.
The driver is stopped and restarted, this is so that the baud can be changed. 8192 is the buffer size.
The second problem is the CEN operation - resetting the BK7231, because you can only start programming the BK7231 right after the reset. The window of opportunity is very short.
I also perform this by command:


    void toggleCEN()
    {
        SendCommand(TARGET_IP, "setChannel 0 0");
        SendCommand(TARGET_IP, "setChannel 0 1");
    }
.
This assumes that there is a pin on channel 0 in OBK with the Relay role, and this pin is connected to the CEN of the device being programmed.
Catching the flashing mode (aka "getting bus") takes a bit then anyway, so I may have to improve this mechanism, but at least it works.
Screenshot showing C# code and UART log with “Getting bus success!” message in green .
The rest of the changes are down to swapping the serial port for a TCP socket.
The stability issue remains - the Wi-Fi isn't as reliable as the cable though, and I've seen that sometimes one of the flash commands doesn't execute correctly - I've added a retry transmission mechanism for this reason.
Screenshot of C# code with flash erase log, including one erase sector failure. .

This is what the whole process looks like for flash operations, here reading:
Console screenshot showing flash memory read from BK7231N device over Wi-Fi .

Verify operation .
Smallest test command - draws the data, writes it to the target, then reads it and compares it to the one at the beginning:

WiFiProgram.exe bk7231n -d 192.168.0.139:8888 -u -t -s 0x11000 -l 0x2000
.
In the screenshot is the result from the same but with offset 0, i.e. bootloader editing on BK7231N. This is not possible on the BK7231T - this will lose the ability to program via the UART and SPI will have to be used.
Terminal screenshot showing memory flashing process over UART TCP .
Same test for offset 0x11000 (application start):
Screenshot of terminal showing flash process of BK7231N via Wi-Fi TCP to UART .

Supported commands .
The new flasher has basic commands to operate on the flash. These include reading memory, writing, verification (comparison with a given file) and a memory test based on writing and reading a random sequence of bytes. A short readme follows:

usage: wifiprogram bk7231n [-h] [-d DEVICE] [-s STARTADDR] [-l LENGTH] [-b BAUDRATE]
                   [-u] [-r] [-w] [-p]
                   filename

OBK WiFi Downloader.

positional arguments:
  filename              specify file_crc.bin

optional arguments:
  -h, --help            show this help message and exit
  -d DEVICE, --device DEVICE
                        Target device, default 192.168.0.1:8888
  -s STARTADDR, --startaddr STARTADDR
                        burn flash address, defaults to 0x11000
  -l LENGTH, --length LENGTH
                        length to read, defaults to 0x1000
  -b BAUDRATE, --baudrate BAUDRATE
                        burn uart baudrate, defaults to 921600
  -u, --unprotect       unprotect flash first, used by BK7231N
  -r, --read            read flash
  -w, --write           write flash
  -t, --test            test flash (generate pattern, write, read, verify)
  -v, --verify           verify flash
  
     
     
        Flash BK7123N (-w, --write, start address 0x0)
        wifiprogram bk7231n -d 192.168.0.139:8888 -w -s 0 -u OpenBK7231N_QIO_1.18.193.bin
        Read BK7231N (-r, read):
        wifiprogram bk7231n -d 192.168.0.139:8888 -r -s 0 -l 0x200000 firmwarebackup.bin
        Short test (-t, --test, start address 0x0, len 0x2000):
        wifiprogram bk7231n -d 192.168.0.139:8888 -u -t -s 0 -l 0x2000
        Long test (1MB random data):
        wifiprogram bk7231n -d 192.168.0.139:8888 -u -t -s 0 -l 0x100000
.
Repository:
https://github.com/openshwprojects/WiFiFlasher


The "getting bus" operation takes quite a long time, I don't know how to get the timings correct. The flasher on the UART has no such problem with this. This is an issue to be solved.

Further plans .
This option will be integrated into the main flasher:
https://github.com/openshwprojects/BK7231GUIFlashTool
Ultimately, I will test this with plaforms other than BK7231.

Summary .
Being able to use a second Wi-Fi module as a programmer has its pros and cons. The pros include better automation of the process (not every USB to UART converter has extra lines to control possible RESET/CEN/BOOT pins), flashing a device connected to the network (many IoT devices have non-isolated converters, so you can't just program them with the main power connected) and convenience (no need to pull a USB cable). Of the downsides at the moment, I can see a potential problem with the get bus operation, but this only applies to Beken, and trouble with less precise timing in general - this is to be determined.
It's worth bearing in mind that the whole thing could be greatly improved by implementing the flasher on the target Wi-Fi chip, as at the moment it's simply in the role of TCP bridge to UART, but that may be some day.
@divadiow @insmod let us know if it works for you.

PS: Newer versions may be available here: https://github.com/openshwprojects/WiFiFlasher
Attachments:
  • 20251014-1049.zip (911.96 KB) You must be logged in to download this attachment.

About Author
p.kaczmarek2
p.kaczmarek2 wrote 14342 posts with rating 12243 , helped 649 times. Been with us since 2014 year.

Comments

divadiow 14 Oct 2025 20:44

thanks for the explainer. I didn't *quite* understand the process from the posts on in the other where this idea was born. I actually didn't know what the UartTCP driver was for (!) I'm a fan of soldering... [Read more]

p.kaczmarek2 14 Oct 2025 21:05

UartTCP driver opens a serial port on WiFi module (for example, UART 1 on Beken), and a TCP socket. Then, you can connect to this TCP socket, even with Putty - in "raw" mode. And whatever you will send... [Read more]

divadiow 14 Oct 2025 21:17

cool P7 as Relay:0. Host device running version uart_95b02ee83a21 on the left. 2 CB3S modules. micro-USB for power only - ie no onboard USB-TTL in use. https://obrazki.elektroda.pl/1788324900_1760469136_thumb.jpg... [Read more]

p.kaczmarek2 14 Oct 2025 21:30

Hehe, I didn't think it will actually work that good. Maybe it can be useable. Have you tried higher baud rates? Once I port this approach to Easy Flasher, we should be able to flash all Easy-supported... [Read more]

divadiow 14 Oct 2025 22:14

interesting wifiprogram bk7231n -d 192.168.137.92:8888 -w -b 9216000 -s 0 -u OpenBK7231N_QIO_1.18.194.bin https://obrazki.elektroda.pl/4939713900_1760471924_thumb.jpg not sure final cen is... [Read more]

p.kaczmarek2 14 Oct 2025 22:23

I can see a problem. This: 11000 Is a decimal number, not hexadecimal. You need to put it like: 0x11000 You're lucky that I added this protection. You'd overwrite bootloader at 11000... [Read more]

divadiow 14 Oct 2025 22:28

lol ok. can always SPI fix. wifiprogram bk7231t -d 192.168.137.46:8888 -w -s 0x11000 -u OpenBK7231T_UA_1.18.194.bin https://obrazki.elektroda.pl/8763960600_1760473712_thumb.jpg [Read more]

p.kaczmarek2 14 Oct 2025 22:44

Oh I see, I didn't test it with T, and the offset is unncessary divided by sector size. I pushed a fix, I will also fix online build if it's still broken. https://github.com/openshwprojects/WiFiFlasher My... [Read more]

divadiow 14 Oct 2025 23:03

'fx' build. https://obrazki.elektroda.pl/5681738600_1760475807_thumb.jpg [Read more]

p.kaczmarek2 14 Oct 2025 23:38

I don't remember T platform much, but as far as I know, the unprotect step (switch -u) is not supported there. That's how Easy Flasher does it as well. [Read more]

divadiow 15 Oct 2025 07:32

forget that. autoCEN worked just now with successful T flash after removing -u argument. I got bored after 50 tries and hit RST a few times, flashed fine at 115200 and AP broadcast after. Letting it run... [Read more]

FAQ

TL;DR: Replace the USB‑UART dongle with a second Wi‑Fi module running OpenBeken’s UartTCP (TCP port 8888). “At least it works.” Use it to read/write BK7231 flash over Wi‑Fi. [Elektroda, p.kaczmarek2, post #21719847]

Why it matters: It lets you program mains‑powered IoT devices safely and automate reset/boot control without a USB‑TTL.

Who this is for: Tinkerers and engineers flashing BK7231‑based IoT hardware who want a cable‑free, scriptable workflow.

Quick Facts

What is this Wi‑Fi UART programmer approach?

It uses a spare Wi‑Fi module with OpenBeken as a TCP‑to‑UART bridge to flash another device over the network. You still solder RX/TX, 3.3 V, and GND, but you skip the USB‑TTL and gain easy reset/boot control through GPIO. It is the first working iteration, focused on BK7231. “At least it works.” [Elektroda, p.kaczmarek2, post #21719847]

How does the UartTCP driver work, in plain English?

UartTCP opens a TCP socket on the programmer module and binds it to its UART1. Data sent to the TCP port goes out UART; data received on UART returns over TCP. You can even connect with PuTTY in raw mode to see bytes pass through. [Elektroda, p.kaczmarek2, post #21720469]

What hardware do I need to start?

You need two Wi‑Fi modules (e.g., CB3S/CB2S). One runs OpenBeken with UartTCP enabled; the other is the target. Provide common 3.3 V and GND, and wire RX↔TX. Add one GPIO on the programmer as “Relay” to the target’s CEN pin for resets. [Elektroda, p.kaczmarek2, post #21719847]

How do I wire the programmer to the target correctly?

Connect programmer TX to target RX, programmer RX to target TX, common ground, and shared 3.3 V. Wire a programmer GPIO (role “Relay”) to the target CEN pin for reset control. Keep leads short and stable for higher baud reliability. [Elektroda, p.kaczmarek2, post #21719847]

How do I start the TCP bridge and set the UART baud?

Send a HTTP cmnd using the OpenBeken interface. Example sequence: stopDriver UartTCP; startDriver UartTCP 8192. The flasher automates this by issuing the backlog command before connecting the TCP socket. [Elektroda, p.kaczmarek2, post #21719847]

How do I trigger CEN/reset automatically to catch bootloader mode?

Map a GPIO as “Relay” on channel 0 and wire it to CEN. Then toggle it: setChannel 0 0; setChannel 0 1. The window is short, so the tool issues the toggle and immediately attempts to get the bus. [Elektroda, p.kaczmarek2, post #21719847]

What commands does the WiFi flasher support today?

The CLI covers read, write, verify, unprotect (for N), and a test routine that writes random bytes, reads back, and compares. It accepts device IP:port, start address, length, and baud settings. Examples are shown for both short and long tests. [Elektroda, p.kaczmarek2, post #21719847]

Does it work on BK7231T as well as BK7231N?

Yes, T flashes succeeded when not using the -u unprotect flag. The author noted unprotect is not supported on T, aligning with Easy Flasher behavior. Auto‑CEN also worked for T after removing -u. [Elektroda, p.kaczmarek2, post #21720644]

What proven baud rates should I try first?

115,200 baud is a safe first choice and demonstrated successful on BK7231T. Higher rates like 921,600 were attempted; catching CEN and stability depend on timing and Wi‑Fi conditions. A retry mechanism helps overcome transient failures. [Elektroda, divadiow, post #21720541]

How do I avoid the 0x11000 vs 11000 mistake?

Pass flash offsets in hexadecimal with 0x prefix. Using 11000 without 0x is decimal and can target the wrong region. A safeguard exists, but keep addresses explicit, e.g., -s 0x11000 for application start on BK7231T/N. [Elektroda, p.kaczmarek2, post #21720566]

Is Wi‑Fi reliable enough compared to a USB‑UART cable?

Cable is more deterministic, but Wi‑Fi worked with added retries. The author observed occasional command misfires and implemented retransmission to stabilize long writes. Expect slightly less precise timing than UART‑only workflows. [Elektroda, p.kaczmarek2, post #21719847]

What successful end‑to‑end result should I expect?

A full write with sector erases and verification. One run reported flash MID 1560EB (TH25Q16HB) and a capacity of 2 MB, followed by CRC match across 298 sectors. That indicates a clean burn. [Elektroda, divadiow, post #21720484]

What is OpenBeken in this setup?

OpenBeken is the firmware on the programmer module providing UartTCP, GPIO control, and the HTTP command interface used by the flasher. It turns the module into a configurable TCP‑UART bridge with scripting hooks. [Elektroda, p.kaczmarek2, post #21719847]

Any edge cases or failure facts I should know?

Getting bus is timing‑sensitive right after reset, so misses can occur. BK7231T rejects the unprotect step; remove -u. Decimal offset input can target unintended regions; guard with 0x. Retries handle sporadic Wi‑Fi drops. [Elektroda, p.kaczmarek2, post #21720644]

Will this flow come to other platforms or GUI tools?

Yes. The plan is to integrate the network flashing option into BK7231GUIFlashTool and test beyond BK7231. Watch the WiFiFlasher repo for newer builds. [Elektroda, p.kaczmarek2, post #21719847]

How do I perform a quick Wi‑Fi flash in three steps?

  1. Wire RX↔TX, 3.3 V, GND, and programmer GPIO (Relay) to target CEN.
  2. Start UartTCP at your baud; connect to IP:8888.
  3. Run: wifiprogram bk7231n -d :8888 -w -s 0x11000 -u . [Elektroda, p.kaczmarek2, post #21719847]
Generated by the language model.
%}