MCU SDK Porting

Last Updated on : 2024-06-24 06:21:40download

The MCU SDK enables you to interface your MCU with Tuya’s module so that your hardware can be connected to the Tuya Developer Platform and access cloud services. The SDK is specific to the product functions you defined on the platform. It includes basic and advanced feature implementation with samples, making it easier to develop IoT applications. This topic describes how to port the MCU SDK to your hardware platform.

Hardware requirements

SDK requirements for the MCU are as follows. If your hardware is constrained in resources, you can refer to functions in the SDK and port the protocol yourself.

  • Memory: 4 KB

  • RAM: About 100 bytes of the RAM are required, depending on the data length of the data point (DP). If you enable OTA updates, it must be greater than 260 bytes.

  • Nested function: 9-level.

    If you develop with an Arduino development board, see Connect Arduino to Tuya.

File structure

Files Description
mcu_api.c
Contains functions that can be called.
mcu_api.h Contains declarations for functions in mcu_api.c.
protocol.c Contains functions for processing protocol data. You can add write code to enable your MCU to receive data from the Wi-Fi module.
protocol.h protocol.h contains the following information:
  • Parameters that the MCU sends to the Wi-Fi module for initialization.
  • Macros defined for custom features, which can be enabled as needed.
  • Declarations for functions in protocol.c.
system.c Contains the implementation of parsing the serial protocol.
system.h system.h contains the following information:
  • Definitions of commands.
  • Some global variables.
  • Declarations for functions in system.c.
wifi.h Contains macro definitions for Wi-Fi communication.
  • In the mcu_sdk for door locks, lock_api.c and lock_api.h are included to implement lock functionality.
  • In the mcu_sdk for devices with the GPRS feature, the file name of wifi.h is changed to gprs.h.

How to port SDK

  1. Program the MCU and port the SDK.
  2. Check macro definitions in the protocol.h.
  3. Port the protocol.c file and the function call.
  4. Add the function call for DP data communication.
  5. Add the function of device pairing and LED indicator.
  6. Add the production test feature.

Program MCU and port SDK

  1. In your original project, initialize the MCU peripherals, including serial port, external interrupt (button), timer (LED indicator), and more.

  2. Copy the .c and .h files in the MCU SDK folder to your project directory where other .c and .h files are located.

    MCU SDK Porting

    MCU SDK Porting

Check macro definitions in protocol.h

Product information

  1. Define the product ID (PID). PRODUCT_KEY is the macro defined for the PID. PID is the unique identifier assigned to each product.

    #define PRODUCT_KEY "ax23rawjo4np****"
    

    If the PRODUCT_KEY and the PID are inconsistent, you can go to Hardware Development > Download Documents section, and download the latest SDK.

  2. Define the version number. MCU_VER defines the software version, which defaults to 1.0.0. If you enable OTA updates for the MCU firmware, you need to update the MCU version number after the firmware update is installed.

    #define MCU_VER "1.0.0"
    
  3. Define the working mode of the Wi-Fi module. CONFIG_MODE defines the pairing mode that can be the default mode (switching between AP mode and EZ mode), the safe mode, and the anti-misoperation mode. The anti-misoperation mode is recommended.

    • The following describes the three modes.

      • Default mode: The pairing mode can switch between AP mode and EZ mode. If the module is not paired or removed, it will keep a state pending pairing after power on.

        #define CONFIG_MODE     CONFIG_MODE_DEFAULT
        
      • Safe mode: The module does not enter the pairing mode after power on until the MCU sends the reset command. If the module is not paired within a specified time period (three minutes by default), it will automatically exit the pairing mode. You need to repeat the reset process to make the module enter pairing mode again.

        #define CONFIG_MODE     CONFIG_MODE_LOWPOWER
        
      • Anti-misoperation mode: A paired module that is physically reset will resume its network connection if it is not paired within a specified time period (three minutes by default). Similarly, if a device that is physically reset is shut down due to an outage, it will resume its network connection after power on. In this mode, if a user removed a device from the app, the network connection history of this device will be cleared.

        #define CONFIG_MODE     CONFIG_MODE_SPECIAL
        
    • Define the hold-time of the pairing mode. If you select safe mode or anti-misoperation mode, you can enable the macro CONFIG_MODE_DELAY_TIME and set the hold-time of the pairing mode. The hold-time can be between 3 and 10 minutes. If you do not enable this macro, the hold-time defaults to three minutes.

      #define CONFIG_MODE_DELAY_TIME    10
      
  4. Specify a pairing mode. You can set the coexistence of EZ mode and AP mode or only AP mode available through CONFIG_MODE_CHOOSE.

    • 0: indicates the coexistence of EZ mode and AP mode. This way, it is not necessary to switch between modes.

      #define CONFIG_MODE_CHOOSE        0
      
    • 1: indicates only AP mode is supported.

      #define CONFIG_MODE_CHOOSE        1
      
  5. Set the infrared feature. You can set the TX and RX pins used for the infrared feature through ENABLE_MODULE_IR_FUN.

    //#define ENABLE_MODULE_IR_FUN        // Enable the infrared feature.
    #ifdef ENABLE_MODULE_IR_FUN
    #define MODULE_IR_PIN_TX      5       // TX pin of infrared.
    #define MODULE_IR_PIN_RX      12      // RX pin of infrared.
    #endif
    
  6. Set low power mode. You can enable low power mode through LONG_CONN_LOWPOWER, which is disabled by default.

    //#define LONG_CONN_LOWPOWER        0         // Disable low power mode.
    //#define LONG_CONN_LOWPOWER        1         // Enable low power mode.
    

(Optional) OTA updates

  1. Enable OTA updates. To support OTA firmware updates, define SUPPORT_MCU_FIRM_UPDATE. OTA updates are disabled by default.

    #define         SUPPORT_MCU_FIRM_UPDATE
    
  2. Define the size of a single packet.

    #ifdef SUPPORT_MCU_FIRM_UPDATE
    #define PACKAGE_SIZE                     0        // One update package is 256 bytes.
    //#define PACKAGE_SIZE                   1        // One update package is 512 bytes.
    //#define PACKAGE_SIZE                   2        // One update package is 1024 bytes.
    #endif
    

    For more information about the OTA updates, see OTA Update Guide.

  • OTA updates read and write flash memory. The system needs to read data and verify whether the correct data is written to flash memory.
  • Specify a timeout period for OTA updates so that the MCU will not always be in the data reception status in case of OTA failure.
  • Each OTA packet has offset information, which can be used to detect duplicate packets or packet loss.

(Optional) Transmit and receive buffer

  • Serial receive buffer: The buffer size depends on how often the serial data handler is called. If the MCU can quickly process serial data, the buffer size can be reduced.

  • Serial transmit buffer: The buffer size must be greater than the maximum length of DP data.

  • Buffer for serial data processing: The buffer size must be greater than the maximum length of DP data. If OTA updates and specific weather services are enabled, the buffer size must be greater than the maximum amount of payload.

    /******************************************************************************
    	3: Define the transmit and receive buffer:
    	If your MCU has insufficient RAM, you can change the buffer size to 24 bytes.
    ******************************************************************************/
    #ifndef SUPPORT_MCU_FIRM_UPDATE
    #define WIFI_UART_RECV_BUF_LMT          16              // The serial receive buffer size, which can be reduced if your MCU has insufficient RAM.
    #define WIFI_DATA_PROCESS_LMT           24              // The buffer size for serial data processing. It depends on the amount of DP data but must be greater than 24 bytes.
    #else
    #define WIFI_UART_RECV_BUF_LMT          128             // The serial receive buffer size, which can be reduced if your MCU has insufficient RAM.
    
    // Set the proper buffer size. Consider the defined update package and specific weather services, if applicable.
    #define WIFI_DATA_PROCESS_LMT           300             // The buffer size for serial data processing. When OTA updates are enabled, if you set the size of a single update package to 256 bytes, the buffer size must be greater than 260 bytes. If weather services are also enabled, more buffer is required.
    //#define WIFI_DATA_PROCESS_LMT           600             // The buffer size for serial data processing. When OTA updates are enabled, if you set the size of a single update package to 512 bytes, the buffer size must be greater than 520 bytes. If weather services are also enabled, more buffer is required.
    //#define WIFI_DATA_PROCESS_LMT           1200            // The buffer size for serial data processing. When OTA updates are enabled, if you set the size of a single update package to 1024 bytes, the buffer size must be greater than 1030 bytes. If weather services are also enabled, more buffer is required.
    
    #endif
    
    #define WIFIR_UART_SEND_BUF_LMT         48              // It depends on the amount of DP data but must be greater than 48 bytes.
    

(Required) Working mode of module

  • If the reset button and LED indicator for network status are connected to the MCU, the module works with the MCU to process network events, which is most commonly used. You need to comment out the macro WIFI_CONTROL_SELF_MODE.

    //#define         WIFI_CONTROL_SELF_MODE                       // The module processes the reset button and LED indicator itself. If you use an external reset button or LED indicator, disable this macro.
    
  • If the reset button and LED indicator for network status are connected to the Wi-Fi module, the module processes network events itself. You need to enable the macro WIFI_CONTROL_SELF_MODE. Specify the GPIO pins connected to the indicator and the button in the following two macros.

    #ifdef          WIFI_CONTROL_SELF_MODE                        // The module processes network events itself.
    	 #define     WF_STATE_KEY            14                    // The indicator for network status. Set it according to your circuit.
    	 #define     WF_RESERT_KEY           0                     // The button for Wi-Fi module reset. Set it according to your circuit.
    #endif
    

(Optional) Production test feature

The production test feature for the Wi-Fi module is enabled by default. To help you smoothly and efficiently carry out mass production, it is recommended to enable the production test feature.

#define         WIFI_TEST_ENABLE                // Enable the production test feature.

For more information, see Production Test Guide.

(Optional) Weather services

After the module is connected to the router, you can define WEATHER_ENABLE to enable weather services. Once the module is connected to the cloud, the server sends weather data immediately and then every 30 minutes.

  1. Enable weather services. Define WEATHER_ENABLE.

    //#define         WEATHER_ENABLE                  // Enable weather services.
    
  2. Specify the supported weather service. You can select the supported weather parameters from the weather_choose array in the protocol.c file.

    #ifdef WEATHER_ENABLE
    /**
    	* @var    weather_choose
    	* @brief  The array of weather parameters.
    	* @note  You can define the supported parameters and comment out the undesired ones.
    	*/
    const char *weather_choose[WEATHER_CHOOSE_CNT] = {
    	"temp",
    	"humidity",
    	"condition",
    	"pm25",
    	/*"pressure",
    	"realFeel",
    	"uvi",
    	"tips",
    	"windDir",
    	"windLevel",
    	"windSpeed",
    	"sunRise",
    	"sunSet",
    	"aqi",
    	"so2 ",
    	"rank",
    	"pm10",
    	"o3",
    	"no2",
    	"co",*/
    };
    #endif
    
  3. Specify the number of supported weather conditions. Define the number of supported weather conditions in WEATHER_CHOOSE_CNT.

    #define         WEATHER_CHOOSE_CNT              4
    
  4. Specify the number of days for which the server returns forecast data. The module with the new version of the firmware supports a 7-day weather forecast. You can define the number of days for which the server returns forecast data in the macro WEATHER_FORECAST_DAYS_NUM.

    • 1: returns the weather of the current day.
    • 0 or greater than 7: The module returns an error. Weather services failed to be enabled.
    #define         WEATHER_FORECAST_DAYS_NUM       1
    

    The weather data sent by the module contains information about the forecast days. 0 indicates the current day.

(Optional) Streaming service

Streaming service suits the needs of the MCU on the robot vacuum to transmit a large amount of data. You can enable this service through WIFI_STREAM_ENABLE.

//#define         WIFI_STREAM_ENABLE

(Optional) Other features

You can complete corresponding functions to implement specific features.

Port protocol.c file and function calls

  1. Copy the wifi.h file to the folder where Wi-Fi files are stored, such as the main.c folder.

  2. Call wifi_protocol_init() function in the mcu_api.c file after the MCU serial port and other peripherals are initialized.

  3. Specify the serial transmission function in uart_transmit_output in the protocol.c file, and delete #error.

    Example:

    /**
    	* @brief  Send serial data
    	* @param[in] {value}  The one byte of data to be sent by UART.
    	* @return Null
    	*/
    void uart_transmit_output(unsigned char value)
    {
    	//#error "Specify the UART transmission function and delete this line"
    	UART3_SendByte(value);
    /*
    	//Example:
    	extern void Uart_PutChar(unsigned char value);
    	 Uart_PutChar(value);                                  // Serial port transmitting function
    */
    }
    
  4. In the interrupt handler for serial data reception, call uart_receive_input in the mcu_api.c file. Use the returned value as the parameter.

    Example:

    void USART3_IRQHandler(void)
    {
    	unsigned char Res=0;
    
    	if((USART3->SR&UART_FLAG_RXNE) != 0)
    	{
    		Res=USART3->DR;
    		uart_receive_input(Res);
    	}
    }
    
  5. After the MCU runs in the while(1) loop, it calls the wifi_uart_service() function in the mcu_api.c file. The sample code in main.c is as follows:

    #include "wifi.h"
    ...
    void main(void)
    {
    	wifi_protocol_init();
    	...
    	while(1)
    	{
    		wifi_uart_service();
    		...
    	}
    	...
    }
    

    The MCU must directly call wifi_uart_service() function in the mcu_api.c file in the while(1) loop. After the program is initialized, if an interrupt service routine (ISR) is necessary, you must keep it as short as possible and do not call the data reporting function to avoid loss of data.

Call DP data communication function

The DP supports six data types.

Types Description
Boolean Used for DPs of switch products, such as the switch, ECO, and screen.
Enum Used for DPs that have multiple kinds of status, such as working mode, fan speed, and swing direction.
Value Used for DPs that have integer values, such as temperature and battery level.
fault Used for reporting device faults, denoted in bitmap format.
string Used for DPs of string type. Used for DPs that transmit data in string format. You can choose this string type if other data types are not applicable.
Raw Used for DPs that have no requirements for data format, transmitting raw data either in plaintext or encrypted text. The data format, packet, and data parsing must be unified in the sender and the receiver.

Scenario 1: Report data of all DPs

After the module is restarted or paired again, it will initiate a status query. The MCU must return the status of all DPs.

  1. Open protocol.c and find the function all_data_update(void).

  2. Specify the initial values in corresponding functions for all DPs to be reported. These values will be displayed on the control panel in the app.

    Do not call all_data_update() because this function will be called at the specified time.

    /**
    * @brief   Upload the status of all DPs for synchronization with the app.
    * @param  Null
    * @return Null
    * @note   The MCU implements the data reporting in this function, which must support two data transfer types, namely send only as well as send and report.
    */
    void all_data_update(void)
    {
    	//#error "Complete the example of two data transfer types and delete this line"
    
    	/*
    	// This code is automatically generated. You need to edit it based on the actual DPs.
    	mcu_dp_bool_update(DPID_SWITCH,current on/off status); // Report Boolean data
    	mcu_dp_value_update(DPID_TEMP_SET,current temperature setting); // Report value data
    	mcu_dp_value_update(DPID_TEMP_CURRENT,current temperature); // Report value data
    	mcu_dp_enum_update(DPID_MODE,current mode); // Report enum data
    	mcu_dp_enum_update(DPID_FAN_SPEED_ENUM,current speed); // Report enum data
    	mcu_dp_enum_update(DPID_STATUS,current status); // Report enum data
    	mcu_dp_bool_update(DPID_ECO,current ECO mode); // Report Boolean data
    	mcu_dp_bool_update(DPID_DRYING,current drying mode); // Report Boolean data
    	mcu_dp_bool_update(DPID_VENTILATION,current ventilation mode); // Report Boolean data
    	mcu_dp_bool_update(DPID_HEAT,current auxiliary heat); // Report Boolean data
    	mcu_dp_bool_update(DPID_LIGHT,current light); // Report Boolean data
    	mcu_dp_bool_update(DPID_CHILD_LOCK,current child lock); // Report Boolean data
    	mcu_dp_bool_update(DPID_BEEP,current beep); // Report Boolean data
    	mcu_dp_value_update(DPID_HUMIDITY_SET,current humidity setting); // Report value data
    	mcu_dp_value_update(DPID_HUMIDITY_CURRENT,current humidity); // Report value data
    	mcu_dp_enum_update(DPID_TEMP_UNIT_CONVERT,current temperature unit conversion); // Report enum data
    	mcu_dp_enum_update(DPID_COUNTDOWN_SET,current countdown); // Report enum data
    	mcu_dp_value_update(DPID_COUNTDOWN_LEFT,time remaining of current countdown); // Report value data
    	mcu_dp_fault_update(DPID_FAULT,current fault alert); // Report fault data
    	mcu_dp_value_update(DPID_TEMP_CURRENT_F,current temperature in °F); // Report value data
    	mcu_dp_value_update(DPID_TEMP_SET_F,current temperature setting in °F); // Report value data
    	mcu_dp_bool_update(DPID_SLEEP,current sleep feature); // Report Boolean data
    	mcu_dp_bool_update(DPID_CLEANING,current self-cleaning); // Report Boolean data
    	mcu_dp_bool_update(DPID_SWITCH_VERTICAL,current vertical swing); // Report Boolean data
    	mcu_dp_enum_update(DPID_GEAR_VERTICAL,current vertical swing level); // Report enum data
    	mcu_dp_value_update(DPID_ANGLE_VERTICAL,current vertical swing angle); // Report value data
    	mcu_dp_bool_update(DPID_SWITCH_HORIZONTAL,current horizontal swing); // Report Boolean data
    	mcu_dp_enum_update(DPID_GEAR_HORIZONTAL,current horizontal swing level); // Report enum data
    	mcu_dp_value_update(DPID_ANGLE_HORIZONTAL,current horizontal swing angle); // Report value data
    	mcu_dp_bool_update(DPID_DISPLAY,current screen display switch); // Report Boolean data
    	*/
    }
    

Scenario 2: Report a single DP

When the status of a single DP changes, the MCU must actively report the current DP status to sync with the app. The data format is mcu_dp_xxxx_updata(DPID_X,n), where DPID_X is the DP whose status changes. You can call each function in all_data_update() individually.

Example:

mcu_dp_bool_update(DPID_SWITCH,1); // Report Boolean data
mcu_dp_value_update(DPID_TEMPER_SET,25); // Report value data
mcu_dp_string_update(DPID_DAY,"1234",4); // Report string data

Scenario 3: Send DP commands

In protocol.c, each DP that can send control commands has an individual command handler. The format is dp_download_xxx_handle(), where xxx is the DP that can send commands. After the function parses the DP, the MCU will execute commands accordingly. Take the received switch DP data as an example:

/*****************************************************************************
Function name: dp_download_switch_handle
Feature description: a processing function for `DPID_SWITCH`.
Input parameters: value indicates the data source
		  length: the length of the data
Return parameters: Returns SUCCESS on success, and ERROR on failure.
Note: For the type of send and report, the module must return the result to the cloud for synchronization with the app.
*****************************************************************************/
static unsigned char dp_download_switch_handle(const unsigned char value[], unsigned short length)
{
	// For example, a DP of Boolean type
	unsigned char ret;
	// 0: indicates off. 1: indicates on.
	unsigned char switch1;

	switch1 = mcu_get_dp_download_bool(value,length);
	if(switch1 == 0)
	{
		 // The switch is off.
		MCU_OFF_switch1();
	}
	else
	{
		 // The switch is on.
		MCU_ON_switch1();
	}

	 // Feedback after a command is executed
	ret = mcu_dp_bool_update(DPID_SWITCH,switch1);
	if(ret == SUCCESS)
		return SUCCESS;
	else
		return ERROR;
}

If the change of device status is not triggered by control commands, the MCU will call mcu_dp_bool_update(DPID_SWITCH_1,switch_1); to upload the current status of the DP for feedback. You can also choose the reporting time as needed.

Add the function of device pairing and LED indicator

The function of pairing and LED indicator is required only when the module works with the MCU to process network events.

To implement device pairing, add the pairing command and LED indicator function. If the module works with the MCU to process network events, you can customize the ways to pair devices and indicate pairing status. Generally, you can set the keypress trigger and LED indication.

Two pairing modes are available.

  • EZ mode: an ease-of-use pairing mode, indicated by quick blinking.
  • AP mode: reliable pairing, usually indicated by slow blinking.

We recommend that you implement both modes to handle different scenarios.

Command of device pairing

You can implement the pairing command through two functions mcu_reset_wifi() and mcu_set_wifi_mode(), which are called in the button processing function after pairing is triggered by button-press.

  • mcu_reset_wifi()

    Call this function to reset the Wi-Fi module. All the pairing information will be cleared after a reset. Each time mcu_reset_wifi() is called, the pairing mode is toggled from AP mode to EZ mode or EZ mode to AP mode.

    MCU SDK Porting
  • mcu_set_wifi_mode()

    It has two parameters SMART_CONFIG and AP_CONFIG. After the function is called, all pairing information will be cleared and the module enters EZ mode or AP mode.

Pairing guide

To get Wi-Fi module’s network status, call mcu_get_wifi_work_state() during while(1) loop. Write the blinking mode of the LED indicator according to the network status.

Network status Description Status value LED indicator
Status 1 Pair a device in EZ mode. 0x00 The LED blinks quickly at an interval of 250 milliseconds.
Status 2 Pair a device in AP mode. 0x01 The LED blinks slowly at an interval of 1,500 milliseconds.
Status 3 The Wi-Fi network is set up, but the device is not connected to the router. 0x02 The LED is off.
Status 4 The Wi-Fi network is set up, and the device is connected to the router. The device can be controlled over a local area network (LAN). 0x03 The LED indicator is steady on.
Status 5 The device is connected to the router and the cloud. The device can be controlled over a local area network (LAN) or from the cloud. 0x04 The LED indicator is steady on.
Status 6 The Wi-Fi device is in low power mode. 0x05 The LED is off.
Status 7 EZ mode and AP mode coexist. 0x06 The LED blinks quickly at an interval of 250 milliseconds.

Call mcu_get_wifi_work_state() to get connection status.

void main(void)
{
	...
	while(1)
	{
		...
		switch(mcu_get_wifi_work_state())
		{
			case SMART_CONFIG_STATE:
				   // In EZ mode, the LED flickers quickly.
			break;
			case AP_STATE:
				// In AP mode, the LED flickers slowly.
			break;
			case WIFI_NOT_CONNECTED:
				// The Wi-Fi network has been set up and is connecting to the router. The LED is off.
			break;
			case WIFI_CONNECTED:
				   // The Wi-Fi network is connected to the router. The LED is steady on.
			break;
			default:break;
		}
		...
	}
}

Add production test feature

The production test supports three test items. You can select them as needed.

  • Scan the specified router
  • Connect to the specified router
  • Test infrared functionality

For more information, see Production Test Guide.

Communication between MCU and Wi-Fi module

Data communication must start after the initialization is completed.

Frame format

For more information about the frame format, see Frame format description.

Initialization communication

After the MCU and the module are powered on, the initialization configuration starts. Initialization communication includes but is not limited to:

  • Verify whether the MCU and the module work properly.
  • Verify whether the connection works properly.
  • Get the data required for module activation.
  • Get the working mode of the module.

Heartbeat

A heartbeat is a type of communication packet between the module and the MCU to check whether the communication was lost. We recommend that the frame of the first communication between the MCU and the module be used as the heartbeat. The communication can work properly only when the heartbeat is sent and responded successfully.

Query product information.

After the module builds communication with the MCU, it will query the MCU firmware version and the following information.

  • PID: product ID, used to activate the product.
  • Version number: MCU firmware version number, used to verify whether the OTA updates are successful.
  • Pairing mode: the pairing mode of the module.

Set working mode of the module

The module works with the MCU to process the network event or processes it itself. The working mode is determined by the hardware connection of the LED indicator and reset button on the Wi-Fi module.

The following block diagram shows the initialization communication.

MCU SDK Porting

Things to note

  • To ensure proper data communication, we recommend that you start service data transmission like DP data and OTA updates after the network is initialized.
  • If you use the MCU to control the on/off of the module, data communication must be started after all the initialization is done.

Relation between DP data reporting and network status

In the following two network states, the device can report DP data to and receive DP commands from the app.

  • In status 5, the device is connected to the router and the cloud. DP data reporting can work properly.
  • In status 4, the device is connected to the router but not to the cloud. The mobile phone can be connected to the router, and DPs can be controlled over the LAN. The DP data can be reported to the app.

OTA data communication

This section describes the OTA data communication between the MCU and the Wi-Fi module.

File download works the same way as OTA data communication.

  • OTA starts

    When the Wi-Fi module detects an MCU update, it will send a command to start updates.

    • If the module does not receive a response from the MCU within five seconds, it will resend the package three times. If the MCU still does not respond, the OTA updates fail.
    • If the total update package size exceeds the processing capacity of the MCU, the MCU does not respond, and the module will exit OTA updates. In this case, you should check whether the updates uploaded to the Tuya Developer Platform are correct.
  • OTA data transmission starts

    After sending a package, if the Wi-Fi module does not receive a response from the MCU within five seconds, it will resend the package three times. If the MCU still does not respond, the OTA updates fail.

    • If the MCU detects incorrect OTA data, it does not respond. In this case, check the data offset to avoid duplicate packets or packet loss.
    • If the MCU processes OTA data too slowly, the module will frequently resend data. Check the data offset to avoid duplicate packets or packet loss. In this case, you can reduce the update package size.
  • OTA transmission is completed

    You can determine whether the OTA transmission is completed in the following two ways.

    • The frame length is 0x0004, indicating the packet is zero bytes.
    • The data offset is equal to the total update package size contained in the frame that the Wi-Fi module sends to the MCU for initiating OTA updates.

    We recommend using both ways to verify OTA transmission.