logo elektroda
logo elektroda
X
logo elektroda

PWM Groups (synchronized PWMs) driver for OpenBeken - BK7231N - with dead time

p.kaczmarek2 2643 5

TL;DR

  • OpenBeken 1.17.388 adds a BK7231N PWM Groups driver that synchronizes two PWMs, supports independent duty cycles, and inserts a configurable dead time.
  • The timings are calculated from the main oscillator frequency, with duty values treated as percentages and frequency treated as Hz.
  • A typical command is PWMG_Set 10 10 10 1000, and PinA/PinB use P-index values such as 6 and 7.
  • The revised implementation fixes the SDK bugs and works correctly in tests, including when a 0 duty cycle is used.
  • Range checking is still missing, and behavior for PWMs outside the same pair has not been tested.
Generated by the language model.
ADVERTISEMENT
📢 Listen (AI):
  • Oscilloscope display showing PWM waveforms on a RIGOL screen.
    In the 1.17.388 version, OpenBeken introduced a PWM Groups driver. This driver enables the synchronization of two PWMs and facilitates setting a specified dead time between them. Of course, the duty cycles of each PWM groups are independently controlled and the frequency is also adjustable.


    Tuya's (Beken?) implementation
    The PWM groups driver is present in the used BK7231N SDK, but after few quick tests it's clear that's it not working correctly:
    Code: C / C++
    Log in, to see the code

    There are multiple issues with this code:
    - the second duty cycle is not used at all and both PWMs are using duty_cycle1
    - the frequency variable is not in fact a frequency, but rather a period
    - the following implementation breaks when a 0 duty_cycle is given


    My improvements
    I've performed some tests with the original version of the code, also by manually setting values for each PWM:
    Code: C / C++
    Log in, to see the code

    Result:
    Oscilloscope displaying PWM signal waveforms.

    Test code:
    Code: C / C++
    Log in, to see the code

    results:
    Oscilloscope screen displaying two synchronized PWM signals with dead time.

    Test code:
    Code: C / C++
    Log in, to see the code

    Result:
    View of Rigol oscilloscope screen with PWM signals

    Test code:
    Code: C / C++
    Log in, to see the code

    Result:
    Oscilloscope display showing PWM waveforms on a RIGOL screen.
    It seems that duty_cycle1, duty_cycle2 and duty_cycle3 describes when a PWM toggles self state. Based on that, I proposed the following implementation:
    Code: C / C++
    Log in, to see the code

    The code above still uses the incorrect name for period variable (it's called frequency), but I also resolved it.
    The tests have shown that the period and duty cycles should be calculated on the main oscillator frequency basis:
    Code: C / C++
    Log in, to see the code

    The duty values are assumed to be in percent and frequency is in Hz. The period values are calculates from them.

    Usage
    To use it in OBK, you need a BK7231N device. First, enable driver:
    
    startDriver PWMG

    Then, start the group:
    
    PWMG_Set 10 10 10 1000
    

    Full command syntax is the following:
    
    PWMG_Set Duty1Percent Duty2Percent DeadTimePercent Frequency PinA PinB
    

    Please note that the following will only work correctly for PWM pairs, like PWM0+PWM1, PWM2+PWM3, etc.
    Futhermore, for PinA/PinB you need to give a P-index, so PWM0 is not 0, it's 6.
    Please see screenshot below for explanation:
    Table showing GPIO interfaces and their corresponding IC pins.
    Of course, when typing command, type just "6", not "P6", like:
    
    PWMG_Set 10 10 10 1000 6 7
    


    Examples
    Command (1000Hz, 10% first, second 10%, dead 10%):
    
    PWMG_Set 10 10 10 1000
    

    Result:
    Oscilloscope display showing a PWM signal waveform.

    Command (1000Hz, 50% first, second 10%, dead 10%):
    
    PWMG_Set 50 10 10 1000
    

    Result:
    Rigol DS1054Z oscilloscope displaying PWM signals

    Command (5000Hz, 10% first, second 10%, dead 10%):
    
    PWMG_Set 10 10 10 5000
    

    Result:
    Oscilloscope screen displaying a PWM signal waveform.


    Summary
    PWM groups driver is now working, altough it still could be improved a bit. For example, the code is not currently checking for out of range values, and using them may yield unexpected results. Futhermore I have not tested how PWM behaves when user specified two PWMs that are not from the same group.
    The PWM groups driver was added per user request here, but I hope it can be useful for more people as well. Do you have any ideas how could you use such a driver? Let us know.

    Cool? Ranking DIY
    Helpful post? Buy me a coffee.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    p.kaczmarek2 wrote 14570 posts with rating 12584, helped 654 times. Been with us since 2014 year.
  • ADVERTISEMENT
  • #2 20888493
    niclauser
    Level 4  
    Posts: 5
    Thank you very much for creating the driver. I will test it in my project and report here.
  • ADVERTISEMENT
  • #3 20888500
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14570
    Help: 654
    Rate: 12584
    You're welcome, I think I will still take some time tomorrow to improve it futher, because with the current state of things, it's possible to "break" dead time by setting too high duty cycles for both PWMs. I think I will add an extra check for that in code that enforces dead time when incorrect arguments are passed.

    Do you have oscilloscope?
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #4 20976850
    niclauser
    Level 4  
    Posts: 5
    Hello,

    Unfortunately, I've only recently gotten around to testing the new function again. I flashed a PEARL light chain ZX-5140-675 with Open Beken.

    See also my query here:
    https://www.elektroda.com/rtvforum/topic4010285.html#20840633

    The result is wonderful and you did a great job!!!

    By changing the values I was able to create different flashing frequencies for the fairy lights. Whatever is possible now, all the LEDs in the light chain are now easier, which was previously impossible due to the reverse parallel connection of the LEDs. Please watch the short video below.

    My problem, how can I switch the PWM groups on and off centrally? And would it be possible to integrate appropriate controls into the interface to adjust the frequencies? (Just like the light - dark - or the color controls on LED bulbs)












  • ADVERTISEMENT
  • #5 20990147
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14570
    Help: 654
    Rate: 12584
    That's a good news!

    What do you mean by "centrally"?

    You can script the device behaviour in autoexec.bat, see samples:
    https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/autoexecExamples.md
    You can also create a custom REST page for your device:
    https://www.elektroda.com/rtvforum/topic3971355.html
    Everything depends on your particular use case. Do you prefer to control your lights via Home Assistant or directly from OpenBeken?
    Helpful post? Buy me a coffee.
  • #6 20990894
    niclauser
    Level 4  
    Posts: 5
    By central I meant like an LED light bulb, an on/off switch and sliders for flashing frequency and light/dark.

    I prefer the control directly via OpenBeken.
📢 Listen (AI):

FAQ

TL;DR: At 1000 Hz and 10%/10%/10% settings, OpenBeken’s PWM Groups driver lets BK7231N generate two synchronized PWM outputs with dead time; as the author noted, "PWM groups driver is now working." This helps users who need complementary waveforms for LED chains or similar loads without writing low-level PWM timing by hand. [#20888311]

Why it matters: It turns a flawed BK7231N SDK group-PWM routine into a practical OpenBeken feature for synchronized outputs, safer switching gaps, and easier control of reverse-parallel LED loads.

Wariant Oryginalny SDK Tuya/Beken Ulepszona implementacja OpenBeken
Obsługa dwóch wypełnień Używał tylko duty_cycle1 dla obu kanałów Obsługuje duty_cycle1 i duty_cycle2 osobno
Nazwa zmiennej frequency Faktycznie oznaczała okres Autor przelicza Hz na okres jawnie
Przypadek 0% duty Potrafił się psuć Dodano bezpieczne gałęzie dla 0%
SposĂłb uĹĽycia Niejednoznaczny Komenda PWMG_Set Duty1 Duty2 Dead Freq PinA PinB

Key insight: BK7231N PWM Groups działa poprawnie dopiero wtedy, gdy liczysz wartości z zegara 26 MHz, traktujesz „frequency” jako okres i pilnujesz, by dwa wypełnienia plus dead time nie nachodziły na siebie.

Quick Facts

  • OpenBeken added the PWM Groups driver in version 1.17.388, targeting BK7231N and synchronized two-channel PWM with configurable dead time. [#20888311]
  • The command syntax is PWMG_Set Duty1Percent Duty2Percent DeadTimePercent Frequency PinA PinB; the example PWMG_Set 10 10 10 1000 6 7 uses 10%, 10%, 10%, 1000 Hz, and P-indexes 6 and 7. [#20888311]
  • OpenBeken converts frequency to period with period = 26000000 / freq, so timing is derived from the 26,000,000 Hz main oscillator. [#20888311]
  • Correct operation is expected on grouped PWM pairs such as PWM0+PWM1 and PWM2+PWM3; the thread explicitly warns that non-paired selections may not behave correctly. [#20888311]
  • A tested real-world use case was a PEARL light chain ZX-5140-675, where synchronized PWM made reverse-parallel LEDs easier to control and enabled different flashing frequencies. [#20976850]

What is the PWM Groups driver in OpenBeken, and how does it synchronize two PWMs with dead time on the BK7231N?

The PWM Groups driver is an OpenBeken feature for BK7231N that runs two PWM outputs in sync and inserts a defined dead time between them. It was introduced in version 1.17.388. The improved routine sets separate timing points for each channel and enables grouped mode when the channels form a valid pair. In practice, it lets one PWM switch after the other instead of overlapping immediately, which is useful for complementary outputs. [#20888311]

How do I enable and use the PWMG driver in OpenBeken to generate synchronized PWM outputs with dead time?

Enable the driver, then call PWMG_Set with percentages and frequency. 1. Run startDriver PWMG. 2. Start a group with PWMG_Set 10 10 10 1000. 3. If needed, specify pins explicitly, for example PWMG_Set 10 10 10 1000 6 7. The full syntax is PWMG_Set Duty1Percent Duty2Percent DeadTimePercent Frequency PinA PinB. Default example values are 10%, 10%, 10%, and 1000 Hz. [#20888311]

Why did the original BK7231N SDK bk_pwm_group_initialize implementation use the same duty cycle for both PWM channels, and how was that fixed?

The original BK7231N SDK code ignored the second duty argument and effectively drove both PWMs from duty_cycle1. The author identified that duty_cycle2 was not used at all. The fix was to map each PWM to its own calculated toggle points, so channel A uses one duty value and channel B uses the other. That change made examples like 50% on the first PWM and 10% on the second work as intended. [#20888311]

What does dead time mean in synchronized PWM signals, and why is it important for electronics projects?

Dead time is a short non-overlap interval inserted between two synchronized PWM transitions. "Dead time" is a PWM timing parameter that creates a deliberate gap between switching events, preventing the two related outputs from changing state at the same instant. In this thread, users set it as a percentage, such as 10%, and OpenBeken applies it between the paired signals. That matters because overlapping complementary outputs can break the intended waveform and cause invalid switching behavior. [#20888311]

Why does the original Tuya/Beken PWM group code break when one duty cycle is set to 0, and how can that case be handled safely?

It breaks because the original logic assumed a nonzero duty and still wrote toggle values that depended on that duty. The author explicitly noted that the implementation fails when a 0 duty cycle is given. The safer fix is simple: when duty_cycle1 or duty_cycle2 is 0, set duty_cycle1, duty_cycle2, and duty_cycle3 in the PWM parameters to 0 and force the initial output level appropriately. That prevents bogus toggle timing. [#20888311]

How are frequency in Hz, duty cycle percentages, and dead time percentages converted into the BK7231N PWM period values used by OpenBeken?

OpenBeken first converts frequency in Hz to a period count, then scales duty and dead time from percentages into that period. The code uses period = 26000000 / freq. It then calculates duty1_s, duty2_s, and dead_s as percent-of-period values. For example, at 1000 Hz the period is derived from the 26 MHz oscillator, and 10% duty becomes 10% of that count. This removes the earlier confusion where the variable named frequency really held a period. [#20888311]

Which PWM pin pairs work correctly with OpenBeken PWM Groups on BK7231N, and why do only grouped pairs like PWM0+PWM1 or PWM2+PWM3 matter?

Grouped pairs such as PWM0+PWM1 and PWM2+PWM3 are the combinations expected to work correctly. The thread states that the feature will only work correctly for PWM pairs like those. The initialization also enables group mode only when the second PWM is exactly the next channel, meaning (pwm1 + 1) == pwm2. If you choose channels outside a hardware pair, the author had not verified correct synchronization behavior. [#20888311]

What is a P-index in OpenBeken pin mapping, and how do I choose the right PinA and PinB values for PWMG_Set?

A P-index is the OpenBeken pin-numbering value you pass into commands instead of the PWM channel number. "P-index" is a pin-mapping identifier that selects a physical device pin inside OpenBeken, not the logical PWM unit number, so command arguments must use board pin indexes such as 6 or 7. The thread gives a direct warning: PWM0 is not entered as 0, but as P-index 6. That is why the example uses 6 7 for PinA and PinB. [#20888311]

How does the improved OpenBeken PWM Groups implementation differ from the original Tuya/Beken SDK version for BK7231N?

The improved OpenBeken version fixes three practical issues in the original SDK code. First, it uses separate duty values for both channels. Second, it handles 0% duty safely with explicit zero branches. Third, it converts user inputs from percent and Hz into the period counts expected by the hardware. The author also noted that the original variable name frequency was misleading because it actually represented period, and that was corrected conceptually in the command-side calculations. [#20888311]

What causes dead time to break when both PWM duty cycles are set too high, and what range checks should be added to prevent invalid settings?

Dead time breaks when the two requested on-times plus the dead-time gap exceed the available period. The author said the current code can still "break" dead time if both PWM duty cycles are set too high. A practical check should reject or clamp any setting where duty1 + duty2 + dead exceeds the usable period budget. Without that guard, the toggle points can overlap or appear in the wrong order, producing an invalid waveform. [#20888500]

How can I switch PWM groups on and off centrally in OpenBeken and create user controls like an on/off button plus sliders for flashing frequency and light/dark timing?

Use OpenBeken’s own scripting or interface features so one control updates the PWMG command values centrally. The user asked for controls like an LED bulb UI: on/off plus sliders for flashing frequency and light-dark timing. The reply suggested two direct OpenBeken paths: script behavior in autoexec.bat or build a custom REST page. Those approaches let you expose a single control layer while keeping the synchronized PWM logic underneath. [#20990147]

What’s the best way to build a direct OpenBeken control interface for PWM group settings: autoexec.bat scripts or a custom REST page?

For direct OpenBeken control, a custom REST page is the better fit for on/off buttons and sliders, while autoexec.bat suits startup logic and automation. The author presented both options after the user said they preferred direct control from OpenBeken rather than Home Assistant. If you want a bulb-like interface for frequency and light-dark adjustment, a custom page matches that goal more closely. If you only need automatic presets at boot, script files are simpler. [#20990147]

How can synchronized PWM groups help control reverse-parallel LED light chains like the PEARL ZX-5140-675 flashed with OpenBeken?

They let you drive both halves of a reverse-parallel LED chain more flexibly, including different flashing frequencies that were previously hard to achieve. A user tested the feature on a PEARL light chain ZX-5140-675 and reported that the result was "wonderful." They specifically said all LEDs in the chain became easier to control because the reverse-parallel connection had made that impossible before. That makes synchronized PWM Groups a practical solution for decorative lighting patterns. [#20976850]

What is the difference between PWM frequency and PWM period in BK7231N/OpenBeken code, and why does misnaming that variable cause confusion?

Frequency is how many cycles occur per second, while period is the count or duration of one cycle. In the original routine, the variable named frequency actually held the period value used by the PWM hardware. That is confusing because users enter frequency in Hz, such as 1000 or 5000, but the hardware logic needs a period derived from 26 MHz. Misnaming the variable hides the required conversion and makes debugging duty calculations harder. [#20888311]

How should I troubleshoot OpenBeken PWM Groups on BK7231N when the waveform looks wrong on an oscilloscope or the two outputs are not properly synchronized?

Check pairing, math, and limits in that order. 1. Verify you selected a valid grouped pair such as PWM0+PWM1 and used the correct P-indexes like 6 and 7. 2. Confirm your Hz and percentage inputs were converted from the 26 MHz base clock into period counts. 3. Reduce duty values if duty1 + duty2 + dead is too large, because excessive values can break dead time. The author also asked the tester whether they had an oscilloscope, which shows waveform inspection was a key validation method. [#20888500]
Generated by the language model.
ADVERTISEMENT