Skip to content

Contributed by sujingliang, organized by Ai-Thinker

[Ai-WB2 Review] Bafa Cloud MQTT

1. Platform Preparation

**1. Log in to https://bemfa.com/注册个用户**

The system assigns a private key.

2. Select the MQTT device cloud

3. Create a topic

Topic name: AIWB2002; the last 3 digits, 002, indicate the device is a light

Last three digitsDescription
001Socket device
002Light bulb device
003Fan device
004Sensor
005Air conditioner device
006Switch device
009Curtain device
010Thermostat
011Water heater
012TV
013Air purifier

2. Modify the Program

Use applications/protocols/mqtt/tcp as the template

1. main.c

Click to expand full code
java
#define ROUTER_SSID
"SSID"

#define ROUTER_PWD
"PWD"

Modify the Wi-Fi login SSID and password

  1. demo.c
Click to expand full code
java
void

mqtt_start
(
void
)

{
    pwm_led_init();
//pwm 初始化

axk_mqtt_client_config_t

mqtt_cfg

=
 {
        .uri =
"mqtt://bemfa.com"
,
//巴法云地址

        .port =
9501
,
//巴法云端口9501,不是1883

        .client_id =
"平台提供的私钥"
,
        .event_handle = event_cb,
//回调

    };

axk_mqtt_client_handle_t

client

=
 axk_mqtt_client_init(&mqtt_cfg);
    axk_mqtt_client_start(client);
}

The event_cb function

Click to expand full code
java
static
 axk_err_t
event_cb
(axk_mqtt_event_handle_t event)

{
...

case
 MQTT_EVENT_CONNECTED:
//MQTT建立连接事件

        blog_info(
"MQTT_EVENT_CONNECTED"
);

// 订阅主题(如 light001)

        axk_mqtt_client_subscribe(client,
"AIWB2002"
,
0
);
//订阅前面注册的AIWB2002主题

break
;

case
 MQTT_EVENT_DATA:
//MQTT接收数据事件

        blog_info(
"MQTT_EVENT_DATA"
);
        printf(
"TOPIC=%.*s\r\n"
, event->topic_len, event->topic);
        printf(
"DATA=%.*s\r\n"
, event->data_len, event->data);

// 判断指令并控制 GPIO

if
 (strncmp(event->data,
"on#"
,
3
) ==
0
) {
//收到on#44,设置LED亮度为44

// 2. 提取亮度值(如 "44")

char
 brightness_str[
4
] = {
0
};

int

brightness

=

0
;
            strncpy(brightness_str, event->data +
3
, event->data_len -
3
);
            brightness = atoi(brightness_str);
// 字符串转整数

// 3. 限制亮度范围(0~255)

if
 (brightness <
0
) brightness =
0
;

if
 (brightness >
255
) brightness =
255
;

            rgb_control(
255
,
255
,
255
,brightness);
        }
else

if
 (strncmp(event->data,
"on"
, event->data_len) ==
0
) {
//收到on,设置LED亮度为255

            blog_info(
"Turn ON LED"
);
            rgb_control(
255
,
255
,
255
,
255
);
        }
// 处理关闭指令(如 "off")

else

if
 (strncmp(event->data,
"off"
, event->data_len) ==
0
) {
//收到off,设置LED亮度为0

            rgb_control(
255
,
255
,
255
,
0
);
            blog_info(
"Turn OFF LED"
);
        }

break
;

...
}

pwmled.c

Click to expand full code
java
#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include <bl602.h>
#include <bl602_gpio.h>
#include <bl602_glb.h>
#include <bl_pwm.h>
#include
"pwmled.h"

#define
PWM_Get_Channel_Reg
(ch)
  (PWM_BASE+PWM_CHANNEL_OFFSET+(ch)*
0x20
)
#define
PWM_STOP_TIMEOUT_COUNT

(
160
*
1000
)

GLB_GPIO_Cfg_Type cfg[
3
] = {
    {
        .drive =
0
,
        .smtCtrl =
1
,
        .gpioMode = GPIO_MODE_OUTPUT,
        .pullType = GPIO_PULL_DOWN,
        .gpioPin =
14
,
/// red

        .gpioFun =
8
,
    },
    {
        .drive =
0
,
        .smtCtrl =
1
,
        .gpioMode = GPIO_MODE_OUTPUT,
        .pullType = GPIO_PULL_DOWN,
        .gpioPin =
17
,
/// green

        .gpioFun =
8
,
    },
    {
        .drive =
0
,
        .smtCtrl =
1
,
        .gpioMode = GPIO_MODE_OUTPUT,
        .pullType = GPIO_PULL_DOWN,
        .gpioPin =
3
,
/// blue

        .gpioFun =
8
,
    },
};

/// @brief Copy from PWM_Smart_Configure. Use Bus Clock instead of External Crystal Clock for PWM Timer

/// @param ch PWM Channel

/// @param clkDiv PWM clock divider

/// @param period PWM period

/// @param threshold2

/// @return

BL_Err_Type
PWM_Smart_Configure2
(PWM_CH_ID_Type ch, uint16_t clkDiv, uint16_t period,uint16_t threshold2)

{
    uint32_t tmpVal;

uint32_t

timeoutCnt

=
 PWM_STOP_TIMEOUT_COUNT;

/* Get channel register */

uint32_t

PWMx

=
 PWM_Get_Channel_Reg(ch);

    tmpVal = BL_RD_REG(PWMx, PWM_CONFIG);

// if(BL_GET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL) != PWM_CLK_XCLK){

if
(BL_GET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL) != PWM_CLK_BCLK){
        BL_WR_REG(PWMx, PWM_CONFIG, BL_SET_REG_BIT(tmpVal, PWM_STOP_EN));

while
(!BL_IS_REG_BIT_SET(BL_RD_REG(PWMx, PWM_CONFIG), PWM_STS_TOP)){
            timeoutCnt--;

if
(timeoutCnt ==
0
){

return
 TIMEOUT;
            }
        }

// tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL, PWM_CLK_XCLK);

        tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL, PWM_CLK_BCLK);
    }
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_OUT_INV, PWM_POL_NORMAL);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_STOP_MODE, PWM_STOP_GRACEFUL);
    BL_WR_REG(PWMx, PWM_CONFIG, tmpVal);

/* Config pwm division */

    BL_WR_REG(PWMx, PWM_CLKDIV, clkDiv);

/* Config pwm period and duty */

    BL_WR_REG(PWMx, PWM_PERIOD, period);
    BL_WR_REG(PWMx, PWM_THRE1,
0
);
    BL_WR_REG(PWMx, PWM_THRE2, threshold2);

return
 SUCCESS;
}

void

pwm_led_init
(
void
)

{

for
 (
int

i

=

0
; i <
3
; i++) {
        GLB_GPIO_Init(cfg + i);

PWM_CH_ID_Type

ch

=
 cfg[i].gpioPin % PWM_CH_MAX;
        PWM_Channel_Disable(ch);
    }
}

void

pwm_led_set
(uint8_t red,uint8_t green,uint8_t blue)

{
    PWM_Smart_Configure2(
2
,
80
,
255
, green);
    PWM_Channel_Enable(
2
);

    PWM_Smart_Configure2(
3
,
80
,
255
, blue);
    PWM_Channel_Enable(
3
);

    PWM_Smart_Configure2(
4
,
80
,
255
, red);
    PWM_Channel_Enable(
4
);

}

void

rgb_control
(uint8_t red, uint8_t green, uint8_t blue,  uint8_t alpha)

{
    uint8_t t_red,t_green,t_blue;

// 应用透明度/亮度

    t_red = red*alpha/
255
;
    t_green = green*alpha/
255
;
    t_blue = blue*alpha/
255
;

    pwm_led_set(t_red,t_green,t_blue);
}

3. Running

Bafa Cloud mini program

MQTTX debugging

4. XiaoDu Speaker + Bafa

The order of the pictures below is mixed up. The flow is: XiaoDu APP on the phone -> My -> Go to My Home -> + Add Device -> search for "Bafa" -> tap the created device "Light"

Then you can use the XiaoDu speaker to control the light by voice.

For example: "XiaoDu XiaoDu, turn on the light."

Released under the MIT License. Build Time 2026-09-11 14:52:23