Overview
Alibaba Cloud IoT Platform (IoT Platform = a cloud-side device management console; after the device connects, you can see its status and send commands to it from the web console) is Alibaba Cloud's one-stop device access and management cloud service; devices exchange messages with it over MQTT (the most mainstream lightweight messaging protocol in IoT). This tutorial uses the official ali_iot example project to connect the Ai-WB2 to the Alibaba Cloud IoT Platform: after connecting, the device automatically reports properties (reporting = device→cloud data); the example also integrates OTA (over-the-air upgrade, updating the program remotely without a data cable) and NTP (network time sync) features.
In plain words: the Alibaba Cloud IoT Platform is like the "WeChat server" — the board is the user; after logging in with the platform-issued "account and password" (the triple: ProductKey, DeviceName, DeviceSecret), it can "post moments" (report properties — the cloud sees your status) and "receive private messages" (commands sent down from the platform). This tutorial walks you through registering an account, creating a product and device, getting the triple, and getting the board to successfully "log in" to Alibaba Cloud.
This tutorial is based on the official Ai-Thinker SDK (Ai-Thinker-Open/Ai-Thinker-WB2, version
release_bl_iot_sdk_1.6.40) exampleapplications/iot-solution/ali_iot; the code can be found directly in the local SDK.
This step “registers the account” on the cloud side: create the product and device, and get the triple (ProductKey/DeviceName/DeviceSecret) the device uses to log into the platform.
- Open the Alibaba Cloud official website, register and log in (new users need real-name verification).
- Search “IoT Platform” in the console and enter the IoT Platform console (on first entry you need to activate the service; a public instance is fine, no purchase needed).
- Click “Create Product”: pick any product name (e.g.
WB2_Light), choose the custom category for category, Wi-Fi for connection method, and ICA standard data format for data format. - After creation, you can see the ProductKey on the product detail page — this is the product’s “account”.
- Go to “Device Management → Add Device”, enter a device name (e.g.
wb2_test); after creation the DeviceName and DeviceSecret are shown.
💡 The triple = ProductKey + DeviceName + DeviceSecret, the “account and password” for the board to log into the cloud platform — it goes into the code in the next steps. The DeviceSecret is shown only once at device creation — copy and save it immediately; if lost, you can only re-add the device.
Open a terminal and enter the official ali_iot example project directory:
cd ~/Ai-Thinker-WB2/applications/iot-solution/ali_iot
Note:
cdis the “change directory” command — entering the official example project; all subsequentmakecommands must run in this directory.
📌 This project consists of multiple source files; the Full Code section only shows
main.c— the rest can be found in the official project. Let’s get familiar with them first:
| File | Purpose |
|---|---|
main/main.c |
Main program: Wi-Fi connection + starting MQTT, the main file this tutorial looks at |
ali_cloud/ali_mqtt/ali_mqtt_init.c |
MQTT connection core: the triple is configured here, plus pub/sub examples |
ali_cloud/ali_ota/ali_ota_init.c |
OTA firmware upgrade (firmware = the program flashed into the board); the version number is configured in ali_ota_init.h |
ali_cloud/ali_ntp/ali_ntp_init.c |
NTP network time sync (automatically calibrates the board clock from the cloud) |
ali_cloud/ali_csdk/ |
Alibaba’s official C-SDK (where the aiot_mqtt_* interfaces live) |
Open main/main.c and change the Wi-Fi account and password at the top (placeholder = the example values pre-written in the code; you need to replace them with your real ones):
#define ROUTER_SSID "WIFI SSID"
#define ROUTER_PWD "WIFI PWS"
Open ali_cloud/ali_mqtt/ali_mqtt_init.c and replace the example triple with the values you got from creating the device in the console:
char *product_key = "你的ProductKey";
char *device_name = "你的DeviceName";
char *device_secret = "你的DeviceSecret";
⚠️ The most common pitfall: in
ali_mqtt_init.c, the topic used bypub_msg()for reporting (topic = channel name; messages are sent/received by channel) and the subscription topic also have the example triple hard-coded (/sys/a1Rq1D1yQnu/bl602-test/...). If you only change the three variables above and not these two topics, the platform rejects the messages because the channel name belongs to someone else’s account. Replacea1Rq1D1yQnuwith your ProductKey andbl602-testwith your DeviceName.
Optional: OTA firmware upgrade needs a version number — open ali_cloud/ali_ota/ali_ota_init.h and confirm PRJ_VERSION "1.0.0" is the version you want.
This tutorial uses the official example project — no new code needed; the complete main/main.c code has been moved to the end of this page:
📜 Full Code — in the “Full Code” section below, collapsed by default — click to expand, identical to the official example (
applications/iot-solution/ali_iot/main/main.c). The detailed MQTT connection logic is inali_cloud/ali_mqtt/ali_mqtt_init.c; the rest can be found in the official project.
Code highlights:
| Code | Purpose |
|---|---|
wifi_mgmr_sta_connect(if, ssid, pwd, ...) |
Makes the board connect to the router in STA mode (as a “client”); nothing works without the internet |
aos_register_event_filter(EV_WIFI, cb, NULL) |
Registers the Wi-Fi event callback (event = system notification); the system calls it whenever Wi-Fi has news |
aos_post_event(EV_WIFI, CODE_WIFI_ON_INIT_DONE, 0) |
Actively fires the “Wi-Fi init” event; without it the whole startup flow never begins |
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile) |
Hooks the Alibaba SDK’s low-level dependencies (memory/network) to this SDK; the SDK can’t run without it |
ali_mqtt_init() |
Creates the MQTT client and connects to Alibaba Cloud; the triple is configured in its file (ali_mqtt_init.c) |
Build in the project directory:
make -j8
Note:
makeis the “build” command, turning code into firmware (the program flashed into the board) the board can run;-j8builds with 8 parallel CPU cores, faster.
On success a firmware build_out/main.bin is generated.
⚠️ If it reports
riscv64-unknown-elf-gcc: command not found, the toolchain permissions aren’t configured — runcd toolchain/riscv/Linux && . chmod755.shfirst, then rebuild.
Keep the board connected via USB, confirm the serial device, and flash:
make flash p=/dev/ttyUSB0 b=921600
Note:
make flashis the “flash” command, writing the compiled firmware into the board’s chip. Afterp=comes the serial device (often/dev/ttyUSB0on Linux,COM3and the like on Windows — use your actual one, check withls /dev/ttyUSB*),b=921600is the flash baud rate (serial transfer speed), keep the default.
⏳ During flashing, press and hold the EN button on the board when prompted to enter download mode; wait for the progress bar to complete — that means the flash succeeded.
After flashing, the board automatically restarts: it connects to Wi-Fi first, then to Alibaba Cloud. Open the serial monitor (a serial debugging assistant app, baud rate 921600 — the baud rate is the “speaking speed” of the serial, both sides must match) and you should see:
[APP] [EVT] GOT IP ...
Start linkkit mqtt
aiot_mqtt_connect successs
AIOT_MQTTEVT_CONNECT
sub data from server
Meanwhile open the Alibaba Cloud IoT Platform console → Product → Device Management — your device status changes to “Online”; on the “Thing Model Data” page you can see the reported property records (the official example triggers a report on each start_update_data() call; the sample property is Power=on).
Seeing aiot_mqtt_connect successs and AIOT_MQTTEVT_CONNECT (“successs” is the official example’s original print — it has an extra s), and the console showing the device online, means success; if you only see GOT IP without the connection-success logs, it hasn’t succeeded yet — check the FAQ at the end.
API Summary for This Tutorial
ali_mqtt_init()
Initializes the Alibaba Cloud MQTT client and establishes the connection to the platform (project-custom interface, source in ali_cloud/ali_mqtt/ali_mqtt_init.c; internally uses the aiot_mqtt_* series to create, configure, connect, subscribe and spawn threads).
Parameters:
- None (the triple is configured as globals at the top of
ali_mqtt_init.c)
Return: 0 on success; -1 on failure
start_update_data()
Triggers one property report: signals the report semaphore; the aiot_mqtt_send_thread thread calls pub_msg() to publish properties to the platform (project-custom interface, source in ali_cloud/ali_mqtt/ali_mqtt_init.c).
Parameters:
- None
Return: none
aiot_mqtt_stop()
Disconnects the MQTT connection, destroys the client instance and frees resources (project-custom interface, source in ali_cloud/ali_mqtt/ali_mqtt_init.c).
Parameters:
- None
Return: 0 on success; -1 on failure
aiot_mqtt_init()
Creates 1 Alibaba Cloud MQTT client instance and initializes default parameters (Alibaba official SDK interface, header ali_cloud/ali_csdk/core/aiot_mqtt_api.h).
Parameters:
- None
Return: client handle (void *) on success; NULL on failure
aiot_mqtt_setopt(handle, option, data)
Configures MQTT client parameters: server address (HOST), port (PORT), the triple (PRODUCT_KEY/DEVICE_NAME/DEVICE_SECRET), security credentials, send/receive callbacks, etc.
Parameters:
handle: the client handle returned byaiot_mqtt_initoption: config option enum (AIOT_MQTTOPT_HOST,AIOT_MQTTOPT_PORT,AIOT_MQTTOPT_PRODUCT_KEY,AIOT_MQTTOPT_DEVICE_NAME,AIOT_MQTTOPT_DEVICE_SECRET,AIOT_MQTTOPT_NETWORK_CRED,AIOT_MQTTOPT_RECV_HANDLER,AIOT_MQTTOPT_EVENT_HANDLER, etc.)data: the value for the option (pass a string or numeric pointer per the option type)
Return: STATE_SUCCESS (0) on success; negative error code on failure
aiot_mqtt_connect(handle)
Establishes the MQTT connection to the Alibaba Cloud IoT Platform; the example auto-reconnects every 5 seconds on failure (aiot_mqtt_reconn).
Parameters:
handle: the client handle
Return: STATE_SUCCESS (0) on success; negative error code on failure (printable with the -0x%04X format)
aiot_mqtt_pub(handle, topic, payload, payload_len, qos)
Publishes a message to the given topic (topic = channel name); the cloud/device subscribed to that topic all receive it.
Parameters:
handle: the client handletopic: topic string, format/sys/${productKey}/${deviceName}/thing/event/property/postpayload: message data pointer (JSON-format property packet in this example)payload_len: message lengthqos: QoS level (0at-most-once /1at-least-once); this example passes0
Return: STATE_SUCCESS (0) on success; negative error code on failure
aiot_mqtt_sub(handle, topic, handler, qos, userdata)
Subscribes to a topic; the handler callback (or the default receive callback) fires when the topic receives messages.
Parameters:
handle: the client handletopic: topic string, e.g./sys/${productKey}/${deviceName}/thing/event/property/post_replyhandler: the message callback for this topic; this example passesNULL(goes through the defaultaiot_mqtt_default_recv_handler)qos: QoS level; this example passes1userdata: user data passed through to the callback; passNULLif none
Return: STATE_SUCCESS (0) on success; negative error code on failure
wifi_mgmr_sta_connect(wifi_interface, ssid, psk, pmk, mac, band, chan_id)
Connects the board to the router in STA mode (as a "client") (Wi-Fi management interface, header components/network/wifi_manager/.../wifi_mgmr_ext.h).
Parameters:
wifi_interface: the STA interface handle returned bywifi_mgmr_sta_enable()ssid: the Wi-Fi namepsk: the Wi-Fi passwordpmk/mac/band/chan_id: pre-shared key, MAC, band, channel; this example passesNULL/0
Return: 0 on success; negative error code on failure
📌 In the Alibaba Cloud SDK's event callbacks don't do time-consuming operations (the example callback only prints); property report packets are JSON-format, and the fields must match the functions defined in the console's "Thing Model", otherwise the platform rejects them.
Full Code
Below is the complete main/main.c source, identical to the official example (applications/iot-solution/ali_iot/main/main.c) (the MQTT logic is in ali_cloud/ali_mqtt/ali_mqtt_init.c; the rest can be found in the official project):
📜 Click to expand the full main/main.c code
/*
* @Author: xuhongv@yeah.net xuhongv@yeah.net
* @Date: 2022-10-03 15:02:19
* @LastEditors: xuhongv@yeah.net xuhongv@yeah.net
* @LastEditTime: 2022-10-08 14:55:16
* @FilePath: \bl_iot_sdk_for_aithinker\applications\get-started\helloworld\helloworld\main.c
* @Description: Hello world
*/
#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
#include <string.h>
#include "blog.h"
#include <aos/yloop.h>
#include <aos/kernel.h>
#include <lwip/tcpip.h>
#include <wifi_mgmr_ext.h>
#include <hal_wifi.h>
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"
#include "aiot_ota_api.h"
#include "ali_mqtt_init.h"
/* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
void ali_linkkit_main(void)
{
TaskHandle_t xAliTaskHandle = NULL;
/* start linkkit mqtt */
printf("Start linkkit mqtt");
/* 配置SDK的底层依赖 */
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
ali_mqtt_init();
}
#define ROUTER_SSID "WIFI SSID"
#define ROUTER_PWD "WIFI PWS"
static wifi_conf_t conf =
{
.country_code = "CN",
};
static void wifi_sta_connect(char *ssid, char *password)
{
wifi_interface_t wifi_interface;
wifi_interface = wifi_mgmr_sta_enable();
wifi_mgmr_sta_connect(wifi_interface, ssid, password, NULL, NULL, 0, 0);
}
static void event_cb_wifi_event(input_event_t *event, void *private_data)
{
static char *ssid;
static char *password;
switch (event->code)
{
case CODE_WIFI_ON_INIT_DONE:
{
blog_info("[APP] [EVT] INIT DONE %lld", aos_now_ms());
wifi_mgmr_start_background(&conf);
}
break;
case CODE_WIFI_ON_MGMR_DONE:
{
blog_info("[APP] [EVT] MGMR DONE %lld", aos_now_ms());
//_connect_wifi();
wifi_sta_connect(ROUTER_SSID, ROUTER_PWD);
}
break;
case CODE_WIFI_ON_SCAN_DONE:
{
blog_info("[APP] [EVT] SCAN Done %lld", aos_now_ms());
// wifi_mgmr_cli_scanlist();
}
break;
case CODE_WIFI_ON_DISCONNECT:
{
blog_info("[APP] [EVT] disconnect %lld", aos_now_ms());
}
break;
case CODE_WIFI_ON_CONNECTING:
{
blog_info("[APP] [EVT] Connecting %lld", aos_now_ms());
}
break;
case CODE_WIFI_CMD_RECONNECT:
{
blog_info("[APP] [EVT] Reconnect %lld", aos_now_ms());
}
break;
case CODE_WIFI_ON_CONNECTED:
{
blog_info("[APP] [EVT] connected %lld", aos_now_ms());
}
break;
case CODE_WIFI_ON_PRE_GOT_IP:
{
blog_info("[APP] [EVT] connected %lld", aos_now_ms());
}
break;
case CODE_WIFI_ON_GOT_IP:
{
ali_linkkit_main();
blog_info("[APP] [EVT] GOT IP %lld", aos_now_ms());
blog_info("[SYS] Memory left is %d Bytes", xPortGetFreeHeapSize());
}
break;
case CODE_WIFI_ON_PROV_SSID:
{
blog_info("[APP] [EVT] [PROV] [SSID] %lld: %s",
aos_now_ms(),
event->value ? (const char *)event->value : "UNKNOWN");
if (ssid)
{
vPortFree(ssid);
ssid = NULL;
}
ssid = (char *)event->value;
}
break;
case CODE_WIFI_ON_PROV_BSSID:
{
blog_info("[APP] [EVT] [PROV] [BSSID] %lld: %s",
aos_now_ms(),
event->value ? (const char *)event->value : "UNKNOWN");
if (event->value)
{
vPortFree((void *)event->value);
}
}
break;
case CODE_WIFI_ON_PROV_PASSWD:
{
blog_info("[APP] [EVT] [PROV] [PASSWD] %lld: %s", aos_now_ms(),
event->value ? (const char *)event->value : "UNKNOWN");
if (password)
{
vPortFree(password);
password = NULL;
}
password = (char *)event->value;
}
break;
case CODE_WIFI_ON_PROV_CONNECT:
{
blog_info("[APP] [EVT] [PROV] [CONNECT] %lld", aos_now_ms());
blog_info("connecting to %s:%s...", ssid, password);
wifi_sta_connect(ssid, password);
}
break;
case CODE_WIFI_ON_PROV_DISCONNECT:
{
blog_info("[APP] [EVT] [PROV] [DISCONNECT] %lld", aos_now_ms());
}
break;
default:
{
blog_info("[APP] [EVT] Unknown code %u, %lld", event->code, aos_now_ms());
/*nothing*/
}
}
}
static void proc_main_entry(void *pvParameters)
{
aos_register_event_filter(EV_WIFI, event_cb_wifi_event, NULL);
hal_wifi_start_firmware_task();
aos_post_event(EV_WIFI, CODE_WIFI_ON_INIT_DONE, 0);
vTaskDelete(NULL);
}
void main()
{
puts("[OS] Starting TCP/IP Stack...");
tcpip_init(NULL, NULL);
puts("[OS] proc_main_entry task...");
xTaskCreate(proc_main_entry, (char *)"main_entry", 1024, NULL, 15, NULL);
}FAQ & Troubleshooting
⚠️ aiot_mqtt_connect successs / AIOT_MQTTEVT_CONNECT never appears
Cause: wrong triple (ProductKey/DeviceName/DeviceSecret don't match the cloud platform), product creation failed, or the Alibaba Cloud account isn't real-name verified / the service isn't activated
Fix: check the three variables in ali_mqtt_init.c against the console one by one (mind the case); confirm both the "product" and "device" exist and are activated in the console; confirm the IoT Platform service is activated
⚠️ Connected, but the console doesn't show reported properties
Cause: in ali_mqtt_init.c, the topic of pub_msg() and the subscription topic have the official example's triple hard-coded (/sys/a1Rq1D1yQnu/bl602-test/...) — the report went into someone else's "channel" and was rejected
Fix: replace a1Rq1D1yQnu with your ProductKey and bl602-test with your DeviceName in both topic strings; the property field names must match the console's "Thing Model" definitions
⚠️ Keeps printing Connecting, no GOT IP (can't connect to the router)
Cause: ROUTER_SSID/ROUTER_PWD wrong in main/main.c, the router is on 5GHz, or the signal is too weak
Fix: check the Wi-Fi account and password; confirm the router broadcasts 2.4GHz; move the board near the router; you can first run Connect Wi-Fi alone to verify internet access
⚠️ Serial device not found / can't open
Cause: USB-to-serial driver not installed, insufficient permission, or the cable only charges and can't transfer data
Fix: on Linux check with lsusb/dmesg; if permission denied run sudo usermod -aG dialout $USER and log back in, or sudo chmod 666 /dev/ttyUSB0; on Windows install the driver and check the COM port in Device Manager; try a data-capable cable
⚠️ Flashing keeps waiting / fails
Cause: didn't enter download mode, wrong baud rate, or wrong serial number
Fix: press and hold EN during flashing to enter download mode as prompted; confirm p=/dev/ttyUSB0 is your actual serial; try a different USB port or cable
⚠️ Build reports command not found
Cause: the toolchain doesn't have execute permission
Fix: run cd toolchain/riscv/Linux && . chmod755.sh, then make -j8 again
Self-Check
The serial shows aiot_mqtt_connect successs and AIOT_MQTTEVT_CONNECT, and the Alibaba Cloud console shows the device "Online" with property report records in the Thing Model data — the Alibaba Cloud IoT connection is verified.

