├── .gitignore ├── README.md ├── README_zh.md ├── config.h ├── examples ├── DataPointType │ ├── DataPointType.ino │ ├── README.md │ └── README_zh.md ├── GetGreenTime │ ├── GetGreenTime.ino │ ├── README.md │ └── README_zh.md ├── ModuleControlSelf │ ├── ModuleControlSelf.ino │ ├── README.md │ └── README_zh.md ├── SHT30 │ ├── README.md │ ├── README_zh.md │ └── SHT30.ino └── start │ ├── README.md │ ├── README_zh.md │ └── start.ino ├── keywords.txt ├── library.properties └── src ├── TuyaDataPoint.cpp ├── TuyaDataPoint.h ├── TuyaDefs.h ├── TuyaExtras.cpp ├── TuyaExtras.h ├── TuyaTools.cpp ├── TuyaTools.h ├── TuyaUart.cpp ├── TuyaUart.h ├── TuyaWifi.cpp └── TuyaWifi.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tuya MCU SDK Arduino Library 2 | 3 | [English](./README.md) | [中文](./README_zh.md) 4 | 5 | Tuya MCU SDK Arduino Library is developed based on the Tuya Wi-Fi general integration solution. The device's MCU is connected to a Wi-Fi module through a serial port to implement a network connection. **The development is based on general firmware, which supports the adaptative 9600 and115200 baud rate. Please read this document carefully before development.** 6 | 7 |
8 | 9 |
10 | 11 | ## [Tuya Beta Test Program](https://pages.tuya.com/develop/ArduinoBetaTest_discord?_source=f21d8ebfe2cde74110e27b26366a81f3) 12 | Now welcome to join the [Tuya Beta Test Program](https://pages.tuya.com/develop/ArduinoBetaTest_discord?_source=f21d8ebfe2cde74110e27b26366a81f3) to get your development gifts and make your own arduino projects with Tuya Support. Your feedback is helpful and valuable to the whole community. 13 | ![image](https://user-images.githubusercontent.com/85163056/126034859-0b9b8856-0556-4d3f-a201-a6951172c080.png) 14 | 15 | 16 | 17 | ## Document introduction 18 | 19 | ```bash 20 | ├── config.h // Configuration file. Add and define features in the MCU SDK with macros. 21 | ├── examples // The folder to save routines. 22 | ├── keywords.txt 23 | ├── library.properties 24 | ├── README.md 25 | └── src // The folder to save Tuya MCU SDK Arduino Library. 26 | ├── TuyaWifi.cpp // The APIs for users. 27 | ├── TuyaDataPoint.cpp // The class of DP operations. 28 | ├── TuyaDataPoint.h 29 | ├── TuyaDefs.h // Some constants. 30 | ├── TuyaWifi.h 31 | ├── TuyaTools.cpp // Tools used by the MCU SDK. 32 | ├── TuyaTools.h 33 | ├── TuyaUart.cpp // Functions for serial communications and data buffer. 34 | └── TuyaUart.h 35 | ``` 36 | 37 | 38 | 39 | ## Important functions 40 | 41 | When you use this library for development with Arduino, you must add the header file `TuyaWifi.h` in your Arduino project. 42 | 43 | ### 1. Initialization 44 | 45 | Every product that is created on the Tuya IoT Platform will have a unique product ID (PID). The PID is associated with all information related to this product, including specific DP, app control panel, and delivery information. 46 | 47 | In `unsigned char TuyaWifi::init(unsigned char *pid, unsigned char *mcu_ver)`, the PID is obtained after you create a product on the [Tuya IoT Platform](http://iot.tuya.com/?_source=bcd157afd1c16c931b7b44381c9fe884). The PID of a Wi-Fi product is typically 16 bytes. The `mcu_ver` parameter is the version number of the software. Pay attention to this parameter if you want to support OTA updates of the MCU. 48 | > **Note**: The current version of the library does not support the OTA feature. 49 | 50 | ```c 51 | #include 52 | 53 | TuyaWifi my_device; 54 | ... 55 | void setup() 56 | { 57 | Serial.begin(9600); 58 | ... 59 | my_device.init("xxxxxxxxxxxxxxxx", "1.0.0");// "xxxxxxxxxxxxxxxx": the PID on the Tuya IoT Platform. "1.0.0" is the default value. You can change "1.0.0" to the actual version number of the current software. 60 | 61 | ... 62 | } 63 | 64 | void loop() 65 | { 66 | ... 67 | my_device.uart_service(); 68 | ... 69 | } 70 | ... 71 | ``` 72 | 73 | 74 | 75 | ### 2. Pass in the DP information to the MCU SDK 76 | 77 | Create products on the [Tuya IoT Platform](http://iot.tuya.com/?_source=bcd157afd1c16c931b7b44381c9fe884) and get information on product DP points. 78 | 79 | A data point (DP) represents a smart device function. 80 | 81 | + Tuya abstracts each function into a data point. DPs are defined in different data types, such as Boolean, enumeration, and integer. 82 | + DPs have read and write attributes. For example, a 2-gang switch has two Boolean DPs, and each DP has either a `True` or `False` value, which is readable and writable. 83 | + To read means to get the current value of the switch, and to write means to change the current value of the switch. 84 | 85 | DPID: specifies the ID of a DP event under a communication protocol. 86 | 87 | 88 | The MCU SDK needs to know which DPs you have created and what type they are. Pass them to the MCU SDK through the `void TuyaWifi::set_dp_cmd_total(unsigned char dp_cmd_array[][2], unsigned char dp_cmd_num)` function. 89 | The Tuya IoT Platform has six types of DPs: 90 | 91 | ```c 92 | #define DP_TYPE_RAW 0x00 // Raw type 93 | #define DP_TYPE_BOOL 0x01 // Boolean type 94 | #define DP_TYPE_VALUE 0x02 // Numeric type 95 | #define DP_TYPE_STRING 0x03 // String type 96 | #define DP_TYPE_ENUM 0x04 // Enum type 97 | #define DP_TYPE_BITMAP 0x05 // Fault type 98 | ``` 99 | 100 | In the `void TuyaWifi::set_dp_cmd_total(unsigned char dp_cmd_array[][2], unsigned char dp_cmd_num)` function, `dp_cmd_array[][2]` is the array that stores DP information, and `dp_cmd_num` is the total number of DPs. 101 | 102 | 103 | 104 | Assume that a light has three functions, corresponding to three DPs as below: 105 | * Switch (DP ID: 20, DP type: Boolean type). 106 | * Brightness (DP ID: 21, DP type: numeric type). 107 | * Light mode (DP ID: 22, DP type: enum type). 108 | 109 | ```c 110 | #include 111 | 112 | TuyaWifi my_device; 113 | ... 114 | #define DPID_SWITCH 20 // The switch DP of the light. 115 | #define DPID_LIGHT 21 // The brightness DP of the light. 116 | #define DPID_MODE 22 // The working mode DP of the light. 117 | 118 | // Note: array[][0] is DP ID, and array[][1] is DP type. 119 | unsigned char dp_id_array[][2] = { 120 | /* DPID | DP type */ 121 | {DPID_SWITCH, DP_TYPE_BOOL}, 122 | {DPID_LIGHT, DP_TYPE_VALUE}, 123 | {DPID_MODE, DP_TYPE_ENUM}, 124 | }; 125 | ... 126 | void setup() 127 | { 128 | ... 129 | my_device.set_dp_cmd_total(dp_id_array, 3); 130 | ... 131 | } 132 | ``` 133 | 134 | 135 | 136 | ### 3. Pairing mode setting 137 | 138 | Call `void TuyaWifi::mcu_set_wifi_mode(unsigned char mode)` to enter the pairing mode. 139 | 140 | ```c 141 | /** 142 | * @description: The MCU sets Wi-Fi working mode 143 | * @param {unsigned char} mode: Enter the specified mode 144 | * 0(SMART_CONFIG): Enter SmartConfig (Wi-Fi Easy Connect) mode 145 | * 1(AP_CONFIG): Enter AP mode 146 | * @return {*} 147 | */ 148 | void TuyaWifi::mcu_set_wifi_mode(unsigned char mode); 149 | ``` 150 | 151 | 152 | 153 | 154 | 155 | ### 4. Send and process DP data 156 | 157 | After the cloud sends data, the sent data must be parsed through the `unsigned char TuyaWifi::mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len)` function. 158 | Currently, this function only supports three types: `DP_TYPE_BOOL`, `DP_TYPE_VALUE`, and `DP_TYPE_ENUM`. `DP_TYPE_BITMAP` refers to the data of fault type, in which the data is only reported to the cloud. You do not need to handle this type. `DP_TYPE_RAW` and `DP_TYPE_STRING` must be implemented yourself. 159 | 160 | ```c 161 | /** 162 | * @description: The MCU gets Boolean, numeric, and enum types to send DP value. (The data of the raw and string types shall be handled at the user's discretion. The data of the fault type can only be reported.) 163 | * @param {unsigned char} dpid: Data point (DP) ID 164 | * @param {const unsigned char} value: DP data buffer address 165 | * @param {unsigned short} len: Data length 166 | * @return {unsigned char} Parsed data 167 | */ 168 | unsigned char TuyaWifi::mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len); 169 | ``` 170 | 171 | 172 | 173 | ### 5. Register a function to process DP sending 174 | 175 | The app sends DP control commands to the device through the cloud. After data parsing, the device executes the specified actions accordingly. 176 | 177 | A callback function is required to process the sent commands, so a processing function must be registered. We can call `void TuyaWifi::dp_process_func_register(tuya_callback_dp_download _func)` to register the callback function. 178 | 179 | ```c 180 | #include 181 | 182 | TuyaWifi my_device; 183 | ... 184 | 185 | void setup() 186 | { 187 | ... 188 | // Register DP download processing callback function 189 | my_device.dp_process_func_register(dp_process); 190 | ... 191 | } 192 | 193 | /** 194 | * @description: DP download callback function. 195 | * @param {unsigned char} dpid 196 | * @param {const unsigned char} value 197 | * @param {unsigned short} length 198 | * @return {unsigned char} 199 | */ 200 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 201 | { 202 | switch(dpid) { 203 | case DPID_SWITCH: 204 | switch_value = my_device.mcu_get_dp_download_data(dpid, value, length); 205 | if (switch_value) { 206 | // Turn on 207 | 208 | } else { 209 | // Turn off 210 | 211 | } 212 | // Status changes must be reported. 213 | my_device.mcu_dp_update(dpid, value, length); 214 | break; 215 | 216 | default:break; 217 | } 218 | return SUCCESS; 219 | } 220 | ``` 221 | 222 | 223 | 224 | ### 6. Report device status 225 | 226 | Reporting the device status is to report the values of all DPs. It is also implemented through function registration. 227 | 228 | Six data types of DPs are defined as follows: 229 | 230 | DP reporting function: 231 | 232 | ```c 233 | /** 234 | * @description: DP data upload 235 | * @param {unsigned char} dpid 236 | * @param {const unsigned char} value 237 | * @param {unsigned short} length 238 | * @return {*} 239 | */ 240 | unsigned char mcu_dp_update(unsigned char dpid, const unsigned char value[], unsigned short len);//update raw, string type 241 | unsigned char mcu_dp_update(unsigned char dpid, unsigned long value, unsigned short len); 242 | unsigned char mcu_dp_update(unsigned char dpid, unsigned int value, unsigned short len); 243 | ``` 244 | 245 | 246 | Example of registering a device status reporting function 247 | 248 | ```c 249 | #include 250 | 251 | TuyaWifi my_device; 252 | 253 | #define DPID_SWITCH 20 254 | // Record the current status of the LED 255 | unsigned char switch_value = 0; 256 | ... 257 | void setup() 258 | { 259 | ... 260 | // Register DP download processing callback function 261 | my_device.dp_update_all_func_register(dp_update_all); 262 | ... 263 | } 264 | 265 | /** 266 | * @description: Upload all DP status of the current device. 267 | * @param {*} 268 | * @return {*} 269 | */ 270 | void dp_update_all(void) 271 | { 272 | my_device.mcu_dp_update(DPID_SWITCH, switch_value, 1); 273 | } 274 | ``` 275 | 276 | ## Technical Support 277 | 278 | You can get support for Tuya by using the following methods: 279 | 280 | - Developer Centre: https://developer.tuya.com?_source=d3b1d41903c59173453028c00b26eda6 281 | - Help Centre: https://support.tuya.com/en/help?_source=9e55ab864ce95b016070141319a5206f 282 | - Technical Support Work Order Centre: https://service.console.tuya.com?_source=5817a709f62789fbeb91c94062bf8993 283 | 284 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # Tuya MCU SDK Arduino Library 2 | 3 | [English](./README.md) | [中文](./README_zh.md) 4 | 5 | Tuya MCU SDK Arduino Library 基于涂鸦Wi-Fi 通用对接方案进行开发的,设备 MCU 通过串口与 Wi-Fi 模组连接实现设备联网。**涂鸦模组中的固件应为通用固件,通用固件支持9600,115200两种波特率自适应。开发前请仔细阅读该文档。** 6 | 7 |
8 | 9 |
10 | 11 | 12 | 13 | ## 文件介绍 14 | 15 | ```bash 16 | ├── config.h //配置文件,通过一些宏对mcu sdk内的功能进行添加和裁剪 17 | ├── examples //例程存放文件夹(DataPointType例程对于涂鸦的数据类型进行了示例,具有较强的参考价值) 18 | ├── keywords.txt 19 | ├── library.properties 20 | ├── README.md 21 | └── src //Tuya mcu sdk Arduino Library 存放文件夹 22 | ├── TuyaWifi.cpp //用户会使用到的API接口 23 | ├── TuyaDataPoint.cpp //对DP点相关操作的类 24 | ├── TuyaDataPoint.h 25 | ├── TuyaDefs.h //会用到的,用户不需改动的一些常量 26 | ├── TuyaWifi.h 27 | ├── TuyaTools.cpp //MCU SDK会使用到的一些工具 28 | ├── TuyaTools.h 29 | ├── TuyaUart.cpp //对串口和数据缓存区处理的一些函数 30 | └── TuyaUart.h 31 | ``` 32 | 33 | 34 | 35 | ## 重要函数 36 | 37 | 在Arduino中使用该库进行编程开发时,必须在你的Arduino工程文件中包含 `TuyaWifi.h` 头文件。 38 | 39 | 40 | 41 | ### 1、相关信息初始化 42 | 43 | 在使用Tuya IoT 云平台的时候,Product ID(简称:PID) 关联了产品具体的功能点、App 控制面板、出货信息等所有跟这个产品相关的信息。 44 | 45 | `unsigned char TuyaWifi::init(unsigned char *pid, unsigned char *mcu_ver)` ,PID通过在 [Tuya IoT平台](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2) 上创建产品获取,wifi类的长度一般为16,`mcu_ver` 这个参数是软件的版本号,如果你的mcu想要支持OTA的话,该信息也是非常重要的。 46 | 47 | > **提示**:当前版本的library暂不支持OTA功能。 48 | 49 | ```c 50 | #include 51 | 52 | TuyaWifi my_device; 53 | ... 54 | void setup() 55 | { 56 | Serial.begin(9600); 57 | ... 58 | my_device.init("xxxxxxxxxxxxxxxx", "1.0.0");//"xxxxxxxxxxxxxxxx":应为你在Tuya IoT 平台上获取的的PID,"1.0.0"应是当前软件的实际版本号 59 | 60 | ... 61 | } 62 | 63 | void loop() 64 | { 65 | ... 66 | my_device.uart_service(); 67 | ... 68 | } 69 | 70 | ... 71 | ``` 72 | 73 | 74 | 75 | ### 2、DP信息传入MCU SDK 76 | 77 | 在[Tuya IoT平台](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2)创建产品,获取产品DP点信息。 78 | 79 | DP为 Data Point 的缩写,即数据点,偶尔被称为 DP 点,表示智能设备所具备的功能点。 80 | 81 | + 涂鸦智能将每个功能点抽象成数据点,数据点定义成不同的类型,例如布尔、枚举、数值等。 82 | + 数据点具备读写属性。例如,一个两路的开关,可以抽象成两个数据点,每个数据点类型为布尔型,可取值为 `True` 或 `False`。 83 | + 数据点可读写,读表示获取开关目前的值,写表示改变开关目前的值。 84 | 85 | DPID:指定通信协议下 DP 事件的 ID。 86 | 87 | 88 | 89 | MCU SDK需要知道你创建了哪些DP点,他们是什么类型的,通过 `void TuyaWifi::set_dp_cmd_total(unsigned char dp_cmd_array[][2], unsigned char dp_cmd_num)` 函数传入MCU SDK。Tuya IoT 对于DP的类型分为6类: 90 | 91 | ```c 92 | #define DP_TYPE_RAW 0x00 //RAW type 93 | #define DP_TYPE_BOOL 0x01 //bool type 94 | #define DP_TYPE_VALUE 0x02 //value type 95 | #define DP_TYPE_STRING 0x03 //string type 96 | #define DP_TYPE_ENUM 0x04 //enum type 97 | #define DP_TYPE_BITMAP 0x05 //fault type 98 | ``` 99 | 100 | 关于`void TuyaWifi::set_dp_cmd_total(unsigned char dp_cmd_array[][2], unsigned char dp_cmd_num)` 函数,`dp_cmd_array[][2]` 为存储的信息的数组,`dp_cmd_num` 为DP总数。 101 | 102 | 103 | 104 | 这里我们假设有一个灯,它主要有3个功能也就是3个DP点,分别是: 105 | 106 | + 开关(DP ID : 20, DP 类型:布尔类型) 107 | + 灯的亮度(DP ID : 21, DP 类型:数值类型) 108 | + 灯光模式(DP ID : 22, DP 类型:枚举类型) 109 | 110 | ```c 111 | #include 112 | 113 | TuyaWifi my_device; 114 | ... 115 | #define DPID_SWITCH 20 //灯的开关DP 116 | #define DPID_LIGHT 21 //灯的亮度DP 117 | #define DPID_MODE 22 //灯的工作模式DP 118 | 119 | //注意:array[][0]为DPID, array[][1]为DP type 120 | unsigned char dp_id_array[][2] = { 121 | /* DPID | DP type */ 122 | {DPID_SWITCH, DP_TYPE_BOOL}, 123 | {DPID_LIGHT, DP_TYPE_VALUE}, 124 | {DPID_MODE, DP_TYPE_ENUM}, 125 | }; 126 | ... 127 | void setup() 128 | { 129 | ... 130 | my_device.set_dp_cmd_total(dp_id_array, 3); 131 | ... 132 | } 133 | ``` 134 | 135 | 136 | 137 | ### 3、配网模式设置 138 | 139 | 调用 `void TuyaWifi::mcu_set_wifi_mode(unsigned char mode)` 进入配网模式。 140 | 141 | ```c 142 | /** 143 | * @description: MCU set wifi working mode 144 | * @param {unsigned char} mode : enter mode 145 | * 0(SMART_CONFIG):enter smartconfig mode 146 | * 1(AP_CONFIG):enter AP mode 147 | * @return {*} 148 | */ 149 | void TuyaWifi::mcu_set_wifi_mode(unsigned char mode); 150 | ``` 151 | 152 | 153 | 154 | ### 4、下发DP数据处理 155 | 156 | 当云端下发数据后,需要对下发的数据进行解析,通过`unsigned char TuyaWifi::mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len)` 这个函数进行解析。该函数目前只支持`DP_TYPE_BOOL`,`DP_TYPE_VALUE`,`DP_TYPE_ENUM` 这3种类型;`DP_TYPE_BITMAP` 为故障型一般只上报处理,不会下发,对该类型不用处理;`DP_TYPE_RAW` ,`DP_TYPE_STRING` 这两种类型需要用户自己进行处理。 157 | 158 | 159 | 160 | ```c 161 | /** 162 | * @description: mcu gets bool,value,enum type to send dp value. (raw, string type needs to be handled at the user's discretion. fault only report) 163 | * @param {unsigned char} dpid : data point ID 164 | * @param {const unsigned char} value : dp data buffer address 165 | * @param {unsigned short} len : data length 166 | * @return {unsigned char} Parsed data 167 | */ 168 | unsigned char TuyaWifi::mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len); 169 | ``` 170 | 171 | 172 | 173 | ### 5、DP下发处理函数注册 174 | 175 | 当APP控制设备的时候,会从云端下发对应的DP命令到设备,设备对数据进行解析后,对下发的命令执行相对于的动作。 176 | 177 | 对下发命令的处理,通过回调函数来调用,所以我们需要把你的处理函数注册一下。调用这个`void TuyaWifi::dp_process_func_register(tuya_callback_dp_download _func)` 对回调函数进行注册。 178 | 179 | ```c 180 | #include 181 | 182 | TuyaWifi my_device; 183 | ... 184 | 185 | void setup() 186 | { 187 | ... 188 | //register DP download processing callback function 189 | my_device.dp_process_func_register(dp_process); 190 | ... 191 | } 192 | 193 | /** 194 | * @description: DP download callback function. 195 | * @param {unsigned char} dpid 196 | * @param {const unsigned char} value 197 | * @param {unsigned short} length 198 | * @return {unsigned char} 199 | */ 200 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 201 | { 202 | switch(dpid) { 203 | case DPID_SWITCH: 204 | switch_value = my_device.mcu_get_dp_download_data(dpid, value, length); 205 | if (switch_value) { 206 | //Turn on 207 | 208 | } else { 209 | //Turn off 210 | 211 | } 212 | //Status changes should be reported. 213 | my_device.mcu_dp_update(dpid, value, length); 214 | break; 215 | 216 | default:break; 217 | } 218 | return SUCCESS; 219 | } 220 | ``` 221 | 222 | 223 | 224 | ### 6、上报设备状态 225 | 226 | 上报设备状态也就是上报所有DP点值,也是通过注册函数的方式进行的。 227 | 228 | 229 | 230 | 接收 DataPoint 的 6 种不同DP类型的数据类型定义: 231 | 232 | DP上报函数: 233 | 234 | ```c 235 | /** 236 | * @description: dp data upload 237 | * @param {unsigned char} dpid 238 | * @param {const unsigned char} value 239 | * @param {unsigned short} len 240 | * @return {*} 241 | */ 242 | unsigned char mcu_dp_update(unsigned char dpid, const unsigned char value[], unsigned short len);//update raw, string type 243 | unsigned char mcu_dp_update(unsigned char dpid, unsigned long value, unsigned short len); 244 | unsigned char mcu_dp_update(unsigned char dpid, unsigned int value, unsigned short len); 245 | ``` 246 | 247 | 248 | 249 | 上报设备状态函数注册示例: 250 | 251 | ```c 252 | #include 253 | 254 | TuyaWifi my_device; 255 | 256 | #define DPID_SWITCH 20 257 | //Record the current status of the led 258 | unsigned char switch_value = 0; 259 | ... 260 | void setup() 261 | { 262 | ... 263 | //register DP download processing callback function 264 | my_device.dp_update_all_func_register(dp_update_all); 265 | ... 266 | } 267 | 268 | /** 269 | * @description: Upload all DP status of the current device. 270 | * @param {*} 271 | * @return {*} 272 | */ 273 | void dp_update_all(void) 274 | { 275 | my_device.mcu_dp_update(DPID_SWITCH, switch_value, 1); 276 | } 277 | ``` 278 | 279 | 280 | 281 | ## 技术支持 282 | 283 | 您可以通过以下方法获得涂鸦的支持: 284 | 285 | - 开发者中心:https://developer.tuya.com 286 | - 帮助中心: https://support.tuya.com/help 287 | - 技术支持工单中心: https://service.console.tuya.com -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: config.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-10 11:24:27 7 | * @LastEditTime: 2021-11-04 14:00:42 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: Tuya mcu sdk Arduino library config file. 11 | */ 12 | #ifndef __CONFIG_H__ 13 | #define __CONFIG_H__ 14 | 15 | #include "TuyaDefs.h" 16 | 17 | /* Distribution mode selection, only three choices, Anti-touch mode is recommende */ 18 | #define CONFIG_MODE CONFIG_MODE_DEFAULT //Default working mode 19 | // #define CONFIG_MODE CONFIG_MODE_LOWPOWER //Safe mode (low power working mode) 20 | // #define CONFIG_MODE CONFIG_MODE_SPECIAL // Anti-touch mode (special working mode) 21 | 22 | /* some extra features defined begin */ 23 | #define WIFI_CONTROL_SELF_MODE 0 24 | #define SUPPORT_GREEN_TIME 1 25 | #define SUPPORT_RTC_TIME 1 26 | /* some extra features defined end */ 27 | 28 | #ifndef SUPPORT_MCU_FIRM_UPDATE 29 | #define WIFI_UART_RECV_BUF_LMT 32 //UART data receiving buffer size, can be reduced if the MCU has insufficient RAM 30 | #define WIFI_DATA_PROCESS_LMT 64 //UART data processing buffer size, according to the user DP data size, must be greater than 24 31 | #else 32 | #define WIFI_UART_RECV_BUF_LMT 128 //UART data receiving buffer size, can be reduced if the MCU has insufficient RAM 33 | /* Select the appropriate UART data processing buffer size here 34 | (select the buffer size based on the size selected by the above MCU firmware upgrade package and whether to turn on the weather service) */ 35 | #define WIFI_DATA_PROCESS_LMT 1000 //UART data processing buffer size. If the MCU firmware upgrade is required, the single-packet size is 256, the buffer must be greater than 260, or larger if the weather service is enabled 36 | // #define WIFI_DATA_PROCESS_LMT 600 //UART data processing buffer size. If the MCU firmware upgrade is required, the single-packet size is 512, the buffer must be greater than 520, or larger if the weather service is enabled 37 | // #define WIFI_DATA_PROCESS_LMT 1200 //UART data processing buffer size. If the MCU firmware upgrade is required, the single-packet size is 1024, the buffer must be greater than 1030, or larger if the weather service is enabled 38 | #endif 39 | 40 | #define WIFIR_UART_SEND_BUF_LMT 64 //According to the user's DP data size, it must be greater than 48 41 | 42 | 43 | #endif /* __CONFIG_H__ */ 44 | -------------------------------------------------------------------------------- /examples/DataPointType/DataPointType.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: DataPointType.ino 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-19 14:31:52 7 | * @LastEditTime: 2021-11-01 10:02:07 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | * @Github:https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library 12 | */ 13 | 14 | #include 15 | 16 | // STM32 17 | // HardwareSerial Serial2(PA_3, PA_2); 18 | 19 | TuyaWifi my_device; 20 | 21 | /* Current LED status */ 22 | unsigned char led_state = 0; 23 | /* Connect network button pin */ 24 | int wifi_key_pin = 7; 25 | 26 | /* Data point define */ 27 | #define DPID_BOOL 101 28 | #define DPID_VALUE 102 29 | #define DPID_ENUM 103 30 | #define DPID_STRING 104 31 | #define DPID_RAW 105 32 | #define DPID_FAULT 106 33 | 34 | /* Current device DP values */ 35 | unsigned char dp_bool_value = 0; 36 | long dp_value_value = 0; 37 | unsigned char dp_enum_value = 0; 38 | unsigned char dp_string_value[8] = {"Hi,Tuya"}; 39 | unsigned char dp_raw_value[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; 40 | int dp_fault_value = 0x01; 41 | 42 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 43 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 44 | */ 45 | unsigned char dp_array[][2] = { 46 | {DPID_BOOL, DP_TYPE_BOOL}, 47 | {DPID_VALUE, DP_TYPE_VALUE}, 48 | {DPID_ENUM, DP_TYPE_ENUM}, 49 | {DPID_STRING, DP_TYPE_STRING}, 50 | {DPID_RAW, DP_TYPE_RAW}, 51 | {DPID_FAULT, DP_TYPE_BITMAP}, 52 | }; 53 | 54 | unsigned char pid[] = {"yw3fhhvcbsfnl3eg"}; 55 | unsigned char mcu_ver[] = {"1.0.0"}; 56 | 57 | /* last time */ 58 | unsigned long last_time = 0; 59 | 60 | void setup() 61 | { 62 | Serial.begin(9600); 63 | Serial2.begin(9600); 64 | 65 | //Initialize led port, turn off led. 66 | pinMode(LED_BUILTIN, OUTPUT); 67 | digitalWrite(LED_BUILTIN, LOW); 68 | 69 | //Initialize networking keys. 70 | pinMode(wifi_key_pin, INPUT_PULLUP); 71 | 72 | //Enter the PID and MCU software version 73 | my_device.init(pid, mcu_ver); 74 | //incoming all DPs and their types array, DP numbers 75 | my_device.set_dp_cmd_total(dp_array, 6); 76 | //register DP download processing callback function 77 | my_device.dp_process_func_register(dp_process); 78 | //register upload all DP callback function 79 | my_device.dp_update_all_func_register(dp_update_all); 80 | 81 | last_time = millis(); 82 | } 83 | 84 | void loop() 85 | { 86 | my_device.uart_service(); 87 | 88 | //Enter the connection network mode when Pin7 is pressed. 89 | if (digitalRead(wifi_key_pin) == LOW) { 90 | delay(80); 91 | if (digitalRead(wifi_key_pin) == LOW) { 92 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 93 | } 94 | } 95 | 96 | /* LED blinks when network is being connected */ 97 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 98 | if (millis() - last_time >= 500) { 99 | last_time = millis(); 100 | /* Toggle current LED status */ 101 | if (led_state == LOW) { 102 | led_state = HIGH; 103 | } else { 104 | led_state = LOW; 105 | } 106 | 107 | digitalWrite(LED_BUILTIN, led_state); 108 | } 109 | } 110 | 111 | delay(10); 112 | } 113 | 114 | /** 115 | * @description: DP download callback function. 116 | * @param {unsigned char} dpid 117 | * @param {const unsigned char} value 118 | * @param {unsigned short} length 119 | * @return {unsigned char} 120 | */ 121 | unsigned char dp_process(unsigned char dpid, const unsigned char value[], unsigned short length) 122 | { 123 | switch (dpid) { 124 | case DPID_BOOL: 125 | Serial2.println("Bool type:"); 126 | dp_bool_value = my_device.mcu_get_dp_download_data(dpid, value, length); 127 | Serial2.println(dp_bool_value); 128 | /* After processing the download DP command, the current status should be reported. */ 129 | my_device.mcu_dp_update(DPID_BOOL, dp_bool_value, 1); 130 | break; 131 | 132 | case DPID_VALUE: 133 | Serial2.println("Value type:"); 134 | dp_value_value = my_device.mcu_get_dp_download_data(DPID_VALUE, value, length); 135 | Serial2.println(dp_value_value); 136 | /* After processing the download DP command, the current status should be reported. */ 137 | my_device.mcu_dp_update(DPID_VALUE, dp_value_value, 1); 138 | break; 139 | 140 | case DPID_ENUM: 141 | Serial2.println("Enum type:"); 142 | dp_enum_value = my_device.mcu_get_dp_download_data(dpid, value, length); 143 | Serial2.println(dp_enum_value); 144 | /* After processing the download DP command, the current status should be reported. */ 145 | my_device.mcu_dp_update(DPID_ENUM, dp_enum_value, 1); 146 | break; 147 | 148 | case DPID_STRING: 149 | Serial2.println("String type:"); 150 | /* */ 151 | for (unsigned int i=0; i 14 | 15 | // STM32 16 | // HardwareSerial Serial2(PA_3, PA_2); 17 | 18 | TuyaWifi my_device; 19 | 20 | /* Current LED status */ 21 | unsigned char led_state = 0; 22 | /* Connect network button pin */ 23 | int key_pin = 7; 24 | 25 | /* Data point define */ 26 | #define DPID_SWITCH 20 27 | 28 | TUYA_WIFI_TIME green_time; 29 | unsigned long last_get_green_time; 30 | 31 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 32 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 33 | */ 34 | unsigned char dp_array[][2] = 35 | { 36 | {DPID_SWITCH, DP_TYPE_BOOL}, 37 | }; 38 | 39 | unsigned char pid[] = {"ma67l9sgmdyg3d2k"}; 40 | unsigned char mcu_ver[] = {"1.0.0"}; 41 | 42 | /* last time */ 43 | unsigned long last_time = 0; 44 | 45 | void setup() 46 | { 47 | Serial.begin(9600); 48 | Serial2.begin(9600); 49 | 50 | //Initialize led port, turn off led. 51 | pinMode(LED_BUILTIN, OUTPUT); 52 | digitalWrite(LED_BUILTIN, LOW); 53 | 54 | //Initialize networking keys. 55 | pinMode(key_pin, INPUT_PULLUP); 56 | 57 | //Enter the PID and MCU software version 58 | my_device.init(pid, mcu_ver); 59 | //incoming all DPs and their types array, DP numbers 60 | my_device.set_dp_cmd_total(dp_array, 1); 61 | //register DP download processing callback function 62 | my_device.dp_process_func_register(dp_process); 63 | //register upload all DP callback function 64 | my_device.dp_update_all_func_register(dp_update_all); 65 | 66 | last_time = millis(); 67 | } 68 | 69 | void loop() 70 | { 71 | my_device.uart_service(); 72 | 73 | //Enter the connection network mode when Pin7 is pressed. 74 | if (digitalRead(key_pin) == LOW) { 75 | delay(80); 76 | if (digitalRead(key_pin) == LOW) { 77 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 78 | } 79 | } 80 | /* LED blinks when network is being connected */ 81 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 82 | if (millis()- last_time >= 500) { 83 | last_time = millis(); 84 | 85 | if (led_state == LOW) { 86 | led_state = HIGH; 87 | } else { 88 | led_state = LOW; 89 | } 90 | digitalWrite(LED_BUILTIN, led_state); 91 | } 92 | } 93 | 94 | /* 5s get Greenwich Mean Time */ 95 | if (millis() - last_get_green_time >= 3000) { 96 | last_get_green_time = millis(); 97 | if (TY_SUCCESS == my_device.get_green_time(&green_time, 100)) { /* if network lag, you can increase the timeout */ 98 | Serial2.print(green_time.year); 99 | Serial2.print("-"); 100 | Serial2.print(green_time.month); 101 | Serial2.print("-"); 102 | Serial2.println(green_time.day); 103 | 104 | Serial2.print(green_time.hour); 105 | Serial2.print(":"); 106 | Serial2.print(green_time.minute); 107 | Serial2.print(":"); 108 | Serial2.println(green_time.second); 109 | } else { 110 | Serial2.println("get green time failed"); 111 | } 112 | } 113 | 114 | delay(10); 115 | } 116 | 117 | /** 118 | * @description: DP download callback function. 119 | * @param {unsigned char} dpid 120 | * @param {const unsigned char} value 121 | * @param {unsigned short} length 122 | * @return {unsigned char} 123 | */ 124 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 125 | { 126 | switch(dpid) { 127 | case DPID_SWITCH: 128 | led_state = my_device.mcu_get_dp_download_data(dpid, value, length); /* Get the value of the down DP command */ 129 | if (led_state) { 130 | //Turn on 131 | digitalWrite(LED_BUILTIN, HIGH); 132 | } else { 133 | //Turn off 134 | digitalWrite(LED_BUILTIN, LOW); 135 | } 136 | //Status changes should be reported. 137 | my_device.mcu_dp_update(dpid, value, length); 138 | break; 139 | 140 | default:break; 141 | } 142 | return TY_SUCCESS; 143 | } 144 | 145 | /** 146 | * @description: Upload all DP status of the current device. 147 | * @param {*} 148 | * @return {*} 149 | */ 150 | void dp_update_all(void) 151 | { 152 | my_device.mcu_dp_update(DPID_SWITCH, led_state, 1); 153 | } 154 | 155 | -------------------------------------------------------------------------------- /examples/GetGreenTime/README.md: -------------------------------------------------------------------------------- 1 | # get green time 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | This library only supports the Tuya WiFi+BLE, WiFi module with the generic firmware burned in and verified on the Arduino UNO board. 5 | 6 | **Note: The default Serial serial port in Arduino has been taken over by the Tuya mcu sdk, please do not do anything with the default Serial (pins 0 , 1).** 7 | 8 | 9 | 10 | ## I. Introduction to the demo 11 | 12 | The connection between the Tuya module and the Arduino board will interfere with the burning of the Arduino board. The Arduino board should be disconnected from the Tuya communication board or the Tuya communication board when burning. 13 | 14 | This example uses Arduino board + Tuya wifi communication board. This demo is mainly used to show how to get the network time, using Arduino pin 8 of as RX and pin 9 as TX to print the time information. 15 | 16 | The function of getting time can only be used after the module is successfully networked. 17 | 18 | 19 | ### 1. Get Green time 20 | 21 | **Function** 22 | ```c 23 | char TuyaWifi::get_green_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 24 | ``` 25 | **Parameters:** 26 | + `time`:  Store the data of the time from the module. 27 | ```c 28 | typedef struct 29 | { 30 | unsigned short year; 31 | unsigned char month; 32 | unsigned char day; 33 | unsigned char hour; 34 | unsigned char minute; 35 | unsigned char second; 36 | unsigned char weekday; 37 | 38 | char update_flag; 39 | }TUYA_WIFI_TIME; 40 | ``` 41 | + `timeout`:  Timeout time, unit ms. The timeout time can be extended if the network condition is bad. 42 | 43 | **Return:** 44 | + `1`:  Get success. 45 | + `-1`:  The input parameter is `NULL`, the input parameter is wrong. 46 | + `-2`:  Timeout. 47 | 48 |
49 | 50 | ### 1. Get RTC time 51 | 52 | **Function** 53 | ```c 54 | char TuyaWifi::get_rtc_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 55 | ``` 56 | **Parameters:** 57 | + `time`:  Store the data of the time from the module. 58 | ```c 59 | typedef struct 60 | { 61 | unsigned short year; 62 | unsigned char month; 63 | unsigned char day; 64 | unsigned char hour; 65 | unsigned char minute; 66 | unsigned char second; 67 | unsigned char weekday; 68 | 69 | char update_flag; 70 | }TUYA_WIFI_TIME; 71 | ``` 72 | + `timeout`:  Timeout time, unit ms. The timeout time can be extended if the network condition is bad. 73 | 74 | **Return:** 75 | + `1`:  Get success. 76 | + `-1`:  The input parameter is `NULL`, the input parameter is wrong. 77 | + `-2`:  Timeout. 78 | 79 |
80 | 81 | 82 | ## III. Technical Support 83 | 84 | You can get support for Tuya by using the following methods: 85 | 86 | - Developer Centre: https://developer.tuya.com 87 | - Help Centre: https://support.tuya.com/help 88 | - Technical Support Work Order Centre: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/GetGreenTime/README_zh.md: -------------------------------------------------------------------------------- 1 | # get green time 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | 该库仅支持烧录了通用固件的涂鸦 WiFi+BLE 、WiFi模组,在Arduino UNO板子上验证通过。 5 |
6 | **注意:Arduino 中的 默认Serial 串口已被Tuya mcu sdk 接管,请不要对默认Serial(引脚 0 ,1)做任何操作。** 7 |
8 | 9 | ## 一、demo 介绍 10 | 11 | 涂鸦模组和Arduino板连接时会干扰到对Arduino板的烧录,烧录时应断开Arduino板与涂鸦通信板或涂鸦通信板的连接。例程烧录成功后将Arduino板上串口(Serial) 与 涂鸦模组上的 `RXD` 和 `TXD` 连接起来,然后将UNO板子上的 `Pin7` 脚拉低1s左右(模拟按键按下),设备将会进入配网模式,在进入配网状态和配网过程中Arduino板上LED将会闪烁,打开涂鸦智能APP对设备(Arduino_led)进行配网操作,连接成功后Arduino板上LED将会停止闪烁,配网成功后即可通过APP对设备进行控制。 12 | 13 | 本例程硬件使用了Arduino板+涂鸦wifi通信板,在 start demo 的基础上进行了修改。本 demo 主要用于演示如何获取网络时间,将 Arduino 的 pin 8 作为 RX, pin 9 作为 TX,打印时间信息。 14 | 15 | 获取时间的功能需要在模组成功联网后才可使用。 16 | 17 | ### 1. 获取格林时间 18 | 19 | **函数原型** 20 | ```c 21 | char TuyaWifi::get_green_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 22 | ``` 23 | **Parameters:** 24 | + `time`:  存储从模组上获取的时间的数据。 25 | ```c 26 | typedef struct 27 | { 28 | unsigned short year; 29 | unsigned char month; 30 | unsigned char day; 31 | unsigned char hour; 32 | unsigned char minute; 33 | unsigned char second; 34 | unsigned char weekday; 35 | 36 | char update_flag; 37 | }TUYA_WIFI_TIME; 38 | ``` 39 | + `timeout`:  超时时间,单位 ms。如果网络状况不好可将超时时间适当延长。 40 | 41 | **Return:** 42 | + `1`:  获取成功。 43 | + `-1`:  入参为 `NULL`,入参错误。 44 | + `-2`:  获取时间超时。 45 | 46 |
47 | 48 | ### 2.获取模组RTC时间 49 | 函数原型: 50 | ```c 51 | char TuyaWifi::get_rtc_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 52 | ``` 53 | **Parameters:** 54 | + `time`:  存储从模组上获取的时间的数据。 55 | ```c 56 | typedef struct 57 | { 58 | unsigned short year; 59 | unsigned char month; 60 | unsigned char day; 61 | unsigned char hour; 62 | unsigned char minute; 63 | unsigned char second; 64 | unsigned char weekday; 65 | 66 | char update_flag; 67 | }TUYA_WIFI_TIME; 68 | ``` 69 | + `timeout`:  超时时间,单位 ms。如果网络状况不好可将超时时间适当延长。 70 | 71 | **Return:** 72 | + `1`:  获取成功。 73 | + `-1`:  入参为 `NULL`,入参错误。 74 | + `-2`:  获取时间超时。 75 | 76 |
77 | 78 | ## 二、技术支持 79 | 80 | 您可以通过以下方法获得涂鸦的支持: 81 | 82 | - 开发者中心:https://developer.tuya.com 83 | - 帮助中心: https://support.tuya.com/help 84 | - 技术支持工单中心: https://service.console.tuya.com 85 | -------------------------------------------------------------------------------- /examples/ModuleControlSelf/ModuleControlSelf.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: start.ino 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-11-04 11:06:13 7 | * @LastEditTime: 2021-11-04 14:29:10 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: Note: Please read the readme!!! 11 | * Note: Please read the readme!!! 12 | * Note: Please read the readme!!! 13 | * @Github:https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library 14 | */ 15 | 16 | #include 17 | 18 | TuyaWifi my_device; 19 | 20 | /* Data point define */ 21 | #define DPID_SWITCH 20 22 | 23 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 24 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 25 | */ 26 | unsigned char dp_array[][2] = 27 | { 28 | {DPID_SWITCH, DP_TYPE_BOOL}, 29 | }; 30 | 31 | unsigned char pid[] = {"ma67l9sgmdyg3d2k"}; 32 | unsigned char mcu_ver[] = {"1.0.0"}; 33 | 34 | void setup() 35 | { 36 | // Serial.begin(9600); 37 | Serial.begin(9600); 38 | 39 | //Enter the PID and MCU software version 40 | my_device.init(pid, mcu_ver); 41 | //incoming all DPs and their types array, DP numbers 42 | my_device.set_dp_cmd_total(dp_array, 1); 43 | //register DP download processing callback function 44 | my_device.dp_process_func_register(dp_process); 45 | //register upload all DP callback function 46 | my_device.dp_update_all_func_register(dp_update_all); 47 | 48 | /* set tuya module pin 16 as led, set tuya module pin 28 as connect wifi key. 49 | * Long press 5s to enter networking mode. 50 | */ 51 | my_device.set_state_pin(16, 28); 52 | } 53 | 54 | void loop() 55 | { 56 | my_device.uart_service(); 57 | 58 | delay(10); 59 | } 60 | 61 | /** 62 | * @description: DP download callback function. 63 | * @param {unsigned char} dpid 64 | * @param {const unsigned char} value 65 | * @param {unsigned short} length 66 | * @return {unsigned char} 67 | */ 68 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 69 | { 70 | switch(dpid) { 71 | case DPID_SWITCH: 72 | led_state = my_device.mcu_get_dp_download_data(dpid, value, length); /* Get the value of the down DP command */ 73 | if (led_state) { 74 | //Turn on 75 | digitalWrite(LED_BUILTIN, HIGH); 76 | } else { 77 | //Turn off 78 | digitalWrite(LED_BUILTIN, LOW); 79 | } 80 | //Status changes should be reported. 81 | my_device.mcu_dp_update(dpid, value, length); 82 | break; 83 | 84 | default:break; 85 | } 86 | return TY_SUCCESS; 87 | } 88 | 89 | /** 90 | * @description: Upload all DP status of the current device. 91 | * @param {*} 92 | * @return {*} 93 | */ 94 | void dp_update_all(void) 95 | { 96 | my_device.mcu_dp_update(DPID_SWITCH, led_state, 1); 97 | } 98 | -------------------------------------------------------------------------------- /examples/ModuleControlSelf/README.md: -------------------------------------------------------------------------------- 1 | # Module control self 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | This library only supports the Tuya WiFi+BLE, WiFi module with the generic firmware burned in and verified on the Arduino UNO board. 5 | 6 | **Note: The default Serial serial port in Arduino has been taken over by the Tuya mcu sdk, please do not do anything with the default Serial (pins 0 , 1).** 7 | 8 | 9 | 10 | ## I. Introduction to the demo 11 | 12 | The connection between the Tuya module and the Arduino board will interfere with the burning of the Arduino board. The Arduino board should be disconnected from the Tuya communication board or the Tuya communication board when burning. 13 | 14 | This example uses Arduino board + Tuya wifi communication board and is modified from the start demo. This demo is mainly used to show how to use the module self-processing function. 15 |
16 | 17 | ### 1. How to open the module self-processing function? 18 | In `.. /.. /config.h`, change `#define WIFI_CONTROL_SELF_MODE 0` to 19 | 20 | ```c 21 | #define WIFI_CONTROL_SELF_MODE 1 22 | ``` 23 | It turns on the module self-processing function. 24 | **This function is turned off by default. After turning it on, other demos will have compilation errors except this demo. Because some functions can not be used under module self-processing, such as getting the current network connection status, mcu sending re-entering network mode and other functions can not be used.** 25 |
26 | 27 | ### 2. What does the module self-processing function do? 28 | The main function of the module self-processing function is to leave the function of the wiring indicator and wiring button to the module, so the pin pin on the module is used. Developers do not need to implement the function of the wiring button and wiring indicator on the MCU. Press and hold the wiring button for 5s to start the module into the wiring state. 29 |
30 | 31 | ### 3. How to use the module self-processing function? 32 | First, you need to enable the module self-processing function. Then you need to call the function in `setup()` to configure the pins of the module as the led pin and button pin. 33 | If you do not call the function, the default parameters will be used. The default `pin 16` is the pin for the wiring indicator and `pin 28` is the pin for the wiring button. 34 | 35 | ```c 36 | void set_state_pin(unsigned char led_pin, unsigned char key_pin); 37 | ``` 38 |
39 | 40 | ## III. Technical Support 41 | 42 | You can get support for Tuya by using the following methods: 43 | 44 | - Developer Centre: https://developer.tuya.com 45 | - Help Centre: https://support.tuya.com/help 46 | - Technical Support Work Order Centre: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/ModuleControlSelf/README_zh.md: -------------------------------------------------------------------------------- 1 | # Module control self 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | 该库仅支持烧录了通用固件的涂鸦 WiFi+BLE 、WiFi模组,在Arduino UNO板子上验证通过。 5 |
6 | **注意:Arduino 中的 默认Serial 串口已被Tuya mcu sdk 接管,请不要对默认Serial(引脚 0 ,1)做任何操作。** 7 |
8 | ## 一、demo 介绍 9 | 10 | 涂鸦模组和Arduino板连接时会干扰到对Arduino板的烧录,烧录时应断开Arduino板与涂鸦通信板或涂鸦通信板的连接。 11 | 12 | 本例程硬件使用了Arduino板+涂鸦wifi通信板,在 start demo 的基础上进行了修改。本 demo 主要用于演示模组自处理功能如何使用。 13 | ### 1.如何开启模组自处理功能 14 | 在 `../../config.h` 中将 `#define WIFI_CONTROL_SELF_MODE 0` 更改为: 15 | ```c 16 | #define WIFI_CONTROL_SELF_MODE 1 17 | ``` 18 | 就开启了模组自处理功能。 19 | **该功能默认关闭,打开后除本 demo 外,其他 demo 会出现编译错误的情况。因为在模组自处理下部分功能无法使用,如获取当前网络连接状态,mcu 发送重新进入配网模式等功能无法使用。** 20 |
21 | 22 | ### 2.模组自处理功能有什么作用 23 | 模组自处理功能,主要作用是将配网指示灯和配网按键的功能交给了模组去处理,所以使用的也就是模组上的 pin 脚。开发者不用在 MCU 上实现配网按键和配网指示灯的功能了。长按配网按键 5s 开始进入模组进入配网状态。 24 |
25 | 26 | ### 3.如何使用模组自处理功能 27 | 首先要开启模组自处理功能。然后需要在 `setup()` 内调用下面的函数配置对应模组的引脚作为配网指示灯和配网按键的引脚。 28 | 不调用函数修改,将会使用默认参数进行设置。默认 `pin 16` 为配网指示灯的引脚, `pin 28` 为配网按键的引脚。 29 | ```c 30 | void set_state_pin(unsigned char led_pin, unsigned char key_pin); 31 | ``` 32 |
33 | 34 | ## 二、技术支持 35 | 36 | 您可以通过以下方法获得涂鸦的支持: 37 | 38 | - 开发者中心:https://developer.tuya.com 39 | - 帮助中心: https://support.tuya.com/help 40 | - 技术支持工单中心: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/SHT30/README.md: -------------------------------------------------------------------------------- 1 | # SHT30 2 | 3 | [English](./README.md) | [中文](./README_zh.md) 4 | 5 | This library only supports the Tuya WiFi+BLE, WiFi module with the generic firmware burned in and verified on the Arduino UNO board. 6 | 7 | **Note: The default Serial serial port in Arduino has been taken over by the Tuya mcu sdk, please do not do anything with the default Serial (pins 0 , 1).** 8 | 9 | ## I. Introduction to the demo 10 | 11 | The connection between the Tuya module and the Arduino board will interfere with the burning of the Arduino board. The Arduino board should be disconnected from the Tuya communication board or the Tuya communication board when burning. After the routine is successfully burned, connect the serial port (Serial) on the Arduino board to the `RXD` and `TXD` on the Tuya module, then pull down the `Pin7` pin on the UNO board for about 1s (simulating a key press), the device will enter the connection network mode, the LED on the Arduino board will flash during the connection network state and connection network process After successful connection, the LED on the Arduino board will stop flashing and the device can be controlled by the APP. 12 | 13 | This example uses an Arduino board, a Tuya wifi communication board and a SHT30 temperature and humidity sensor. The device uploads the temperature and humidity values of the current environment every 1 second, which can be viewed through the Tuya Smart App. 14 | 15 | ## II. Functional realisation 16 | 17 | In the [Tuya IoT platform](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2) after creating the product, the implementation of the code part can be mainly divided into three major parts: network distribution, device information initialization, and obtaining SHT30 sensing information. 18 | 19 | The distribution network section. 20 | 21 | ```c 22 | /* Current LED status */ 23 | unsigned char led_state = 0; 24 | /* Connect network button pin */ 25 | int wifi_key_pin = 7; 26 | /* last time */ 27 | unsigned long last_time = 0; 28 | 29 | void setup() 30 | { 31 | ... 32 | /* Related peripheral initialization */ 33 | //Initialize led port, turn off led. 34 | pinMode(LED_BUILTIN, OUTPUT); 35 | digitalWrite(LED_BUILTIN, LOW); 36 | //Initialize networking keys. 37 | pinMode(wifi_key_pin, INPUT_PULLUP); 38 | ... 39 | last_time = millis(); 40 | } 41 | 42 | void loop() 43 | { 44 | ... 45 | //Enter the connection network mode when Pin7 is pressed. 46 | if (digitalRead(wifi_key_pin) == LOW) { 47 | delay(80); 48 | if (digitalRead(wifi_key_pin) == LOW) { 49 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 50 | } 51 | } 52 | /* LED blinks when network is being connected */ 53 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 54 | if (millis()- last_time >= 500) { 55 | last_time = millis(); 56 | 57 | if (led_state == LOW) { 58 | led_state = HIGH; 59 | } else { 60 | led_state = LOW; 61 | } 62 | 63 | digitalWrite(LED_BUILTIN, led_state); 64 | } 65 | ... 66 | } 67 | ``` 68 | 69 | 70 | 71 | Device information initialization. 72 | 73 | ```c 74 | #include 75 | 76 | TuyaWifi my_device; 77 | 78 | /* Data point define */ 79 | #define DPID_TEMP_CURRENT 1 80 | #define DPID_HUMIDITY_CURRENT 2 81 | 82 | /* Current device DP values */ 83 | int temperature = 0; 84 | int humidity = 0; 85 | 86 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 87 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 88 | */ 89 | unsigned char dp_array[][2] = 90 | { 91 | {DPID_TEMP_CURRENT, DP_TYPE_VALUE}, 92 | {DPID_HUMIDITY_CURRENT, DP_TYPE_VALUE}, 93 | }; 94 | 95 | unsigned char pid[] = {"xxxxxxxxxxxxxxxx"};//xxxxxxxxxxxxxxxx is your PID 96 | unsigned char mcu_ver[] = {"1.0.0"}; 97 | 98 | void setup() 99 | { 100 | Serial.begin(9600); 101 | ... 102 | my_device.init(pid, mcu_ver); 103 | //incoming all DPs and their types array, DP numbers 104 | my_device.set_dp_cmd_total(dp_array, 2); 105 | //register DP download processing callback function 106 | my_device.dp_process_func_register(dp_process); 107 | //register upload all DP callback function 108 | my_device.dp_update_all_func_register(dp_update_all); 109 | ... 110 | } 111 | 112 | void loop() 113 | { 114 | my_device.uart_service(); 115 | ... 116 | delay(1000); 117 | } 118 | 119 | /** 120 | * @description: DP download callback function. 121 | * @param {unsigned char} dpid 122 | * @param {const unsigned char} value 123 | * @param {unsigned short} length 124 | * @return {unsigned char} 125 | */ 126 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 127 | { 128 | /* all DP only report */ 129 | return SUCCESS; 130 | } 131 | 132 | /** 133 | * @description: Upload all DP status of the current device. 134 | * @param {*} 135 | * @return {*} 136 | */ 137 | void dp_update_all(void) 138 | { 139 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 140 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 141 | } 142 | ``` 143 | 144 | 145 | 146 | Get SHT30 sensor data. 147 | 148 | ```c 149 | #include 150 | 151 | /* SHT30 */ 152 | #define SHT30_I2C_ADDR 0x44 153 | 154 | /* Current device DP values */ 155 | int temperature = 0; 156 | int humidity = 0; 157 | 158 | void setup() 159 | { 160 | ... 161 | // Initialise I2C communication as MASTER 162 | Wire.begin(); 163 | ... 164 | } 165 | 166 | void loop() 167 | { 168 | ... 169 | /* get the temperature and humidity */ 170 | get_sht30_value(&temperature, &humidity); 171 | 172 | if ((my_device.mcu_get_wifi_work_state() == WIFI_CONNECTED) || (my_device.mcu_get_wifi_work_state() == WIFI_CONN_CLOUD)) { 173 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 174 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 175 | } 176 | 177 | delay(1000); 178 | } 179 | 180 | void get_sht30_value(int *temp_value, int *humi_value) 181 | { 182 | unsigned char i2c_data[6]; 183 | 184 | // Start I2C Transmission 185 | Wire.beginTransmission(SHT30_I2C_ADDR); 186 | // Send measurement command 187 | Wire.write(0x2C); 188 | Wire.write(0x06); 189 | // Stop I2C transmission 190 | Wire.endTransmission(); 191 | delay(500); 192 | 193 | // Request 6 bytes of data 194 | Wire.requestFrom(SHT30_I2C_ADDR, 6); 195 | 196 | // Read 6 bytes of i2c_data 197 | // temperature msb, temperature lsb, temperature crc, humidity msb, humidity lsb, humidity crc 198 | if (Wire.available() == 6) { 199 | for (int i = 0; i < 6 ; i++) { 200 | i2c_data[i] = Wire.read(); 201 | } 202 | 203 | if ((sht30_crc(i2c_data, 2) == i2c_data[2]) && (sht30_crc(i2c_data+3, 2) == i2c_data[5])) {/* crc success */ 204 | *temp_value = (((((i2c_data[0] * 256.0) + i2c_data[1]) * 175) / 65535.0) - 45) * 100; 205 | *humi_value = ((((i2c_data[3] * 256.0) + i2c_data[4]) * 100) / 65535.0) * 100; 206 | } else { 207 | *temp_value = 0; 208 | *humi_value = 0; 209 | } 210 | } 211 | } 212 | 213 | /** 214 | * @description: check sht30 temperature and humidity data 215 | * @param {unsigned char} *data 216 | * @param {unsigned int} count 217 | * @return {*} 218 | */ 219 | unsigned char sht30_crc(unsigned char *data, unsigned int count) 220 | { 221 | unsigned char crc = 0xff; 222 | unsigned char current_byte; 223 | unsigned char crc_bit; 224 | 225 | /* calculates 8-Bit checksum with given polynomial */ 226 | for (current_byte = 0; current_byte < count; ++current_byte) 227 | { 228 | crc ^= (data[current_byte]); 229 | for (crc_bit = 8; crc_bit > 0; --crc_bit) 230 | { 231 | if (crc & 0x80) 232 | crc = (crc << 1) ^ 0x31; 233 | else 234 | crc = (crc << 1); 235 | } 236 | } 237 | return crc; 238 | } 239 | ``` 240 | 241 | 242 | 243 | ## III. Technical support 244 | 245 | You can get support for Tuya by using the following methods: 246 | 247 | - Developer Centre: https://developer.tuya.com 248 | - Help Centre: https://support.tuya.com/help 249 | - Technical Support Work Order Centre: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/SHT30/README_zh.md: -------------------------------------------------------------------------------- 1 | # SHT30 2 | 3 | [English](./README.md) | [中文](./README_zh.md) 4 | 5 | 该库仅支持烧录了通用固件的涂鸦 WiFi+BLE 、WiFi模组,在Arduino UNO板子上验证通过。 6 | 7 | **注意:Arduino 中的 默认Serial 串口已被Tuya mcu sdk 接管,请不要对默认Serial(引脚 0 ,1)做任何操作。** 8 | 9 | ## 一、demo 介绍 10 | 11 | 涂鸦模组和Arduino板连接时会干扰到对Arduino板的烧录,烧录时应断开Arduino板与涂鸦通信板或涂鸦通信板的连接。例程烧录成功后将Arduino板上串口(Serial) 与 涂鸦模组上的 `RXD` 和 `TXD` 连接起来,然后将UNO板子上的 `Pin7` 脚拉低1s左右(模拟按键按下),设备将会进入配网模式,在进入配网状态和配网过程中Arduino板上LED将会闪烁,打开涂鸦智能APP对设备(Arduino_SHT30)进行配网操作,连接成功后Arduino板上LED将会停止闪烁,配网成功后即可通过APP对设备进行控制。 12 | 13 | 本例程硬件使用了Arduino板+涂鸦wifi通信板+SHT30温湿度传感器,设备每隔1秒上传一次当前环境下温湿度值,可通过涂鸦智能APP配网后查看。 14 | 15 | ## 二、功能实现 16 | 17 | 在[涂鸦IoT平台](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2) 创建完产品后,代码部分的实现主要可以分为配网、设备信息初始化、获取SHT30传感信息三大部分。 18 | 19 | 配网部分: 20 | 21 | ```c 22 | /* Current LED status */ 23 | unsigned char led_state = 0; 24 | /* Connect network button pin */ 25 | int wifi_key_pin = 7; 26 | /* last time */ 27 | unsigned long last_time = 0; 28 | 29 | void setup() 30 | { 31 | ... 32 | /* 相关外设初始化 */ 33 | //Initialize led port, turn off led. 34 | pinMode(LED_BUILTIN, OUTPUT); 35 | digitalWrite(LED_BUILTIN, LOW); 36 | //Initialize networking keys. 37 | pinMode(wifi_key_pin, INPUT_PULLUP); 38 | ... 39 | last_time = millis(); 40 | } 41 | 42 | void loop() 43 | { 44 | ... 45 | //Enter the connection network mode when Pin7 is pressed. 46 | if (digitalRead(wifi_key_pin) == LOW) { 47 | delay(80); 48 | if (digitalRead(wifi_key_pin) == LOW) { 49 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 50 | } 51 | } 52 | /* LED blinks when network is being connected */ 53 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 54 | if (millis()- last_time >= 500) { 55 | last_time = millis(); 56 | 57 | if (led_state == LOW) { 58 | led_state = HIGH; 59 | } else { 60 | led_state = LOW; 61 | } 62 | 63 | digitalWrite(LED_BUILTIN, led_state); 64 | } 65 | ... 66 | } 67 | ``` 68 | 69 | 70 | 71 | 设备信息初始化: 72 | 73 | ```c 74 | #include 75 | 76 | TuyaWifi my_device; 77 | 78 | /* Data point define */ 79 | #define DPID_TEMP_CURRENT 1 80 | #define DPID_HUMIDITY_CURRENT 2 81 | 82 | /* Current device DP values */ 83 | int temperature = 0; 84 | int humidity = 0; 85 | 86 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 87 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 88 | */ 89 | unsigned char dp_array[][2] = 90 | { 91 | {DPID_TEMP_CURRENT, DP_TYPE_VALUE}, 92 | {DPID_HUMIDITY_CURRENT, DP_TYPE_VALUE}, 93 | }; 94 | 95 | unsigned char pid[] = {"xxxxxxxxxxxxxxxx"};//xxxxxxxxxxxxxxxx 应为你的PID 96 | unsigned char mcu_ver[] = {"1.0.0"}; 97 | 98 | void setup() 99 | { 100 | Serial.begin(9600); 101 | ... 102 | my_device.init(pid, mcu_ver); 103 | //incoming all DPs and their types array, DP numbers 104 | my_device.set_dp_cmd_total(dp_array, 2); 105 | //register DP download processing callback function 106 | my_device.dp_process_func_register(dp_process); 107 | //register upload all DP callback function 108 | my_device.dp_update_all_func_register(dp_update_all); 109 | ... 110 | } 111 | 112 | void loop() 113 | { 114 | my_device.uart_service(); 115 | ... 116 | delay(1000); 117 | } 118 | 119 | /** 120 | * @description: DP download callback function. 121 | * @param {unsigned char} dpid 122 | * @param {const unsigned char} value 123 | * @param {unsigned short} length 124 | * @return {unsigned char} 125 | */ 126 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 127 | { 128 | /* all DP only report */ 129 | return SUCCESS; 130 | } 131 | 132 | /** 133 | * @description: Upload all DP status of the current device. 134 | * @param {*} 135 | * @return {*} 136 | */ 137 | void dp_update_all(void) 138 | { 139 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 140 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 141 | } 142 | ``` 143 | 144 | 145 | 146 | 获取SHT30传感器信息: 147 | 148 | ```c 149 | #include 150 | 151 | /* SHT30 */ 152 | #define SHT30_I2C_ADDR 0x44 153 | 154 | /* Current device DP values */ 155 | int temperature = 0; 156 | int humidity = 0; 157 | 158 | void setup() 159 | { 160 | ... 161 | // Initialise I2C communication as MASTER 162 | Wire.begin(); 163 | ... 164 | } 165 | 166 | void loop() 167 | { 168 | ... 169 | /* get the temperature and humidity */ 170 | get_sht30_value(&temperature, &humidity); 171 | 172 | if ((my_device.mcu_get_wifi_work_state() == WIFI_CONNECTED) || (my_device.mcu_get_wifi_work_state() == WIFI_CONN_CLOUD)) { 173 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 174 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 175 | } 176 | 177 | delay(1000); 178 | } 179 | 180 | void get_sht30_value(int *temp_value, int *humi_value) 181 | { 182 | unsigned char i2c_data[6]; 183 | 184 | // Start I2C Transmission 185 | Wire.beginTransmission(SHT30_I2C_ADDR); 186 | // Send measurement command 187 | Wire.write(0x2C); 188 | Wire.write(0x06); 189 | // Stop I2C transmission 190 | Wire.endTransmission(); 191 | delay(500); 192 | 193 | // Request 6 bytes of data 194 | Wire.requestFrom(SHT30_I2C_ADDR, 6); 195 | 196 | // Read 6 bytes of i2c_data 197 | // temperature msb, temperature lsb, temperature crc, humidity msb, humidity lsb, humidity crc 198 | if (Wire.available() == 6) { 199 | for (int i = 0; i < 6 ; i++) { 200 | i2c_data[i] = Wire.read(); 201 | } 202 | 203 | if ((sht30_crc(i2c_data, 2) == i2c_data[2]) && (sht30_crc(i2c_data+3, 2) == i2c_data[5])) {/* crc success */ 204 | *temp_value = (((((i2c_data[0] * 256.0) + i2c_data[1]) * 175) / 65535.0) - 45) * 100; 205 | *humi_value = ((((i2c_data[3] * 256.0) + i2c_data[4]) * 100) / 65535.0) * 100; 206 | } else { 207 | *temp_value = 0; 208 | *humi_value = 0; 209 | } 210 | } 211 | } 212 | 213 | /** 214 | * @description: check sht30 temperature and humidity data 215 | * @param {unsigned char} *data 216 | * @param {unsigned int} count 217 | * @return {*} 218 | */ 219 | unsigned char sht30_crc(unsigned char *data, unsigned int count) 220 | { 221 | unsigned char crc = 0xff; 222 | unsigned char current_byte; 223 | unsigned char crc_bit; 224 | 225 | /* calculates 8-Bit checksum with given polynomial */ 226 | for (current_byte = 0; current_byte < count; ++current_byte) 227 | { 228 | crc ^= (data[current_byte]); 229 | for (crc_bit = 8; crc_bit > 0; --crc_bit) 230 | { 231 | if (crc & 0x80) 232 | crc = (crc << 1) ^ 0x31; 233 | else 234 | crc = (crc << 1); 235 | } 236 | } 237 | return crc; 238 | } 239 | ``` 240 | 241 | 242 | 243 | ## 三、技术支持 244 | 245 | 您可以通过以下方法获得涂鸦的支持: 246 | 247 | - 开发者中心:https://developer.tuya.com 248 | - 帮助中心: https://support.tuya.com/cn/help 249 | - 技术支持工单中心: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/SHT30/SHT30.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: SHT30_DIS.ino 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-21 15:23:49 7 | * @LastEditTime: 2021-11-01 10:01:57 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | * @Github:https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library 12 | */ 13 | #include 14 | #include 15 | 16 | TuyaWifi my_device; 17 | 18 | /* Current LED status */ 19 | unsigned char led_state = 0; 20 | /* Connect network button pin */ 21 | int wifi_key_pin = 7; 22 | 23 | /* SHT30 */ 24 | #define SHT30_I2C_ADDR 0x44 25 | 26 | /* Data point define */ 27 | #define DPID_TEMP_CURRENT 1 28 | #define DPID_HUMIDITY_CURRENT 2 29 | 30 | /* Current device DP values */ 31 | int temperature = 0; 32 | int humidity = 0; 33 | 34 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 35 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 36 | */ 37 | unsigned char dp_array[][2] = 38 | { 39 | {DPID_TEMP_CURRENT, DP_TYPE_VALUE}, 40 | {DPID_HUMIDITY_CURRENT, DP_TYPE_VALUE}, 41 | }; 42 | 43 | unsigned char pid[] = {"so33adeiympep2v6"}; 44 | unsigned char mcu_ver[] = {"1.0.0"}; 45 | 46 | /* last time */ 47 | unsigned long last_time = 0; 48 | 49 | void setup() 50 | { 51 | Serial.begin(9600); 52 | 53 | // Initialise I2C communication as MASTER 54 | Wire.begin(); 55 | 56 | //Initialize led port, turn off led. 57 | pinMode(LED_BUILTIN, OUTPUT); 58 | digitalWrite(LED_BUILTIN, LOW); 59 | //Initialize networking keys. 60 | pinMode(wifi_key_pin, INPUT_PULLUP); 61 | 62 | my_device.init(pid, mcu_ver); 63 | //incoming all DPs and their types array, DP numbers 64 | my_device.set_dp_cmd_total(dp_array, 2); 65 | //register DP download processing callback function 66 | my_device.dp_process_func_register(dp_process); 67 | //register upload all DP callback function 68 | my_device.dp_update_all_func_register(dp_update_all); 69 | 70 | delay(300); 71 | last_time = millis(); 72 | } 73 | 74 | void loop() 75 | { 76 | my_device.uart_service(); 77 | 78 | //Enter the connection network mode when Pin7 is pressed. 79 | if (digitalRead(wifi_key_pin) == LOW) { 80 | delay(80); 81 | if (digitalRead(wifi_key_pin) == LOW) { 82 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 83 | } 84 | } 85 | /* LED blinks when network is being connected */ 86 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 87 | if (millis()- last_time >= 500) { 88 | last_time = millis(); 89 | 90 | if (led_state == LOW) { 91 | led_state = HIGH; 92 | } else { 93 | led_state = LOW; 94 | } 95 | 96 | digitalWrite(LED_BUILTIN, led_state); 97 | } 98 | } 99 | 100 | /* get the temperature and humidity */ 101 | get_sht30_value(&temperature, &humidity); 102 | 103 | /* report the temperature and humidity */ 104 | if ((my_device.mcu_get_wifi_work_state() == WIFI_CONNECTED) || (my_device.mcu_get_wifi_work_state() == WIFI_CONN_CLOUD)) { 105 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 106 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 107 | } 108 | 109 | delay(1000); 110 | } 111 | 112 | void get_sht30_value(int *temp_value, int *humi_value) 113 | { 114 | unsigned char i2c_data[6]; 115 | 116 | // Start I2C Transmission 117 | Wire.beginTransmission(SHT30_I2C_ADDR); 118 | // Send measurement command 119 | Wire.write(0x2C); 120 | Wire.write(0x06); 121 | // Stop I2C transmission 122 | Wire.endTransmission(); 123 | delay(500); 124 | 125 | // Request 6 bytes of data 126 | Wire.requestFrom(SHT30_I2C_ADDR, 6); 127 | 128 | // Read 6 bytes of i2c_data 129 | // temperature msb, temperature lsb, temperature crc, humidity msb, humidity lsb, humidity crc 130 | if (Wire.available() == 6) { 131 | for (int i = 0; i < 6 ; i++) { 132 | i2c_data[i] = Wire.read(); 133 | } 134 | 135 | if ((sht30_crc(i2c_data, 2) == i2c_data[2]) && (sht30_crc(i2c_data+3, 2) == i2c_data[5])) {/* crc success */ 136 | *temp_value = (((((i2c_data[0] * 256.0) + i2c_data[1]) * 175) / 65535.0) - 45) * 100; 137 | *humi_value = ((((i2c_data[3] * 256.0) + i2c_data[4]) * 100) / 65535.0) * 100; 138 | } else { 139 | *temp_value = 0; 140 | *humi_value = 0; 141 | } 142 | } 143 | } 144 | 145 | /** 146 | * @description: check sht30 temperature and humidity data 147 | * @param {unsigned char} *data 148 | * @param {unsigned int} count 149 | * @return {*} 150 | */ 151 | unsigned char sht30_crc(unsigned char *data, unsigned int count) 152 | { 153 | unsigned char crc = 0xff; 154 | unsigned char current_byte; 155 | unsigned char crc_bit; 156 | 157 | /* calculates 8-Bit checksum with given polynomial */ 158 | for (current_byte = 0; current_byte < count; ++current_byte) 159 | { 160 | crc ^= (data[current_byte]); 161 | for (crc_bit = 8; crc_bit > 0; --crc_bit) 162 | { 163 | if (crc & 0x80) 164 | crc = (crc << 1) ^ 0x31; 165 | else 166 | crc = (crc << 1); 167 | } 168 | } 169 | return crc; 170 | } 171 | 172 | /** 173 | * @description: DP download callback function. 174 | * @param {unsigned char} dpid 175 | * @param {const unsigned char} value 176 | * @param {unsigned short} length 177 | * @return {unsigned char} 178 | */ 179 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 180 | { 181 | /* all DP only report */ 182 | return TY_SUCCESS; 183 | } 184 | 185 | /** 186 | * @description: Upload all DP status of the current device. 187 | * @param {*} 188 | * @return {*} 189 | */ 190 | void dp_update_all(void) 191 | { 192 | my_device.mcu_dp_update(DPID_TEMP_CURRENT, temperature, 1); 193 | my_device.mcu_dp_update(DPID_HUMIDITY_CURRENT, humidity, 1); 194 | } 195 | 196 | 197 | -------------------------------------------------------------------------------- /examples/start/README.md: -------------------------------------------------------------------------------- 1 | # start 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | This library only supports the Tuya WiFi+BLE, WiFi module with the generic firmware burned in and verified on the Arduino UNO board. 5 | 6 | **Note: The default Serial serial port in Arduino has been taken over by the Tuya mcu sdk, please do not do anything with the default Serial (pins 0 , 1).** 7 | 8 | 9 | 10 | ## I. Introduction to the demo 11 | 12 | The connection between the Tuya module and the Arduino board will interfere with the burning of the Arduino board. The Arduino board should be disconnected from the Tuya communication board or the Tuya communication board when burning. After the routine is successfully burned, connect the serial port (Serial) on the Arduino board to the `RXD` and `TXD` on the Tuya module, then pull down the `Pin7` pin on the UNO board for about 1s (simulating a key press), the device will enter the connection network mode, the LED on the Arduino board will flash during the connection network state and connection network process After successful connection, the LED on the Arduino board will stop flashing and the device can be controlled by the APP. 13 | 14 | This example uses Arduino board + Tuya wifi communication board, which can be controlled by the Arduino board after connection network through the Tuya Smart App. 15 | 16 | 17 | 18 | ## II. Function Implementation 19 | 20 | ### 1. Create product 21 | 22 | Go to [Tuya IoT Platform](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2) to create a product. 23 | 24 | ![creat_produce1](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce1.png) 25 | 26 | Select category, programme. 27 | 28 | ![creat_produce2](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce2.png) 29 | 30 | Complete the product information and click on create product: ! 31 | 32 | ![creat_produce3](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce3.png) 33 | 34 | Select the relevant functions according to your needs and click on Confirm: ! 35 | 36 | ![create_produce4](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce4.png) 37 | 38 | After selecting the device panel, go to Hardware Development, select the Tuya Standard Module MCU SDK development method and select the corresponding module: 39 | 40 | ![create_produce6](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce6.png) 41 | 42 | Select the firmware. 43 | 44 | ![create_produce7](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce7.png) 45 | 46 | ### 2. Important function descriptions 47 | 48 | Initialise the serial port, the generic firmware of the Tuya WIFi module supports 115200, 9600 baud rate adaptive, so the serial port should be initialised to 115200 or 9600 when initialising the serial port. in `setup()`. 49 | 50 | ```c++ 51 | Serial.begin(9600); 52 | ``` 53 | 54 | mcu needs to send the created PID and the mcu's software version number to the Tuya Cloud module. In `setup()`. 55 | 56 | ```c++ 57 | //Enter the PID and MCU software version 58 | my_device.init("ma67l9sgmdyg3d2k", "1.0.0"); 59 | ``` 60 | 61 | We need to pass the ID and type of the DP selected when creating the product into the MCU SDK to use. 62 | 63 | ```c++ 64 | TuyaWifi my_device; 65 | 66 | #define DPID_SWITCH 20 //DP ID 67 | 68 | unsigned char dp_array[][2] = 69 | { 70 | //This product was created with only one DP point selected, so there is only one piece of information in this array 71 | {DPID_SWITCH, DP_TYPE_BOOL}, // the first one is filled with the DP point ID, the second one is the data type of the DP point 72 | }; 73 | 74 | void setup() 75 | { 76 | ... 77 | my_device.set_dp_cmd_total(dp_array, 1); //dp_array: is an array of DP point IDs and data types, 1: is the number of DPs defined in the array 78 | ... 79 | } 80 | 81 | ``` 82 | 83 | The initialization also requires registration of the DP point down processing function and the upload all DP points function. 84 | 85 | ```c++ 86 | unsigned char led_state = 0; 87 | 88 | void setup() 89 | { 90 | ... 91 | //register DP download processing callback function 92 | my_device.dp_process_func_register(led_dp_process); //register DP download processing callback function 93 | //register upload all DP callback function 94 | my_device.dp_update_all_func_register(dp_update_all); //register device status function, upload all DP points 95 | ... 96 | } 97 | 98 | void loop() 99 | { 100 | ... 101 | my_device.uart_service(); 102 | ... 103 | } 104 | 105 | /** 106 | * @description: DP download callback function. 107 | * @param {unsigned char} dpid 108 | * @param {const unsigned char} value 109 | * @param {unsigned short} length 110 | * @return {unsigned char} 111 | */ 112 | unsigned char led_dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 113 | { 114 | switch(dpid) { 115 | case DPID_SWITCH: 116 | led_state = my_device.mcu_get_dp_download_data(dpid, value, length);//get the data of this DP in the downstream data frame 117 | if (led_state) { 118 | digitalWrite(LED_BUILTIN, HIGH); 119 | } else { 120 | digitalWrite(LED_BUILTIN, LOW); 121 | } 122 | my_device.mcu_dp_update(dpid, value, length); 123 | break; 124 | 125 | default:break; 126 | } 127 | return 1; 128 | } 129 | 130 | /** 131 | * @description: Upload all DP status of the current device. 132 | * @param {*} 133 | * @return {*} 134 | */ 135 | void dp_update_all(void) 136 | { 137 | my_device.mcu_dp_update(DPID_SWITCH, &led_state, 1); 138 | } 139 | ``` 140 | 141 | 142 | 143 | ## III. Technical Support 144 | 145 | You can get support for Tuya by using the following methods: 146 | 147 | - Developer Centre: https://developer.tuya.com 148 | - Help Centre: https://support.tuya.com/help 149 | - Technical Support Work Order Centre: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/start/README_zh.md: -------------------------------------------------------------------------------- 1 | # start 2 | [English](./README.md) | [中文](./README_zh.md) 3 | 4 | 该库仅支持烧录了通用固件的涂鸦 WiFi+BLE 、WiFi模组,在Arduino UNO板子上验证通过。 5 | 6 | **注意:Arduino 中的 默认Serial 串口已被Tuya mcu sdk 接管,请不要对默认Serial(引脚 0 ,1)做任何操作。** 7 | 8 | 9 | 10 | ## 一、demo 介绍 11 | 12 | 涂鸦模组和Arduino板连接时会干扰到对Arduino板的烧录,烧录时应断开Arduino板与涂鸦通信板或涂鸦通信板的连接。例程烧录成功后将Arduino板上串口(Serial) 与 涂鸦模组上的 `RXD` 和 `TXD` 连接起来,然后将UNO板子上的 `Pin7` 脚拉低1s左右(模拟按键按下),设备将会进入配网模式,在进入配网状态和配网过程中Arduino板上LED将会闪烁,打开涂鸦智能APP对设备(Arduino_led)进行配网操作,连接成功后Arduino板上LED将会停止闪烁,配网成功后即可通过APP对设备进行控制。 13 | 14 | 本例程硬件使用了Arduino板+涂鸦wifi通信板,可通过涂鸦智能APP配网后对Arduino板上LED进行控制。 15 | 16 | 17 | 18 | ## 二、功能实现 19 | 20 | ### 1、创建产品 21 | 22 | 进入 [Tuya IoT平台](https://iot.tuya.com/?_source=97c44038fafc20e9c8dd5fdb508cc9c2) 创建产品: 23 | 24 | ![creat_produce1](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce1.png) 25 | 26 | 选择品类,方案: 27 | 28 | ![creat_produce2](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce2.png) 29 | 30 | 完善产品信息,点击创建产品: 31 | 32 | ![creat_produce3](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce3.png) 33 | 34 | 根据自身需求选择相关功能,点击确认: 35 | 36 | ![creat_produce4](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce4.png) 37 | 38 | 选择设备面板后,进入硬件开发,选择 涂鸦标准模组 MCU SDK 开发方式,选择对应的模组: 39 | 40 | ![creat_produce6](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce6.png) 41 | 42 | 选择固件: 43 | 44 | ![creat_produce7](https://images.tuyacn.com/smart/shiliu_zone/Tuya_Arduino_library/creat_produce7.png) 45 | 46 | ### 2、重要函数说明 47 | 48 | 初始化串口,涂鸦WIFi模组的通用固件支持115200、9600波特率自适应,所以初始化串口时应将串口波特率初始化为115200或9600。在 `setup()` 中: 49 | 50 | ```c++ 51 | Serial.begin(9600); 52 | ``` 53 | 54 | mcu需要将创建的PID和mcu的软件版本号发送给涂鸦云模组。在 `setup()` 中: 55 | 56 | ```c++ 57 | //Enter the PID and MCU software version 58 | my_device.init("ma67l9sgmdyg3d2k", "1.0.0"); 59 | ``` 60 | 61 | 我们需要将创建产品时选择的所DP 的 ID 和类型传入MCU SDK内使用: 62 | 63 | ```c++ 64 | TuyaWifi my_device; 65 | 66 | #define DPID_SWITCH 20 //DP ID 67 | 68 | unsigned char dp_array[][2] = 69 | { 70 | //该产品创建时只选择了一个DP点,所以该数组只有一条信息 71 | {DPID_SWITCH, DP_TYPE_BOOL}, //前一个填入DP点ID,后一个为DP点的数据类型 72 | }; 73 | 74 | void setup() 75 | { 76 | ... 77 | my_device.set_dp_cmd_total(dp_array, 1); //dp_array:为存储DP点ID和数据类型的数组, 1:为数组内定义的DP个数 78 | ... 79 | } 80 | 81 | ``` 82 | 83 | 初始化时还需注册DP点下发处理函数和上传所有DP点函数: 84 | 85 | ```c++ 86 | unsigned char led_state = 0; 87 | 88 | void setup() 89 | { 90 | ... 91 | //register DP download processing callback function 92 | my_device.dp_process_func_register(led_dp_process); //注册DP下发处理函数 93 | //register upload all DP callback function 94 | my_device.dp_update_all_func_register(dp_update_all);//注册设备状态函数,上传所有DP点 95 | ... 96 | } 97 | 98 | void loop() 99 | { 100 | ... 101 | my_device.uart_service(); 102 | ... 103 | } 104 | 105 | /** 106 | * @description: DP download callback function. 107 | * @param {unsigned char} dpid 108 | * @param {const unsigned char} value 109 | * @param {unsigned short} length 110 | * @return {unsigned char} 111 | */ 112 | unsigned char led_dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 113 | { 114 | switch(dpid) { 115 | case DPID_SWITCH: 116 | led_state = my_device.mcu_get_dp_download_data(dpid, value, length);//得到下发数据帧中该DP的数据 117 | if (led_state) { 118 | digitalWrite(LED_BUILTIN, HIGH); 119 | } else { 120 | digitalWrite(LED_BUILTIN, LOW); 121 | } 122 | my_device.mcu_dp_update(dpid, value, length); 123 | break; 124 | 125 | default:break; 126 | } 127 | return 1; 128 | } 129 | 130 | /** 131 | * @description: Upload all DP status of the current device. 132 | * @param {*} 133 | * @return {*} 134 | */ 135 | void dp_update_all(void) 136 | { 137 | my_device.mcu_dp_update(DPID_SWITCH, &led_state, 1); 138 | } 139 | ``` 140 | 141 | 142 | 143 | ## 三、技术支持 144 | 145 | 您可以通过以下方法获得涂鸦的支持: 146 | 147 | - 开发者中心:https://developer.tuya.com 148 | - 帮助中心: https://support.tuya.com/help 149 | - 技术支持工单中心: https://service.console.tuya.com -------------------------------------------------------------------------------- /examples/start/start.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: start.ino 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-10 11:24:27 7 | * @LastEditTime: 2021-11-04 11:06:13 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: This demo is based on the Arduino UNO, and the LEDs on the UNO board are controlled by the Tuya Smart App. 11 | * Enter network connection mode when Pin7 to GND. 12 | * @Github:https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | TuyaWifi my_device; 20 | 21 | /* Current LED status */ 22 | unsigned char led_state = 0; 23 | /* Connect network button pin */ 24 | int key_pin = 7; 25 | 26 | /* Data point define */ 27 | #define DPID_SWITCH 20 28 | 29 | /* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type. 30 | * dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP 31 | */ 32 | unsigned char dp_array[][2] = 33 | { 34 | {DPID_SWITCH, DP_TYPE_BOOL}, 35 | }; 36 | 37 | unsigned char pid[] = {"ma67l9sgmdyg3d2k"}; 38 | unsigned char mcu_ver[] = {"1.0.0"}; 39 | 40 | /* last time */ 41 | unsigned long last_time = 0; 42 | 43 | void setup() 44 | { 45 | Serial.begin(9600); 46 | 47 | //Initialize led port, turn off led. 48 | pinMode(LED_BUILTIN, OUTPUT); 49 | digitalWrite(LED_BUILTIN, LOW); 50 | 51 | //Initialize networking keys. 52 | pinMode(key_pin, INPUT_PULLUP); 53 | 54 | //Enter the PID and MCU software version 55 | my_device.init(pid, mcu_ver); 56 | //incoming all DPs and their types array, DP numbers 57 | my_device.set_dp_cmd_total(dp_array, 1); 58 | //register DP download processing callback function 59 | my_device.dp_process_func_register(dp_process); 60 | //register upload all DP callback function 61 | my_device.dp_update_all_func_register(dp_update_all); 62 | 63 | last_time = millis(); 64 | } 65 | 66 | void loop() 67 | { 68 | my_device.uart_service(); 69 | 70 | //Enter the connection network mode when Pin7 is pressed. 71 | if (digitalRead(key_pin) == LOW) { 72 | delay(80); 73 | if (digitalRead(key_pin) == LOW) { 74 | my_device.mcu_set_wifi_mode(SMART_CONFIG); 75 | } 76 | } 77 | /* LED blinks when network is being connected */ 78 | if ((my_device.mcu_get_wifi_work_state() != WIFI_LOW_POWER) && (my_device.mcu_get_wifi_work_state() != WIFI_CONN_CLOUD) && (my_device.mcu_get_wifi_work_state() != WIFI_SATE_UNKNOW)) { 79 | if (millis()- last_time >= 500) { 80 | last_time = millis(); 81 | 82 | if (led_state == LOW) { 83 | led_state = HIGH; 84 | } else { 85 | led_state = LOW; 86 | } 87 | digitalWrite(LED_BUILTIN, led_state); 88 | } 89 | } 90 | 91 | delay(10); 92 | } 93 | 94 | /** 95 | * @description: DP download callback function. 96 | * @param {unsigned char} dpid 97 | * @param {const unsigned char} value 98 | * @param {unsigned short} length 99 | * @return {unsigned char} 100 | */ 101 | unsigned char dp_process(unsigned char dpid,const unsigned char value[], unsigned short length) 102 | { 103 | switch(dpid) { 104 | case DPID_SWITCH: 105 | led_state = my_device.mcu_get_dp_download_data(dpid, value, length); /* Get the value of the down DP command */ 106 | if (led_state) { 107 | //Turn on 108 | digitalWrite(LED_BUILTIN, HIGH); 109 | } else { 110 | //Turn off 111 | digitalWrite(LED_BUILTIN, LOW); 112 | } 113 | //Status changes should be reported. 114 | my_device.mcu_dp_update(dpid, value, length); 115 | break; 116 | 117 | default:break; 118 | } 119 | return TY_SUCCESS; 120 | } 121 | 122 | /** 123 | * @description: Upload all DP status of the current device. 124 | * @param {*} 125 | * @return {*} 126 | */ 127 | void dp_update_all(void) 128 | { 129 | my_device.mcu_dp_update(DPID_SWITCH, led_state, 1); 130 | } 131 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Data types (KEYWORD1) 3 | ####################################### 4 | 5 | TuyaWifi KEYWORD1 6 | TuyaUart KEYWORD1 7 | TuyaTools KEYWORD1 8 | TuyaDataPoint KEYWORD1 9 | 10 | ####################################### 11 | # Methods and Functions (KEYWORD2) 12 | ####################################### 13 | 14 | my_device KEYWORD2 15 | init KEYWORD2 16 | uart_service KEYWORD2 17 | dp_process_func_register KEYWORD2 18 | dp_update_all_func_register KEYWORD2 19 | data_point_handle KEYWORD2 20 | set_download_cmd_total KEYWORD2 21 | get_dowmload_dpid_index KEYWORD2 22 | mcu_get_dp_download_data KEYWORD2 23 | mcu_dp_update KEYWORD2 24 | mcu_set_wifi_mode KEYWORD2 25 | mcu_get_wifi_work_state KEYWORD2 26 | set_dp_cmd_total KEYWORD2 27 | 28 | ####################################### 29 | # Constants (LITERAL1) 30 | ####################################### 31 | 32 | SMART_CONFIG_STATE LITERAL1 33 | AP_STATE LITERAL1 34 | WIFI_NOT_CONNECTED LITERAL1 35 | WIFI_CONNECTED LITERAL1 36 | WIFI_CONN_CLOUD LITERAL1 37 | WIFI_LOW_POWER LITERAL1 38 | SMART_AND_AP_STATE LITERAL1 39 | WIFI_SATE_UNKNOW LITERAL1 40 | 41 | DP_TYPE_RAW LITERAL1 42 | DP_TYPE_BOOL LITERAL1 43 | DP_TYPE_VALUE LITERAL1 44 | DP_TYPE_STRING LITERAL1 45 | DP_TYPE_ENUM LITERAL1 46 | DP_TYPE_BITMAP LITERAL1 47 | 48 | SMART_CONFIG LITERAL1 49 | AP_CONFIG LITERAL1 50 | 51 | CONFIG_MODE_DEFAULT LITERAL1 52 | CONFIG_MODE_LOWPOWER LITERAL1 53 | CONFIG_MODE_SPECIAL LITERAL1 54 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Tuya_WiFi_MCU_SDK 2 | version=0.0.3 3 | author=Tuya 4 | maintainer=Tuya 5 | sentence=Communicate with Tuya modules that have flashed the Tuya common Wi-Fi firmware. 6 | paragraph= 7 | category=Communication 8 | url=https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library 9 | architectures=* 10 | includes=TuyaWifi.h 11 | -------------------------------------------------------------------------------- /src/TuyaDataPoint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaDataPoint.cpp 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-10 15:34:17 7 | * @LastEditTime: 2021-04-28 19:48:05 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: tuya mcu sdk Arduino library about data point process. 11 | */ 12 | #include "TuyaDataPoint.h" 13 | #include "TuyaDefs.h" 14 | #include "TuyaTools.h" 15 | #include "TuyaUart.h" 16 | #include 17 | 18 | extern TuyaTools tuya_tools; 19 | extern TuyaUart tuya_uart; 20 | 21 | unsigned char TuyaDataPoint::mcu_get_dp_download_bool(const unsigned char value[], unsigned short len) 22 | { 23 | return (value[0]); 24 | } 25 | 26 | unsigned char TuyaDataPoint::mcu_get_dp_download_enum(const unsigned char value[], unsigned short len) 27 | { 28 | return (value[0]); 29 | } 30 | 31 | unsigned long TuyaDataPoint::mcu_get_dp_download_value(const unsigned char value[], unsigned short len) 32 | { 33 | return (tuya_tools.byte_to_int(value)); 34 | } 35 | 36 | unsigned char TuyaDataPoint::mcu_dp_raw_update(unsigned char dpid, const unsigned char value[], unsigned short len) 37 | { 38 | unsigned short send_len = 0; 39 | 40 | if (stop_update_flag == TY_ENABLE) 41 | return TY_SUCCESS; 42 | // 43 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 44 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_RAW); 45 | // 46 | send_len = tuya_uart.set_wifi_uart_byte(send_len, len / 0x100); 47 | send_len = tuya_uart.set_wifi_uart_byte(send_len, len % 0x100); 48 | // 49 | send_len = tuya_uart.set_wifi_uart_buffer(send_len, (unsigned char *)value, len); 50 | 51 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 52 | 53 | return TY_SUCCESS; 54 | } 55 | 56 | unsigned char TuyaDataPoint::mcu_dp_bool_update(unsigned char dpid, unsigned char value) 57 | { 58 | unsigned short send_len = 0; 59 | 60 | if (stop_update_flag == TY_ENABLE) 61 | return TY_SUCCESS; 62 | 63 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 64 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_BOOL); 65 | // 66 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 0); 67 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 1); 68 | // 69 | if (value == TY_FALSE) 70 | { 71 | send_len = tuya_uart.set_wifi_uart_byte(send_len, TY_FALSE); 72 | } 73 | else 74 | { 75 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 1); 76 | } 77 | 78 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 79 | 80 | return TY_SUCCESS; 81 | } 82 | 83 | unsigned char TuyaDataPoint::mcu_dp_value_update(unsigned char dpid, unsigned long value) 84 | { 85 | unsigned short send_len = 0; 86 | 87 | if (stop_update_flag == TY_ENABLE) 88 | return TY_SUCCESS; 89 | 90 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 91 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_VALUE); 92 | // 93 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 0); 94 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 4); 95 | // 96 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 24); 97 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 16); 98 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 8); 99 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value & 0xff); 100 | 101 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 102 | 103 | return TY_SUCCESS; 104 | } 105 | 106 | unsigned char TuyaDataPoint::mcu_dp_string_update(unsigned char dpid, const unsigned char value[], unsigned short len) 107 | { 108 | unsigned short send_len = 0; 109 | 110 | if (stop_update_flag == TY_ENABLE) 111 | return TY_SUCCESS; 112 | // 113 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 114 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_STRING); 115 | // 116 | send_len = tuya_uart.set_wifi_uart_byte(send_len, len / 0x100); 117 | send_len = tuya_uart.set_wifi_uart_byte(send_len, len % 0x100); 118 | // 119 | send_len = tuya_uart.set_wifi_uart_buffer(send_len, (unsigned char *)value, len); 120 | 121 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 122 | 123 | return TY_SUCCESS; 124 | } 125 | 126 | unsigned char TuyaDataPoint::mcu_dp_enum_update(unsigned char dpid, unsigned char value) 127 | { 128 | unsigned short send_len = 0; 129 | 130 | if (stop_update_flag == TY_ENABLE) 131 | return TY_SUCCESS; 132 | 133 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 134 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_ENUM); 135 | // 136 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 0); 137 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 1); 138 | // 139 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value); 140 | 141 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 142 | 143 | return TY_SUCCESS; 144 | } 145 | 146 | unsigned char TuyaDataPoint::mcu_dp_fault_update(unsigned char dpid, unsigned long value) 147 | { 148 | unsigned short send_len = 0; 149 | 150 | if (stop_update_flag == TY_ENABLE) 151 | return TY_SUCCESS; 152 | 153 | send_len = tuya_uart.set_wifi_uart_byte(send_len, dpid); 154 | send_len = tuya_uart.set_wifi_uart_byte(send_len, DP_TYPE_BITMAP); 155 | // 156 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 0); 157 | 158 | if ((value | 0xff) == 0xff) 159 | { 160 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 1); 161 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value); 162 | } 163 | else if ((value | 0xffff) == 0xffff) 164 | { 165 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 2); 166 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 8); 167 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value & 0xff); 168 | } 169 | else 170 | { 171 | send_len = tuya_uart.set_wifi_uart_byte(send_len, 4); 172 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 24); 173 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 16); 174 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value >> 8); 175 | send_len = tuya_uart.set_wifi_uart_byte(send_len, value & 0xff); 176 | } 177 | 178 | tuya_uart.wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len); 179 | 180 | return TY_SUCCESS; 181 | } 182 | -------------------------------------------------------------------------------- /src/TuyaDataPoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaDataPoint.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-10 15:34:17 7 | * @LastEditTime: 2021-04-28 19:48:45 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #ifndef __TUYA_DATA_POINT_H__ 13 | #define __TUYA_DATA_POINT_H__ 14 | 15 | class TuyaDataPoint 16 | { 17 | public: 18 | // TuyaDataPoint(void); 19 | // ~TuyaDataPoint(void); 20 | 21 | unsigned char mcu_get_dp_download_bool(const unsigned char value[], unsigned short len); 22 | unsigned char mcu_get_dp_download_enum(const unsigned char value[], unsigned short len); 23 | unsigned long mcu_get_dp_download_value(const unsigned char value[], unsigned short len); 24 | 25 | unsigned char mcu_dp_raw_update(unsigned char dpid, const unsigned char value[], unsigned short len); 26 | unsigned char mcu_dp_bool_update(unsigned char dpid, unsigned char value); 27 | unsigned char mcu_dp_value_update(unsigned char dpid, unsigned long value); 28 | unsigned char mcu_dp_string_update(unsigned char dpid, const unsigned char value[], unsigned short len); 29 | unsigned char mcu_dp_enum_update(unsigned char dpid, unsigned char value); 30 | unsigned char mcu_dp_fault_update(unsigned char dpid, unsigned long value); 31 | 32 | private: 33 | }; 34 | 35 | #endif /* __TUYA_DATA_POINT_H__ */ 36 | -------------------------------------------------------------------------------- /src/TuyaDefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaDefs.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-10 11:28:40 7 | * @LastEditTime: 2021-04-28 19:48:57 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: Some necessary constant definitions. 11 | */ 12 | #ifndef __TUYA_DEFS_H__ 13 | #define __TUYA_DEFS_H__ 14 | 15 | /* Define constant */ 16 | #ifndef TY_TRUE 17 | #define TY_TRUE 1 18 | #endif 19 | 20 | #ifndef TY_FALSE 21 | #define TY_FALSE 0 22 | #endif 23 | 24 | #ifndef TY_NULL 25 | #ifdef __cplusplus 26 | #define TY_NULL 0 27 | #else 28 | #define TY_NULL ((void *)0) 29 | #endif 30 | #endif 31 | 32 | #ifndef TY_SUCCESS 33 | #define TY_SUCCESS 1 34 | #endif 35 | 36 | #ifndef TY_ERROR 37 | #define TY_ERROR 0 38 | #endif 39 | 40 | #ifndef TY_INVALID 41 | #define TY_INVALID 0xFF 42 | #endif 43 | 44 | #ifndef TY_ENABLE 45 | #define TY_ENABLE 1 46 | #endif 47 | 48 | #ifndef TY_DISABLE 49 | #define TY_DISABLE 0 50 | #endif 51 | 52 | #define MCU_RX_VER 0x00 //Module send frame protocol version number 53 | #define MCU_TX_VER 0x03 //MCU send frame protocol version number(default) 54 | #define PROTOCOL_HEAD 0x07 //Fixed protocol header length 55 | #define FRAME_FIRST 0x55 //Frame header first byte 56 | #define FRAME_SECOND 0xaa //Frame header second byte 57 | 58 | //============================================================================= 59 | //Byte order of the frame 60 | //============================================================================= 61 | #define HEAD_FIRST 0 62 | #define HEAD_SECOND 1 63 | #define PROTOCOL_VERSION 2 64 | #define FRAME_TYPE 3 65 | #define LENGTH_HIGH 4 66 | #define LENGTH_LOW 5 67 | #define DATA_START 6 68 | 69 | //============================================================================= 70 | //Data frame type 71 | //============================================================================= 72 | #define HEAT_BEAT_CMD 0 //Heartbeat package 73 | #define PRODUCT_INFO_CMD 1 //Product information 74 | #define WORK_MODE_CMD 2 //Query the module working mode set by the MCU 75 | #define WIFI_STATE_CMD 3 //Wifi working status 76 | #define WIFI_RESET_CMD 4 //Reset wifi 77 | #define WIFI_MODE_CMD 5 //Select smartconfig/AP mode 78 | #define DATA_QUERT_CMD 6 //Order send 79 | #define STATE_UPLOAD_CMD 7 //Status upload 80 | #define STATE_QUERY_CMD 8 //Status query 81 | #define UPDATE_START_CMD 0x0a //Upgrade start 82 | #define UPDATE_TRANS_CMD 0x0b //Upgrade transfer 83 | #define GET_ONLINE_TIME_CMD 0x0c //Get system time (Greenwich Mean Time) 84 | #define FACTORY_MODE_CMD 0x0d //Enter production test mode 85 | #define WIFI_TEST_CMD 0x0e //Wifi function test 86 | #define GET_LOCAL_TIME_CMD 0x1c //Get local time 87 | #define WEATHER_OPEN_CMD 0x20 //Turn on the weather 88 | #define WEATHER_DATA_CMD 0x21 //Weather data 89 | #define STATE_UPLOAD_SYN_CMD 0x22 //Status upload (synchronization) 90 | #define STATE_UPLOAD_SYN_RECV_CMD 0x23 //Status upload results(synchronization) 91 | #define HEAT_BEAT_STOP 0x25 //Turn off the WIFI module heartbeat 92 | #define STREAM_TRANS_CMD 0x28 //Stream data transmission 93 | #define GET_WIFI_STATUS_CMD 0x2b //Gets the wifi networking status 94 | #define WIFI_CONNECT_TEST_CMD 0x2c //Wifi function test(connection designated route) 95 | #define GET_MAC_CMD 0x2d //Get module mac 96 | #define GET_IR_STATUS_CMD 0x2e //IR status notification 97 | #define IR_TX_RX_TEST_CMD 0x2f //IR into send-receive test 98 | #define MAPS_STREAM_TRANS_CMD 0x30 //streams trans(Support for multiple maps) 99 | #define FILE_DOWNLOAD_START_CMD 0x31 //File download startup 100 | #define FILE_DOWNLOAD_TRANS_CMD 0x32 //File download data transfer 101 | #define MODULE_EXTEND_FUN_CMD 0x34 //Open the module time service notification 102 | #define BLE_TEST_CMD 0x35 //Bluetooth functional test(Scan designated bluetooth beacon) 103 | #define GET_VOICE_STATE_CMD 0x60 //Gets the voice status code 104 | #define MIC_SILENCE_CMD 0x61 //MIC mute Settings 105 | #define SET_SPEAKER_VOLUME_CMD 0x62 //speaker volume set 106 | #define VOICE_TEST_CMD 0x63 //Audio production test 107 | #define VOICE_AWAKEN_TEST_CMD 0x64 //Wake up production test 108 | #define VOICE_EXTEND_FUN_CMD 0x65 //Voice module extension function 109 | 110 | //============================================================================= 111 | //WIFI work status 112 | //============================================================================= 113 | #define SMART_CONFIG_STATE 0x00 114 | #define AP_STATE 0x01 115 | #define WIFI_NOT_CONNECTED 0x02 116 | #define WIFI_CONNECTED 0x03 117 | #define WIFI_CONN_CLOUD 0x04 118 | #define WIFI_LOW_POWER 0x05 119 | #define SMART_AND_AP_STATE 0x06 120 | #define WIFI_SATE_UNKNOW 0xff 121 | //============================================================================= 122 | //wifi reset status 123 | //============================================================================= 124 | #define RESET_WIFI_ERROR 0 125 | #define RESET_WIFI_SUCCESS 1 126 | 127 | //============================================================================= 128 | //wifi reset result 129 | //============================================================================= 130 | #define SET_WIFICONFIG_ERROR 0 131 | #define SET_WIFICONFIG_SUCCESS 1 132 | 133 | //============================================================================= 134 | //dp data point type 135 | //============================================================================= 136 | #define DP_TYPE_RAW 0x00 //RAW type 137 | #define DP_TYPE_BOOL 0x01 //bool type 138 | #define DP_TYPE_VALUE 0x02 //value type 139 | #define DP_TYPE_STRING 0x03 //string type 140 | #define DP_TYPE_ENUM 0x04 //enum type 141 | #define DP_TYPE_BITMAP 0x05 //fault type 142 | 143 | //============================================================================= 144 | //wifi distribution network 145 | //============================================================================= 146 | #define SMART_CONFIG 0x0 147 | #define AP_CONFIG 0x1 148 | 149 | //============================================================================= 150 | //Choose network access mode 151 | //============================================================================= 152 | #define CONFIG_MODE_DEFAULT "0" //Default mode 153 | #define CONFIG_MODE_LOWPOWER "1" //low power mode 154 | #define CONFIG_MODE_SPECIAL "2" //special mode 155 | 156 | #endif /* __TUYA_DEFS_H__ */ -------------------------------------------------------------------------------- /src/TuyaExtras.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaExtras.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-10-30 15:50:27 7 | * @LastEditTime: 2021-11-04 11:47:47 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #include "TuyaExtras.h" 13 | #include "TuyaDefs.h" 14 | #include "TuyaUart.h" 15 | 16 | extern TuyaUart tuya_uart; 17 | 18 | #if SUPPORT_GREEN_TIME 19 | void TuyaExtras::mcu_request_green_time(void) 20 | { 21 | tuya_uart.wifi_uart_write_frame(GET_ONLINE_TIME_CMD, MCU_TX_VER, 0); 22 | } 23 | 24 | void TuyaExtras::mcu_get_green_time(unsigned char time[], TUYA_WIFI_TIME *tuya_time) 25 | { 26 | if (time == TY_NULL || tuya_time == TY_NULL) { 27 | return; 28 | } 29 | 30 | if(time[0] == 1) { 31 | tuya_time->update_flag = 1; 32 | tuya_time->year = 2000+time[1]; 33 | tuya_time->month = time[2]; 34 | tuya_time->day = time[3]; 35 | tuya_time->hour = time[4]; 36 | tuya_time->minute = time[5]; 37 | tuya_time->second = time[6]; 38 | tuya_time->weekday = 0; 39 | }else { 40 | tuya_time->update_flag = -1; 41 | } 42 | } 43 | #endif /* SUPPORT_GREEN_TIME */ 44 | 45 | #if SUPPORT_RTC_TIME 46 | void TuyaExtras::mcu_request_rtc_time(void) 47 | { 48 | tuya_uart.wifi_uart_write_frame(GET_LOCAL_TIME_CMD, MCU_TX_VER, 0); 49 | } 50 | 51 | void TuyaExtras::mcu_get_rtc_time(unsigned char time[], TUYA_WIFI_TIME *tuya_time) 52 | { 53 | if (time == TY_NULL || tuya_time == TY_NULL) { 54 | return; 55 | } 56 | 57 | if(time[0] == 1) { 58 | tuya_time->update_flag = 1; 59 | tuya_time->year = time[1]; 60 | tuya_time->month = time[2]; 61 | tuya_time->day = time[3]; 62 | tuya_time->hour = time[4]; 63 | tuya_time->minute = time[5]; 64 | tuya_time->second = time[6]; 65 | tuya_time->weekday = time[7]; 66 | }else { 67 | tuya_time->update_flag = -1; 68 | } 69 | } 70 | #endif /* SUPPORT_RTC_TIME */ 71 | -------------------------------------------------------------------------------- /src/TuyaExtras.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaExtras.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-10-30 15:49:00 7 | * @LastEditTime: 2021-11-01 19:31:15 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #ifndef __TUYA_EXTRAS_H__ 13 | #define __TUYA_EXTRAS_H__ 14 | 15 | #include "../config.h" 16 | 17 | extern "C" 18 | { 19 | #if SUPPORT_GREEN_TIME 20 | typedef struct 21 | { 22 | unsigned short year; 23 | unsigned char month; 24 | unsigned char day; 25 | unsigned char hour; 26 | unsigned char minute; 27 | unsigned char second; 28 | unsigned char weekday; 29 | 30 | char update_flag; 31 | }TUYA_WIFI_TIME; 32 | #endif /* SUPPORT_GREEN_TIME */ 33 | } 34 | 35 | class TuyaExtras 36 | { 37 | public: 38 | #if SUPPORT_GREEN_TIME 39 | void mcu_request_green_time(void); 40 | void mcu_get_green_time(unsigned char time[], TUYA_WIFI_TIME *tuya_time); 41 | #endif /* SUPPORT_GREEN_TIME */ 42 | 43 | #if SUPPORT_RTC_TIME 44 | void mcu_request_rtc_time(void); 45 | void mcu_get_rtc_time(unsigned char time[], TUYA_WIFI_TIME *tuya_time); 46 | #endif /* SUPPORT_RTC_TIME */ 47 | 48 | private: 49 | }; 50 | 51 | #endif /* __TUYA_EXTRA_H__ */ 52 | -------------------------------------------------------------------------------- /src/TuyaTools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaTools.cpp 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-10 14:04:23 7 | * @LastEditTime: 2021-04-28 19:49:08 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: Some necessary tools. 11 | */ 12 | #include "TuyaTools.h" 13 | #include "TuyaDefs.h" 14 | 15 | TuyaTools::TuyaTools(void) 16 | { 17 | } 18 | 19 | TuyaTools::~TuyaTools(void) 20 | { 21 | } 22 | 23 | unsigned char TuyaTools::hex_to_bcd(unsigned char Value_H, unsigned char Value_L) 24 | { 25 | unsigned char bcd_value; 26 | 27 | if ((Value_H >= '0') && (Value_H <= '9')) 28 | Value_H -= '0'; 29 | else if ((Value_H >= 'A') && (Value_H <= 'F')) 30 | Value_H = Value_H - 'A' + 10; 31 | else if ((Value_H >= 'a') && (Value_H <= 'f')) 32 | Value_H = Value_H - 'a' + 10; 33 | 34 | bcd_value = Value_H & 0x0f; 35 | 36 | bcd_value <<= 4; 37 | if ((Value_L >= '0') && (Value_L <= '9')) 38 | Value_L -= '0'; 39 | else if ((Value_L >= 'A') && (Value_L <= 'F')) 40 | Value_L = Value_L - 'a' + 10; 41 | else if ((Value_L >= 'a') && (Value_L <= 'f')) 42 | Value_L = Value_L - 'a' + 10; 43 | 44 | bcd_value |= Value_L & 0x0f; 45 | 46 | return bcd_value; 47 | } 48 | 49 | unsigned long TuyaTools::my_strlen(unsigned char *str) 50 | { 51 | unsigned long len = 0; 52 | if (str == TY_NULL) 53 | { 54 | return 0; 55 | } 56 | 57 | for (len = 0; *str++ != '\0';) 58 | { 59 | len++; 60 | } 61 | 62 | return len; 63 | } 64 | 65 | void *TuyaTools::my_memset(void *src, unsigned char ch, unsigned short count) 66 | { 67 | unsigned char *tmp = (unsigned char *)src; 68 | 69 | if (src == TY_NULL) 70 | { 71 | return TY_NULL; 72 | } 73 | 74 | while (count--) 75 | { 76 | *tmp++ = ch; 77 | } 78 | 79 | return src; 80 | } 81 | 82 | void *TuyaTools::my_memcpy(void *dest, const void *src, unsigned short count) 83 | { 84 | unsigned char *pdest = (unsigned char *)dest; 85 | const unsigned char *psrc = (const unsigned char *)src; 86 | unsigned short i; 87 | 88 | if (dest == TY_NULL || src == TY_NULL) 89 | { 90 | return TY_NULL; 91 | } 92 | 93 | if ((pdest <= psrc) || (pdest > psrc + count)) 94 | { 95 | for (i = 0; i < count; i++) 96 | { 97 | pdest[i] = psrc[i]; 98 | } 99 | } 100 | else 101 | { 102 | for (i = count; i > 0; i--) 103 | { 104 | pdest[i - 1] = psrc[i - 1]; 105 | } 106 | } 107 | 108 | return dest; 109 | } 110 | 111 | char *TuyaTools::my_strcpy(char *dest, const char *src) 112 | { 113 | if ((TY_NULL == dest) || (TY_NULL == src)) 114 | { 115 | return TY_NULL; 116 | } 117 | 118 | char *p = dest; 119 | while (*src != '\0') 120 | { 121 | *dest++ = *src++; 122 | } 123 | *dest = '\0'; 124 | return p; 125 | } 126 | 127 | int TuyaTools::my_strcmp(char *s1, char *s2) 128 | { 129 | while (*s1 && *s2 && *s1 == *s2) 130 | { 131 | s1++; 132 | s2++; 133 | } 134 | return *s1 - *s2; 135 | } 136 | 137 | void TuyaTools::int_to_byte(unsigned long number, unsigned char value[4]) 138 | { 139 | value[0] = number >> 24; 140 | value[1] = number >> 16; 141 | value[2] = number >> 8; 142 | value[3] = number & 0xff; 143 | } 144 | 145 | unsigned long TuyaTools::byte_to_int(const unsigned char value[4]) 146 | { 147 | unsigned long nubmer = 0; 148 | 149 | nubmer = (unsigned long)value[0]; 150 | nubmer <<= 8; 151 | nubmer |= (unsigned long)value[1]; 152 | nubmer <<= 8; 153 | nubmer |= (unsigned long)value[2]; 154 | nubmer <<= 8; 155 | nubmer |= (unsigned long)value[3]; 156 | 157 | return nubmer; 158 | } 159 | 160 | unsigned char TuyaTools::get_check_sum(unsigned char *pack, unsigned short pack_len) 161 | { 162 | unsigned short i; 163 | unsigned char check_sum = 0; 164 | 165 | for (i = 0; i < pack_len; i++) 166 | { 167 | check_sum += *pack++; 168 | } 169 | 170 | return check_sum; 171 | } 172 | -------------------------------------------------------------------------------- /src/TuyaTools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaTools.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-25 17:44:25 7 | * @LastEditTime: 2021-04-28 19:49:36 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #ifndef __TUYA_TOOLS_H__ 13 | #define __TUYA_TOOLS_H__ 14 | 15 | class TuyaTools 16 | { 17 | public: 18 | TuyaTools(void); 19 | ~TuyaTools(void); 20 | 21 | unsigned char hex_to_bcd(unsigned char Value_H, unsigned char Value_L); 22 | unsigned long my_strlen(unsigned char *str); 23 | void *my_memset(void *src, unsigned char ch, unsigned short count); 24 | void *my_memcpy(void *dest, const void *src, unsigned short count); 25 | char *my_strcpy(char *dest, const char *src); 26 | int my_strcmp(char *s1, char *s2); 27 | void int_to_byte(unsigned long number, unsigned char value[4]); 28 | unsigned long byte_to_int(const unsigned char value[4]); 29 | unsigned char get_check_sum(unsigned char *pack, unsigned short pack_len); 30 | 31 | private: 32 | }; 33 | 34 | #endif /* __TUYA_TOOLS_H__ */ 35 | -------------------------------------------------------------------------------- /src/TuyaUart.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaUart.cpp 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-10 15:34:37 7 | * @LastEditTime: 2021-11-04 11:03:14 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: Tuya mcu sdk Arduino library about uart buffer, data receiving and sending. 11 | */ 12 | #include "TuyaWifi.h" 13 | #include "TuyaUart.h" 14 | #include "TuyaTools.h" 15 | 16 | extern TuyaTools tuya_tools; 17 | 18 | TuyaUart::TuyaUart(void) 19 | { 20 | wifi_protocol_init(); 21 | } 22 | 23 | TuyaUart::~TuyaUart(void) 24 | { 25 | } 26 | 27 | void TuyaUart::wifi_protocol_init(void) 28 | { 29 | rx_buf_in = (unsigned char *)wifi_uart_rx_buf; 30 | rx_buf_out = (unsigned char *)wifi_uart_rx_buf; 31 | 32 | stop_update_flag = TY_DISABLE; 33 | } 34 | 35 | void TuyaUart::uart_transmit_output(unsigned char value) 36 | { 37 | write(value); 38 | } 39 | 40 | unsigned char TuyaUart::uart_receive_input(unsigned char data) 41 | { 42 | if (1 == rx_buf_out - rx_buf_in) 43 | { 44 | //UART receive buffer is full 45 | return TY_ERROR; 46 | } 47 | else if ((rx_buf_in > rx_buf_out) && ((unsigned long)(rx_buf_in - rx_buf_out) >= sizeof(wifi_uart_rx_buf))) 48 | { 49 | //UART receive buffer is full 50 | return TY_ERROR; 51 | } 52 | else 53 | { 54 | //UART receive buffer is not full 55 | if (rx_buf_in >= (unsigned char *)(wifi_uart_rx_buf + sizeof(wifi_uart_rx_buf))) 56 | { 57 | rx_buf_in = (unsigned char *)(wifi_uart_rx_buf); 58 | } 59 | 60 | *rx_buf_in++ = data; 61 | } 62 | return TY_SUCCESS; 63 | } 64 | 65 | void TuyaUart::uart_receive_buff_input(unsigned char value[], unsigned short data_len) 66 | { 67 | unsigned short i = 0; 68 | for (i = 0; i < data_len; i++) 69 | { 70 | uart_receive_input(value[i]); 71 | } 72 | } 73 | 74 | unsigned char TuyaUart::take_byte_rxbuff(void) 75 | { 76 | unsigned char date = 0; 77 | 78 | if (rx_buf_out != rx_buf_in) 79 | { 80 | //With data 81 | if (rx_buf_out >= (unsigned char *)(wifi_uart_rx_buf + sizeof(wifi_uart_rx_buf))) 82 | { 83 | //The data has reached the end 84 | rx_buf_out = (unsigned char *)(wifi_uart_rx_buf); 85 | } 86 | 87 | date = *rx_buf_out++; 88 | } 89 | 90 | return date; 91 | } 92 | 93 | unsigned char TuyaUart::with_data_rxbuff(void) 94 | { 95 | if (rx_buf_in != rx_buf_out) 96 | return 1; 97 | else 98 | return 0; 99 | } 100 | 101 | void TuyaUart::wifi_uart_write_data(unsigned char *in, unsigned short len) 102 | { 103 | if ((TY_NULL == in) || (0 == len)) 104 | { 105 | return; 106 | } 107 | 108 | while (len--) 109 | { 110 | uart_transmit_output(*in); 111 | in++; 112 | } 113 | } 114 | 115 | void TuyaUart::wifi_uart_write_frame(unsigned char fr_type, unsigned char fr_ver, unsigned short len) 116 | { 117 | unsigned char check_sum = 0; 118 | 119 | wifi_uart_tx_buf[HEAD_FIRST] = 0x55; 120 | wifi_uart_tx_buf[HEAD_SECOND] = 0xaa; 121 | wifi_uart_tx_buf[PROTOCOL_VERSION] = fr_ver; 122 | wifi_uart_tx_buf[FRAME_TYPE] = fr_type; 123 | wifi_uart_tx_buf[LENGTH_HIGH] = len >> 8; 124 | wifi_uart_tx_buf[LENGTH_LOW] = len & 0xff; 125 | 126 | len += PROTOCOL_HEAD; 127 | check_sum = tuya_tools.get_check_sum((unsigned char *)wifi_uart_tx_buf, len - 1); 128 | wifi_uart_tx_buf[len - 1] = check_sum; 129 | 130 | wifi_uart_write_data((unsigned char *)wifi_uart_tx_buf, len); 131 | } 132 | 133 | unsigned short TuyaUart::set_wifi_uart_byte(unsigned short dest, unsigned char byte) 134 | { 135 | unsigned char *obj = (unsigned char *)wifi_uart_tx_buf + DATA_START + dest; 136 | 137 | *obj = byte; 138 | dest += 1; 139 | 140 | return dest; 141 | } 142 | 143 | unsigned short TuyaUart::set_wifi_uart_buffer(unsigned short dest, const unsigned char *src, unsigned short len) 144 | { 145 | unsigned char *obj = (unsigned char *)wifi_uart_tx_buf + DATA_START + dest; 146 | 147 | tuya_tools.my_memcpy(obj, src, len); 148 | 149 | dest += len; 150 | return dest; 151 | } 152 | 153 | void TuyaUart::set_serial(TY_UART *serial) 154 | { 155 | _serial_port = serial; 156 | } 157 | 158 | void TuyaUart::begin(unsigned long baud_rate) 159 | { 160 | _serial_port->begin(baud_rate); 161 | } 162 | 163 | int TuyaUart::read(void) 164 | { 165 | return _serial_port->read(); 166 | } 167 | 168 | size_t TuyaUart::write(uint8_t c) 169 | { 170 | return _serial_port->write(c); 171 | } 172 | 173 | int TuyaUart::available(void) 174 | { 175 | return _serial_port->available(); 176 | } 177 | -------------------------------------------------------------------------------- /src/TuyaUart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: TuyaUart.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: Tuya 6 | * @Date: 2021-04-15 17:56:56 7 | * @LastEditTime: 2021-04-28 19:50:07 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #ifndef __TUYA_UART_H__ 13 | #define __TUYA_UART_H__ 14 | 15 | #include 16 | 17 | #include "../config.h" 18 | #include "TuyaDefs.h" 19 | 20 | #include 21 | #undef TY_UART 22 | #define TY_UART HardwareSerial 23 | 24 | class TuyaUart 25 | { 26 | public: 27 | unsigned char wifi_uart_rx_buf[PROTOCOL_HEAD + WIFI_UART_RECV_BUF_LMT]; //Serial data processing buffer 28 | unsigned char wifi_uart_tx_buf[PROTOCOL_HEAD + WIFIR_UART_SEND_BUF_LMT]; //Serial receive buffer 29 | unsigned char wifi_data_process_buf[PROTOCOL_HEAD + WIFI_DATA_PROCESS_LMT]; //Serial port send buffer 30 | 31 | TuyaUart(void); 32 | ~TuyaUart(void); 33 | void wifi_protocol_init(void); 34 | 35 | unsigned char uart_receive_input(unsigned char data); 36 | void uart_receive_buff_input(unsigned char value[], unsigned short data_len); 37 | unsigned char take_byte_rxbuff(void); 38 | unsigned char with_data_rxbuff(void); 39 | 40 | void uart_transmit_output(unsigned char value); 41 | void wifi_uart_write_data(unsigned char *in, unsigned short len); 42 | void wifi_uart_write_frame(unsigned char fr_type, unsigned char fr_ver, unsigned short len); 43 | unsigned short set_wifi_uart_byte(unsigned short dest, unsigned char byte); 44 | unsigned short set_wifi_uart_buffer(unsigned short dest, const unsigned char *src, unsigned short len); 45 | 46 | void set_serial(TY_UART *serial); 47 | void begin(unsigned long baud_rate); 48 | int read(void); 49 | size_t write(uint8_t c); 50 | int available(void); 51 | 52 | private: 53 | volatile unsigned char *rx_buf_in; 54 | volatile unsigned char *rx_buf_out; 55 | TY_UART *_serial_port; 56 | }; 57 | 58 | #endif /* __TUYA_UART_H__ */ 59 | -------------------------------------------------------------------------------- /src/TuyaWifi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: Tuya.cpp 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-10 11:25:17 7 | * @LastEditTime: 2021-11-04 13:58:06 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: The functions that the user needs to actively call are in this file. 11 | */ 12 | 13 | #define TUYA_GLOBAL 14 | 15 | #include 16 | #include "TuyaTools.h" 17 | #include "TuyaDataPoint.h" 18 | 19 | TuyaTools tuya_tools; 20 | TuyaUart tuya_uart; 21 | TuyaDataPoint tuya_dp; 22 | TuyaExtras tuya_extras; 23 | 24 | /* Constants required to report product information */ 25 | /* Here "key" means key-value */ 26 | static unsigned char pid_key[] = {"{\"p\":\""}; 27 | static unsigned char mcu_ver_key[] = {"\",\"v\":\""}; 28 | static unsigned char mode_key[] = {"\",\"m\":"}; 29 | static unsigned char product_info_end[] = {"}"}; 30 | 31 | /* Protocol serial port initialization */ 32 | TuyaWifi::TuyaWifi(void) 33 | { 34 | tuya_uart.set_serial(&Serial); 35 | 36 | #if WIFI_CONTROL_SELF_MODE 37 | /* nothing to do here */ 38 | #else 39 | wifi_work_state = WIFI_SATE_UNKNOW; 40 | #endif 41 | } 42 | 43 | TuyaWifi::TuyaWifi(TY_UART *serial) 44 | { 45 | tuya_uart.set_serial(serial); 46 | } 47 | 48 | /** 49 | * @description: Initialize product information 50 | * @param {unsigned char} *pid : Product ID(Create products on the Tuya IoT platform to get) 51 | * @param {unsigned char} *mcu_ver : MCU Software Version Number 52 | * @return {*} 53 | */ 54 | unsigned char TuyaWifi::init(unsigned char *pid, unsigned char *mcu_ver) 55 | { 56 | if (pid == TY_NULL || mcu_ver == TY_NULL) 57 | { 58 | return TY_ERROR; 59 | } 60 | 61 | if (tuya_tools.my_strlen(pid) <= PID_LEN) 62 | { 63 | tuya_tools.my_memcpy(product_id, pid, tuya_tools.my_strlen(pid)); 64 | } 65 | else 66 | { 67 | tuya_tools.my_memcpy(product_id, pid, PID_LEN); 68 | return TY_ERROR; 69 | } 70 | 71 | if (tuya_tools.my_strlen(mcu_ver) <= VER_LEN) 72 | { 73 | tuya_tools.my_memcpy(mcu_ver_value, mcu_ver, tuya_tools.my_strlen(mcu_ver)); 74 | } 75 | else 76 | { 77 | tuya_tools.my_memcpy(mcu_ver_value, mcu_ver, VER_LEN); 78 | return TY_ERROR; 79 | } 80 | 81 | return TY_SUCCESS; 82 | } 83 | 84 | /** 85 | * @description: Wifi serial port processing service 86 | * @param {*} 87 | * @return {*} 88 | */ 89 | void TuyaWifi::uart_service(void) 90 | { 91 | unsigned char ret; 92 | static unsigned short rx_in = 0; 93 | unsigned short offset = 0; 94 | unsigned short rx_value_len = 0; 95 | 96 | /* extract serial data */ 97 | while(tuya_uart.available()) { 98 | ret = tuya_uart.uart_receive_input(tuya_uart.read()); 99 | if (ret != TY_SUCCESS) { 100 | break; 101 | } 102 | } 103 | 104 | while ((rx_in < sizeof(tuya_uart.wifi_data_process_buf)) && tuya_uart.with_data_rxbuff() > 0) 105 | { 106 | tuya_uart.wifi_data_process_buf[rx_in++] = tuya_uart.take_byte_rxbuff(); 107 | } 108 | 109 | if (rx_in < PROTOCOL_HEAD) 110 | return; 111 | 112 | while ((rx_in - offset) >= PROTOCOL_HEAD) 113 | { 114 | if (tuya_uart.wifi_data_process_buf[offset + HEAD_FIRST] != FRAME_FIRST) 115 | { 116 | offset++; 117 | continue; 118 | } 119 | 120 | if (tuya_uart.wifi_data_process_buf[offset + HEAD_SECOND] != FRAME_SECOND) 121 | { 122 | offset++; 123 | continue; 124 | } 125 | 126 | if (tuya_uart.wifi_data_process_buf[offset + PROTOCOL_VERSION] != MCU_RX_VER) 127 | { 128 | offset += 2; 129 | continue; 130 | } 131 | 132 | rx_value_len = tuya_uart.wifi_data_process_buf[offset + LENGTH_HIGH] * 0x100; 133 | rx_value_len += (tuya_uart.wifi_data_process_buf[offset + LENGTH_LOW] + PROTOCOL_HEAD); 134 | if (rx_value_len > sizeof(tuya_uart.wifi_data_process_buf) + PROTOCOL_HEAD) 135 | { 136 | offset += 3; 137 | continue; 138 | } 139 | 140 | if ((rx_in - offset) < rx_value_len) 141 | { 142 | break; 143 | } 144 | 145 | //data receive finish 146 | if (tuya_tools.get_check_sum((unsigned char *)tuya_uart.wifi_data_process_buf + offset, rx_value_len - 1) != tuya_uart.wifi_data_process_buf[offset + rx_value_len - 1]) 147 | { 148 | //check error 149 | offset += 3; 150 | continue; 151 | } 152 | 153 | data_handle(offset); 154 | offset += rx_value_len; 155 | } //end while 156 | 157 | rx_in -= offset; 158 | if (rx_in > 0) 159 | { 160 | tuya_tools.my_memcpy((char *)tuya_uart.wifi_data_process_buf, (const char *)tuya_uart.wifi_data_process_buf + offset, rx_in); 161 | } 162 | 163 | } 164 | 165 | /** 166 | * @description: Data frame processing 167 | * @param {unsigned short} offset : Data start position 168 | * @return {*} 169 | */ 170 | void TuyaWifi::data_handle(unsigned short offset) 171 | { 172 | #ifdef SUPPORT_MCU_FIRM_UPDATE 173 | unsigned char *firmware_addr = TY_NULL; 174 | static unsigned short firm_size; //Upgrade package size 175 | static unsigned long firm_length; //MCU upgrade file length 176 | static unsigned char firm_update_flag = 0; //MCU upgrade flag 177 | unsigned long dp_len; 178 | unsigned char firm_flag; //Upgrade package size flag 179 | #else 180 | unsigned short dp_len; 181 | #endif 182 | 183 | unsigned char ret; 184 | unsigned short i, total_len; 185 | unsigned char cmd_type = tuya_uart.wifi_data_process_buf[offset + FRAME_TYPE]; 186 | 187 | #if ((defined VOICE_MODULE_PROTOCOL_ENABLE) || (defined BLE_RELATED_FUNCTION_ENABLE) || (defined MODULE_EXPANDING_SERVICE_ENABLE) || \ 188 | (defined IR_TX_RX_TEST_ENABLE) || (defined GET_IR_STATUS_ENABLE) || (defined MCU_DP_UPLOAD_SYN) || (defined GET_WIFI_STATUS_ENABLE) || \ 189 | (defined WIFI_CONNECT_TEST_ENABLE) || (defined WIFI_STREAM_ENABLE) || (defined WIFI_TEST_ENABLE)) 190 | unsigned char result; 191 | #endif 192 | 193 | #ifdef WEATHER_ENABLE 194 | static unsigned char isWoSend = 0; //Whether the weather data has been opened, 0:no 1:yes 195 | #endif 196 | 197 | #ifdef WIFI_TEST_ENABLE 198 | unsigned char rssi; 199 | #endif 200 | 201 | #ifdef FILE_DOWNLOAD_ENABLE 202 | unsigned char *file_data_addr = TY_NULL; 203 | static unsigned short file_package_size = 0; //File packet size 204 | static unsigned char file_download_flag = 0; //File download flag 205 | unsigned int file_download_size = 0; 206 | #endif 207 | 208 | switch (cmd_type) 209 | { 210 | case HEAT_BEAT_CMD: //Heartbeat package 211 | heat_beat_check(); 212 | break; 213 | 214 | case PRODUCT_INFO_CMD: //Product information 215 | product_info_update(); 216 | break; 217 | 218 | case WORK_MODE_CMD: //Query the module working mode set by the MCU 219 | get_mcu_wifi_mode(); 220 | break; 221 | 222 | #if WIFI_CONTROL_SELF_MODE 223 | /* nothing to do here */ 224 | #else 225 | case WIFI_STATE_CMD: //Wifi working status 226 | wifi_work_state = tuya_uart.wifi_data_process_buf[offset + DATA_START]; 227 | tuya_uart.wifi_uart_write_frame(WIFI_STATE_CMD, MCU_TX_VER, 0); 228 | #ifdef WEATHER_ENABLE 229 | if (wifi_work_state == WIFI_CONNECTED && isWoSend == 0) //When the WIFI connection is successful, open the weather data only once 230 | { 231 | mcu_open_weather(); 232 | isWoSend = 1; 233 | } 234 | #endif 235 | break; 236 | 237 | case WIFI_RESET_CMD: //Reset wifi 238 | reset_wifi_flag = RESET_WIFI_SUCCESS; 239 | break; 240 | 241 | case WIFI_MODE_CMD: //Select smartconfig/AP mode 242 | set_wifimode_flag = SET_WIFICONFIG_SUCCESS; 243 | break; 244 | #endif 245 | 246 | case DATA_QUERT_CMD: //Order send 247 | total_len = (tuya_uart.wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | tuya_uart.wifi_data_process_buf[offset + LENGTH_LOW]; 248 | 249 | for (i = 0; i < total_len;) 250 | { 251 | dp_len = tuya_uart.wifi_data_process_buf[offset + DATA_START + i + 2] * 0x100; 252 | dp_len += tuya_uart.wifi_data_process_buf[offset + DATA_START + i + 3]; 253 | // 254 | ret = data_point_handle((unsigned char *)tuya_uart.wifi_data_process_buf + offset + DATA_START + i); 255 | 256 | if (TY_SUCCESS == ret) 257 | { 258 | //Send success 259 | } 260 | else 261 | { 262 | //Send fault 263 | } 264 | 265 | i += (dp_len + 4); 266 | } 267 | break; 268 | 269 | case STATE_QUERY_CMD: //Status query 270 | all_data_update(); 271 | break; 272 | 273 | #ifdef SUPPORT_MCU_FIRM_UPDATE 274 | case UPDATE_START_CMD: //Upgrade start 275 | //Get global variable of upgrade package size 276 | firm_flag = PACKAGE_SIZE; 277 | if (firm_flag == 0) 278 | { 279 | firm_size = 256; 280 | } 281 | else if (firm_flag == 1) 282 | { 283 | firm_size = 512; 284 | } 285 | else if (firm_flag == 2) 286 | { 287 | firm_size = 1024; 288 | } 289 | 290 | firm_length = wifi_data_process_buf[offset + DATA_START]; 291 | firm_length <<= 8; 292 | firm_length |= wifi_data_process_buf[offset + DATA_START + 1]; 293 | firm_length <<= 8; 294 | firm_length |= wifi_data_process_buf[offset + DATA_START + 2]; 295 | firm_length <<= 8; 296 | firm_length |= wifi_data_process_buf[offset + DATA_START + 3]; 297 | 298 | upgrade_package_choose(PACKAGE_SIZE); 299 | firm_update_flag = UPDATE_START_CMD; 300 | break; 301 | 302 | case UPDATE_TRANS_CMD: //Upgrade transfer 303 | if (firm_update_flag == UPDATE_START_CMD) 304 | { 305 | //Stop all data reporting 306 | stop_update_flag = TY_ENABLE; 307 | 308 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 309 | 310 | dp_len = wifi_data_process_buf[offset + DATA_START]; 311 | dp_len <<= 8; 312 | dp_len |= wifi_data_process_buf[offset + DATA_START + 1]; 313 | dp_len <<= 8; 314 | dp_len |= wifi_data_process_buf[offset + DATA_START + 2]; 315 | dp_len <<= 8; 316 | dp_len |= wifi_data_process_buf[offset + DATA_START + 3]; 317 | 318 | firmware_addr = (unsigned char *)wifi_data_process_buf; 319 | firmware_addr += (offset + DATA_START + 4); 320 | 321 | if ((total_len == 4) && (dp_len == firm_length)) 322 | { 323 | //Last pack 324 | ret = mcu_firm_update_handle(firmware_addr, dp_len, 0); 325 | firm_update_flag = 0; 326 | } 327 | else if ((total_len - 4) <= firm_size) 328 | { 329 | ret = mcu_firm_update_handle(firmware_addr, dp_len, total_len - 4); 330 | } 331 | else 332 | { 333 | firm_update_flag = 0; 334 | ret = TY_ERROR; 335 | } 336 | 337 | if (ret == TY_SUCCESS) 338 | { 339 | wifi_uart_write_frame(UPDATE_TRANS_CMD, MCU_TX_VER, 0); 340 | } 341 | //Restore all data reported 342 | stop_update_flag = TY_DISABLE; 343 | } 344 | break; 345 | #endif 346 | 347 | #if SUPPORT_GREEN_TIME 348 | case GET_ONLINE_TIME_CMD: //Get system time (Greenwich Mean Time) 349 | tuya_extras.mcu_get_green_time((unsigned char *)(tuya_uart.wifi_data_process_buf + offset + DATA_START), &_green_time); 350 | break; 351 | #endif 352 | 353 | #if SUPPORT_RTC_TIME 354 | case GET_LOCAL_TIME_CMD: //Get local time 355 | tuya_extras.mcu_get_rtc_time((unsigned char *)(tuya_uart.wifi_data_process_buf + offset + DATA_START), &_rtc_time); 356 | break; 357 | #endif 358 | 359 | #ifdef WIFI_TEST_ENABLE 360 | case WIFI_TEST_CMD: //Wifi function test 361 | result = wifi_data_process_buf[offset + DATA_START]; 362 | rssi = wifi_data_process_buf[offset + DATA_START + 1]; 363 | wifi_test_result(result, rssi); 364 | break; 365 | #endif 366 | 367 | #ifdef WEATHER_ENABLE 368 | case WEATHER_OPEN_CMD: //Turn on the weather 369 | weather_open_return_handle(wifi_data_process_buf[offset + DATA_START], wifi_data_process_buf[offset + DATA_START + 1]); 370 | break; 371 | 372 | case WEATHER_DATA_CMD: //Weather data 373 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 374 | weather_data_raw_handle((unsigned char *)wifi_data_process_buf + offset + DATA_START, total_len); 375 | break; 376 | #endif 377 | 378 | #ifdef WIFI_STREAM_ENABLE 379 | case STREAM_TRANS_CMD: //Stream data transmission 380 | stream_status = wifi_data_process_buf[offset + DATA_START]; //Service transmission back to reception 381 | stream_trans_send_result(stream_status); 382 | break; 383 | 384 | case MAPS_STREAM_TRANS_CMD: //streams trans(Support for multiple maps) 385 | maps_stream_status = wifi_data_process_buf[offset + DATA_START]; //Service transmission back to reception 386 | maps_stream_trans_send_result(maps_stream_status); 387 | break; 388 | #endif 389 | 390 | #ifdef WIFI_CONNECT_TEST_ENABLE 391 | case WIFI_CONNECT_TEST_CMD: //Wifi function test(connection designated route) 392 | result = wifi_data_process_buf[offset + DATA_START]; 393 | wifi_connect_test_result(result); 394 | break; 395 | #endif 396 | 397 | #ifdef GET_MODULE_MAC_ENABLE 398 | case GET_MAC_CMD: //Get module mac 399 | mcu_get_mac((unsigned char *)(wifi_data_process_buf + offset + DATA_START)); 400 | break; 401 | #endif 402 | 403 | #ifdef GET_WIFI_STATUS_ENABLE 404 | case GET_WIFI_STATUS_CMD: //Gets the wifi networking status 405 | result = wifi_data_process_buf[offset + DATA_START]; 406 | get_wifi_status(result); 407 | break; 408 | #endif 409 | 410 | #ifdef MCU_DP_UPLOAD_SYN 411 | case STATE_UPLOAD_SYN_RECV_CMD: //Status upload results(synchronization) 412 | result = wifi_data_process_buf[offset + DATA_START]; 413 | get_upload_syn_result(result); 414 | break; 415 | #endif 416 | 417 | #ifdef GET_IR_STATUS_ENABLE 418 | case GET_IR_STATUS_CMD: //IR status notification 419 | result = wifi_data_process_buf[offset + DATA_START]; 420 | get_ir_status(result); 421 | break; 422 | #endif 423 | 424 | #ifdef IR_TX_RX_TEST_ENABLE 425 | case IR_TX_RX_TEST_CMD: //IR into send-receive test 426 | result = wifi_data_process_buf[offset + DATA_START]; 427 | ir_tx_rx_test_result(result); 428 | break; 429 | #endif 430 | 431 | #ifdef FILE_DOWNLOAD_ENABLE 432 | case FILE_DOWNLOAD_START_CMD: //File download startup 433 | //Get file package size selection 434 | if (FILE_DOWNLOAD_PACKAGE_SIZE == 0) 435 | { 436 | file_package_size = 256; 437 | } 438 | else if (FILE_DOWNLOAD_PACKAGE_SIZE == 1) 439 | { 440 | file_package_size = 512; 441 | } 442 | else if (FILE_DOWNLOAD_PACKAGE_SIZE == 2) 443 | { 444 | file_package_size = 1024; 445 | } 446 | 447 | file_download_size = wifi_data_process_buf[offset + DATA_START]; 448 | file_download_size = (file_download_size << 8) | wifi_data_process_buf[offset + DATA_START + 1]; 449 | file_download_size = (file_download_size << 8) | wifi_data_process_buf[offset + DATA_START + 2]; 450 | file_download_size = (file_download_size << 8) | wifi_data_process_buf[offset + DATA_START + 3]; 451 | 452 | file_download_package_choose(FILE_DOWNLOAD_PACKAGE_SIZE); 453 | file_download_flag = FILE_DOWNLOAD_START_CMD; 454 | break; 455 | 456 | case FILE_DOWNLOAD_TRANS_CMD: //File download data transfer 457 | if (file_download_flag == FILE_DOWNLOAD_START_CMD) 458 | { 459 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 460 | 461 | dp_len = wifi_data_process_buf[offset + DATA_START]; 462 | dp_len <<= 8; 463 | dp_len |= wifi_data_process_buf[offset + DATA_START + 1]; 464 | dp_len <<= 8; 465 | dp_len |= wifi_data_process_buf[offset + DATA_START + 2]; 466 | dp_len <<= 8; 467 | dp_len |= wifi_data_process_buf[offset + DATA_START + 3]; 468 | 469 | file_data_addr = (unsigned char *)wifi_data_process_buf; 470 | file_data_addr += (offset + DATA_START + 4); 471 | 472 | if ((total_len == 4) && (dp_len == file_download_size)) 473 | { 474 | //Last pack 475 | ret = file_download_handle(file_data_addr, dp_len, 0); 476 | file_download_flag = 0; 477 | } 478 | else if ((total_len - 4) <= file_package_size) 479 | { 480 | ret = file_download_handle(file_data_addr, dp_len, total_len - 4); 481 | } 482 | else 483 | { 484 | file_download_flag = 0; 485 | ret = TY_ERROR; 486 | } 487 | 488 | if (ret == TY_SUCCESS) 489 | { 490 | wifi_uart_write_frame(FILE_DOWNLOAD_TRANS_CMD, MCU_TX_VER, 0); 491 | } 492 | } 493 | break; 494 | #endif 495 | 496 | #ifdef MODULE_EXPANDING_SERVICE_ENABLE 497 | case MODULE_EXTEND_FUN_CMD: //Module expansion service 498 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 499 | open_module_time_serve_result((unsigned char *)(wifi_data_process_buf + offset + DATA_START), total_len); 500 | break; 501 | #endif 502 | 503 | #ifdef BLE_RELATED_FUNCTION_ENABLE 504 | case BLE_TEST_CMD: //Bluetooth functional test(Scan designated bluetooth beacon) 505 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 506 | BLE_test_result((unsigned char *)(wifi_data_process_buf + offset + DATA_START), total_len); 507 | break; 508 | #endif 509 | 510 | #ifdef VOICE_MODULE_PROTOCOL_ENABLE 511 | case GET_VOICE_STATE_CMD: //Gets the voice status code 512 | result = wifi_data_process_buf[offset + DATA_START]; 513 | get_voice_state_result(result); 514 | break; 515 | case MIC_SILENCE_CMD: //MIC mute Settings 516 | result = wifi_data_process_buf[offset + DATA_START]; 517 | set_voice_MIC_silence_result(result); 518 | break; 519 | case SET_SPEAKER_VOLUME_CMD: //speaker volume set 520 | result = wifi_data_process_buf[offset + DATA_START]; 521 | set_speaker_voice_result(result); 522 | break; 523 | case VOICE_TEST_CMD: //Audio production test 524 | result = wifi_data_process_buf[offset + DATA_START]; 525 | voice_test_result(result); 526 | break; 527 | case VOICE_AWAKEN_TEST_CMD: //Wake up production test 528 | result = wifi_data_process_buf[offset + DATA_START]; 529 | voice_awaken_test_result(result); 530 | break; 531 | case VOICE_EXTEND_FUN_CMD: //Voice module extension function 532 | total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW]; 533 | voice_module_extend_fun((unsigned char *)(wifi_data_process_buf + offset + DATA_START), total_len); 534 | break; 535 | #endif 536 | 537 | default: 538 | break; 539 | } 540 | } 541 | 542 | 543 | /** 544 | * @description: Input product All DP ID, Type, total number of DPs 545 | * @param {unsigned char} dp_cmd_array : DP array. array[][0] : DP ID, 546 | * array[][1] : DP Type(DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP) 547 | * @param {unsigned char} dp_cmd_num : total number of DPs 548 | * @return {*} 549 | */ 550 | void TuyaWifi::set_dp_cmd_total(unsigned char dp_cmd_array[][2], unsigned char dp_cmd_num) 551 | { 552 | download_dp_number = dp_cmd_num; 553 | download_cmd = dp_cmd_array; 554 | } 555 | 556 | /** 557 | * @description: Get the serial number of the DPID in the array. 558 | * @param {unsigned char} dpid 559 | * @return {unsigned char} index : The index of the input dpid in the array 560 | */ 561 | unsigned char TuyaWifi::get_dowmload_dpid_index(unsigned char dpid) 562 | { 563 | unsigned char index; 564 | 565 | for (index = 0; index < download_dp_number; index++) 566 | { 567 | if (download_cmd[index][0] == dpid) 568 | { 569 | break; 570 | } 571 | } 572 | return index; 573 | } 574 | 575 | /** 576 | * @description: Delivery data processing 577 | * @param {const unsigned char} value : Send data source pointer 578 | * @return Return data processing result 579 | */ 580 | unsigned char TuyaWifi::data_point_handle(const unsigned char value[]) 581 | { 582 | unsigned char dp_id, index; 583 | unsigned char dp_type; 584 | unsigned char ret; 585 | unsigned short dp_len; 586 | 587 | dp_id = value[0]; 588 | dp_type = value[1]; 589 | dp_len = value[2] * 0x100; 590 | dp_len += value[3]; 591 | 592 | index = get_dowmload_dpid_index(dp_id); 593 | 594 | if (dp_type != download_cmd[index][1]) 595 | { 596 | //Error message 597 | return TY_FALSE; 598 | } 599 | else 600 | { 601 | ret = dp_download_handle(dp_id, value + 4, dp_len); 602 | } 603 | 604 | return ret; 605 | } 606 | 607 | /** 608 | * @description: DP command processing callback function 609 | * @param {tuya_callback_dp_download} _func 610 | * @return {*} 611 | */ 612 | void TuyaWifi::dp_process_func_register(tuya_callback_dp_download _func) 613 | { 614 | dp_download_handle = _func; 615 | } 616 | 617 | /** 618 | * @description: Reply to the current device status callback function 619 | * @param {tuya_callback_dp_update_all} _func 620 | * @return {*} 621 | */ 622 | void TuyaWifi::dp_update_all_func_register(tuya_callback_dp_update_all _func) 623 | { 624 | all_data_update = _func; 625 | } 626 | 627 | /** 628 | * @description: Heartbeat packet detection 629 | * @param {*} 630 | * @return {*} 631 | */ 632 | void TuyaWifi::heat_beat_check(void) 633 | { 634 | unsigned char length = 0; 635 | static unsigned char mcu_reset_state = TY_FALSE; 636 | 637 | if (TY_FALSE == mcu_reset_state) 638 | { 639 | length = tuya_uart.set_wifi_uart_byte(length, TY_FALSE); 640 | mcu_reset_state = TY_TRUE; 641 | } 642 | else 643 | { 644 | length = tuya_uart.set_wifi_uart_byte(length, TY_TRUE); 645 | } 646 | 647 | tuya_uart.wifi_uart_write_frame(HEAT_BEAT_CMD, MCU_TX_VER, length); 648 | } 649 | 650 | /** 651 | * @description: Product information upload 652 | * @param {*} 653 | * @return {*} 654 | */ 655 | void TuyaWifi::product_info_update(void) 656 | { 657 | unsigned char length = 0; 658 | 659 | #if ((defined CONFIG_MODE_DELAY_TIME) || (defined CONFIG_MODE_CHOOSE) || (defined ENABLE_MODULE_IR_FUN) || (defined LONG_CONN_LOWPOWER)) 660 | unsigned char str[10] = {0}; 661 | #endif 662 | 663 | length = tuya_uart.set_wifi_uart_buffer(length, pid_key, (unsigned short)(tuya_tools.my_strlen(pid_key))); 664 | length = tuya_uart.set_wifi_uart_buffer(length, product_id, PID_LEN); 665 | length = tuya_uart.set_wifi_uart_buffer(length, mcu_ver_key, (unsigned short)(tuya_tools.my_strlen(mcu_ver_key))); 666 | length = tuya_uart.set_wifi_uart_buffer(length, mcu_ver_value, VER_LEN); 667 | length = tuya_uart.set_wifi_uart_buffer(length, mode_key, (unsigned short)(tuya_tools.my_strlen(mode_key))); 668 | length = tuya_uart.set_wifi_uart_buffer(length, (const unsigned char *)CONFIG_MODE, (unsigned short)(tuya_tools.my_strlen((unsigned char *)CONFIG_MODE))); 669 | 670 | #ifdef CONFIG_MODE_DELAY_TIME 671 | sprintf((char *)str, ",\"mt\":%d", CONFIG_MODE_DELAY_TIME); 672 | length = tuya_uart.set_wifi_uart_buffer(length, str, tuya_tools.my_strlen(str)); 673 | #endif 674 | #ifdef CONFIG_MODE_CHOOSE 675 | sprintf((char *)str, ",\"n\":%d", CONFIG_MODE_CHOOSE); 676 | length = tuya_uart.set_wifi_uart_buffer(length, str, tuya_tools.my_strlen(str)); 677 | #endif 678 | #ifdef ENABLE_MODULE_IR_FUN 679 | sprintf((char *)str, ",\"ir\":\"%d.%d\"", MODULE_IR_PIN_TX, MODULE_IR_PIN_RX); 680 | length = tuya_uart.set_wifi_uart_buffer(length, str, tuya_tools.my_strlen(str)); 681 | #endif 682 | #ifdef LONG_CONN_LOWPOWER 683 | sprintf((char *)str, ",\"low\":%d", LONG_CONN_LOWPOWER); 684 | length = tuya_uart.set_wifi_uart_buffer(length, str, tuya_tools.my_strlen(str)); 685 | #endif 686 | 687 | length = tuya_uart.set_wifi_uart_buffer(length, product_info_end, tuya_tools.my_strlen(product_info_end)); 688 | 689 | tuya_uart.wifi_uart_write_frame(PRODUCT_INFO_CMD, MCU_TX_VER, length); 690 | } 691 | 692 | /** 693 | * @description: Query the working mode of mcu and wifi 694 | * @param {*} 695 | * @return {*} 696 | */ 697 | void TuyaWifi::get_mcu_wifi_mode(void) 698 | { 699 | unsigned char length = 0; 700 | 701 | #if WIFI_CONTROL_SELF_MODE //Module self-processing 702 | length = tuya_uart.set_wifi_uart_byte(length, wifi_state_led); 703 | length = tuya_uart.set_wifi_uart_byte(length, wifi_reset_key); 704 | #else 705 | //No need to process data 706 | #endif 707 | 708 | tuya_uart.wifi_uart_write_frame(WORK_MODE_CMD, MCU_TX_VER, length); 709 | } 710 | 711 | /** 712 | * @description: mcu gets bool,value,enum type to send dp value. (raw, string type needs to be handled at the user's discretion. fault only report) 713 | * @param {unsigned char} dpid : data point ID 714 | * @param {const unsigned char} value : dp data buffer address 715 | * @param {unsigned short} len : data length 716 | * @return {unsigned char} Parsed data 717 | */ 718 | unsigned long TuyaWifi::mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len) 719 | { 720 | unsigned long ret = 0; 721 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 722 | { 723 | case DP_TYPE_BOOL: 724 | ret = tuya_dp.mcu_get_dp_download_bool(value, len); 725 | break; 726 | 727 | case DP_TYPE_VALUE: 728 | ret = tuya_dp.mcu_get_dp_download_value(value, len); 729 | break; 730 | 731 | case DP_TYPE_ENUM: 732 | ret = tuya_dp.mcu_get_dp_download_enum(value, len); 733 | break; 734 | 735 | default: 736 | break; 737 | } 738 | return ret; 739 | } 740 | 741 | /** 742 | * @description: dp data upload 743 | * @param {unsigned char} dpid 744 | * @param {const unsigned char} value 745 | * @param {unsigned short} len 746 | * @return {*} 747 | */ 748 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, const unsigned char value[], unsigned short len) 749 | { 750 | unsigned char ret = 0; 751 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 752 | { 753 | case DP_TYPE_RAW: 754 | ret = tuya_dp.mcu_dp_raw_update(dpid, value, len); 755 | break; 756 | 757 | case DP_TYPE_BOOL: 758 | ret = tuya_dp.mcu_dp_bool_update(dpid, *value); 759 | break; 760 | 761 | case DP_TYPE_VALUE: 762 | ret = tuya_dp.mcu_dp_value_update(dpid, *value); 763 | break; 764 | 765 | case DP_TYPE_STRING: 766 | ret = tuya_dp.mcu_dp_string_update(dpid, value, len); 767 | break; 768 | 769 | case DP_TYPE_ENUM: 770 | ret = tuya_dp.mcu_dp_enum_update(dpid, *value); 771 | break; 772 | 773 | case DP_TYPE_BITMAP: 774 | ret = tuya_dp.mcu_dp_fault_update(dpid, *value); 775 | break; 776 | 777 | 778 | default: 779 | break; 780 | } 781 | return ret; 782 | } 783 | 784 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, unsigned char value, unsigned short len) 785 | { 786 | unsigned char ret = 0; 787 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 788 | { 789 | case DP_TYPE_BOOL: 790 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 791 | break; 792 | 793 | case DP_TYPE_ENUM: 794 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 795 | break; 796 | 797 | case DP_TYPE_VALUE: 798 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 799 | break; 800 | 801 | case DP_TYPE_BITMAP: 802 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 803 | break; 804 | 805 | default: 806 | break; 807 | } 808 | return ret; 809 | } 810 | 811 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, char value, unsigned short len) 812 | { 813 | unsigned char ret = 0; 814 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 815 | { 816 | case DP_TYPE_BOOL: 817 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 818 | break; 819 | 820 | case DP_TYPE_ENUM: 821 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 822 | break; 823 | 824 | case DP_TYPE_VALUE: 825 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 826 | break; 827 | 828 | case DP_TYPE_BITMAP: 829 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 830 | break; 831 | 832 | default: 833 | break; 834 | } 835 | return ret; 836 | } 837 | 838 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, unsigned long value, unsigned short len) 839 | { 840 | unsigned char ret = 0; 841 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 842 | { 843 | case DP_TYPE_BOOL: 844 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 845 | break; 846 | 847 | case DP_TYPE_ENUM: 848 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 849 | break; 850 | 851 | case DP_TYPE_VALUE: 852 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 853 | break; 854 | 855 | case DP_TYPE_BITMAP: 856 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 857 | break; 858 | 859 | default: 860 | break; 861 | } 862 | return ret; 863 | } 864 | 865 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, long value, unsigned short len) 866 | { 867 | unsigned char ret = 0; 868 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 869 | { 870 | case DP_TYPE_BOOL: 871 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 872 | break; 873 | 874 | case DP_TYPE_ENUM: 875 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 876 | break; 877 | 878 | case DP_TYPE_VALUE: 879 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 880 | break; 881 | 882 | case DP_TYPE_BITMAP: 883 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 884 | break; 885 | 886 | default: 887 | break; 888 | } 889 | return ret; 890 | } 891 | 892 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, unsigned int value, unsigned short len) 893 | { 894 | unsigned char ret = 0; 895 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 896 | { 897 | case DP_TYPE_BOOL: 898 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 899 | break; 900 | 901 | case DP_TYPE_ENUM: 902 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 903 | break; 904 | 905 | case DP_TYPE_VALUE: 906 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 907 | break; 908 | 909 | case DP_TYPE_BITMAP: 910 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 911 | break; 912 | 913 | default: 914 | break; 915 | } 916 | return ret; 917 | } 918 | 919 | unsigned char TuyaWifi::mcu_dp_update(unsigned char dpid, int value, unsigned short len) 920 | { 921 | unsigned char ret = 0; 922 | switch (download_cmd[get_dowmload_dpid_index(dpid)][1]) 923 | { 924 | case DP_TYPE_BOOL: 925 | ret = tuya_dp.mcu_dp_bool_update(dpid, value); 926 | break; 927 | 928 | case DP_TYPE_ENUM: 929 | ret = tuya_dp.mcu_dp_enum_update(dpid, value); 930 | break; 931 | 932 | case DP_TYPE_VALUE: 933 | ret = tuya_dp.mcu_dp_value_update(dpid, value); 934 | break; 935 | 936 | case DP_TYPE_BITMAP: 937 | ret = tuya_dp.mcu_dp_fault_update(dpid, value); 938 | break; 939 | 940 | default: 941 | break; 942 | } 943 | return ret; 944 | } 945 | 946 | #if WIFI_CONTROL_SELF_MODE 947 | 948 | void TuyaWifi::set_state_pin(unsigned char led_pin, unsigned char key_pin) 949 | { 950 | wifi_state_led = led_pin; 951 | wifi_reset_key = key_pin; 952 | } 953 | #else 954 | /** 955 | * @brief Get set wifi status success flag 956 | * @param Null 957 | * @return wifimode flag 958 | * - 0(SET_WIFICONFIG_ERROR):failure 959 | * - 1(SET_WIFICONFIG_SUCCESS):success 960 | * @note 1:The MCU actively calls to obtain whether the reset wifi is successful through the mcu_get_reset_wifi_flag() function. 961 | * 2:If the module is in self-processing mode, the MCU does not need to call this function. 962 | */ 963 | unsigned char TuyaWifi::mcu_get_wifimode_flag(void) 964 | { 965 | return set_wifimode_flag; 966 | } 967 | 968 | /** 969 | * @description: MCU set wifi working mode 970 | * @param {unsigned char} mode : enter mode 971 | * 0(SMART_CONFIG):enter smartconfig mode 972 | * 1(AP_CONFIG):enter AP mode 973 | * @return {*} 974 | */ 975 | void TuyaWifi::mcu_set_wifi_mode(unsigned char mode) 976 | { 977 | unsigned char length = 0; 978 | 979 | set_wifimode_flag = SET_WIFICONFIG_ERROR; 980 | 981 | length = tuya_uart.set_wifi_uart_byte(length, mode); 982 | 983 | tuya_uart.wifi_uart_write_frame(WIFI_MODE_CMD, MCU_TX_VER, length); 984 | } 985 | 986 | /** 987 | * @brief MCU gets reset wifi success flag 988 | * @param Null 989 | * @return Reset flag 990 | * - 0(RESET_WIFI_ERROR):failure 991 | * - 1(RESET_WIFI_SUCCESS):success 992 | * @note 1:The MCU actively calls mcu_reset_wifi() and calls this function to get the reset state. 993 | * 2:If the module is in self-processing mode, the MCU does not need to call this function. 994 | */ 995 | unsigned char TuyaWifi::mcu_get_reset_wifi_flag(void) 996 | { 997 | return reset_wifi_flag; 998 | } 999 | 1000 | /** 1001 | * @description: MCU actively resets wifi working mode 1002 | * @param {*} 1003 | * @return {*} 1004 | * @note 1:The MCU actively calls to obtain whether the reset wifi is successful through the mcu_get_reset_wifi_flag() function. 1005 | * 2:If the module is in self-processing mode, the MCU does not need to call this function. 1006 | */ 1007 | void TuyaWifi::mcu_reset_wifi(void) 1008 | { 1009 | reset_wifi_flag = RESET_WIFI_ERROR; 1010 | 1011 | tuya_uart.wifi_uart_write_frame(WIFI_RESET_CMD, MCU_TX_VER, 0); 1012 | } 1013 | 1014 | /** 1015 | * @description: The MCU actively obtains the current wifi working status. 1016 | * @param {*} 1017 | * @return {unsigned char} wifi work state 1018 | * SMART_CONFIG_STATE:smartconfig config status 1019 | * AP_STATE:AP config status 1020 | * WIFI_NOT_CONNECTED:WIFI configuration succeeded but not connected to the router 1021 | * WIFI_CONNECTED:WIFI configuration is successful and connected to the router 1022 | * WIFI_CONN_CLOUD:WIFI is connected to the cloud server 1023 | * WIFI_LOW_POWER:WIFI is in low power mode 1024 | * SMART_AND_AP_STATE: WIFI smartconfig&AP mode 1025 | * @note 1:If the module is in self-processing mode, the MCU does not need to call this function. 1026 | */ 1027 | unsigned char TuyaWifi::mcu_get_wifi_work_state(void) 1028 | { 1029 | return wifi_work_state; 1030 | } 1031 | #endif /* WIFI_CONTROL_SELF_MODE */ 1032 | 1033 | #if SUPPORT_GREEN_TIME 1034 | char TuyaWifi::get_green_time(TUYA_WIFI_TIME *time, const unsigned int timeout) 1035 | { 1036 | if (TY_NULL == time) { 1037 | return -1; 1038 | } 1039 | 1040 | #if WIFI_CONTROL_SELF_MODE 1041 | /* nothing to do here*/ 1042 | #else 1043 | if (WIFI_CONN_CLOUD != mcu_get_wifi_work_state()) { 1044 | return -1; 1045 | } 1046 | #endif 1047 | 1048 | unsigned long get_green_time_begin = 0; 1049 | unsigned int delay_time = 100; 1050 | 1051 | if (timeout > 10) { 1052 | delay_time = timeout; 1053 | } 1054 | 1055 | /* 1.request green time */ 1056 | tuya_extras.mcu_request_green_time(); 1057 | /* 2.wait for green time */ 1058 | get_green_time_begin = millis(); 1059 | while (millis()<(get_green_time_begin + timeout)) { 1060 | uart_service(); 1061 | if (1 == _green_time.update_flag) { /* request green time success */ 1062 | tuya_tools.my_memcpy(time, &_green_time, sizeof(_green_time)); 1063 | _green_time.update_flag = 0; 1064 | return TY_SUCCESS; 1065 | } 1066 | } 1067 | _green_time.update_flag = 0; 1068 | return -2; /* request green time timeout */ 1069 | } 1070 | #endif /* SUPPORT_GREEN_TIME */ 1071 | 1072 | #if SUPPORT_RTC_TIME 1073 | char TuyaWifi::get_rtc_time(TUYA_WIFI_TIME *time, const unsigned int timeout) 1074 | { 1075 | unsigned long get_rtc_time_begin = 0; 1076 | unsigned int delay_time = 100; 1077 | 1078 | if (TY_NULL == time) { 1079 | return -1; 1080 | } 1081 | 1082 | if (timeout > 10) { 1083 | delay_time = timeout; 1084 | } 1085 | 1086 | /* 1.request rtc time */ 1087 | tuya_extras.mcu_request_rtc_time(); 1088 | /* 2.wait for rtc time */ 1089 | get_rtc_time_begin = millis(); 1090 | while (millis()<(get_rtc_time_begin + delay_time)) { 1091 | uart_service(); 1092 | if (1 == _rtc_time.update_flag) { /* request rtc time success */ 1093 | tuya_tools.my_memcpy(time, &_rtc_time, sizeof(_rtc_time)); 1094 | _rtc_time.update_flag = 0; 1095 | return TY_SUCCESS; 1096 | } 1097 | } 1098 | _rtc_time.update_flag = 0; 1099 | return -2; /* request rtc time timeout */ 1100 | } 1101 | #endif /* SUPPORT_RTC_TIME */ 1102 | -------------------------------------------------------------------------------- /src/TuyaWifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @FileName: Tuya.h 3 | * @Author: Tuya 4 | * @Email: 5 | * @LastEditors: shiliu 6 | * @Date: 2021-04-10 11:25:26 7 | * @LastEditTime: 2021-11-04 12:01:38 8 | * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD 9 | * @Company: http://www.tuya.com 10 | * @Description: 11 | */ 12 | #ifndef __TUYA_WIFI_H__ 13 | #define __TUYA_WIFI_H__ 14 | 15 | #include 16 | 17 | #include "../config.h" 18 | #include "TuyaDefs.h" 19 | #include "TuyaUart.h" 20 | #include "TuyaExtras.h" 21 | 22 | #ifdef TUYA_GLOBAL 23 | #define TUYA_GLOBAL_EXTERN 24 | #else 25 | #define TUYA_GLOBAL_EXTERN extern 26 | #endif 27 | 28 | #ifndef TUYA_GLOBAL 29 | extern TuyaUart tuya_uart; 30 | #endif 31 | 32 | #define PID_LEN 16 33 | #define VER_LEN 5 34 | 35 | TUYA_GLOBAL_EXTERN volatile unsigned char stop_update_flag; //ENABLE:Stop all data uploads DISABLE:Restore all data uploads 36 | 37 | extern "C" 38 | { 39 | typedef void (*tuya_callback_dp_update_all)(void); 40 | typedef unsigned char (*tuya_callback_dp_download)(unsigned char dpid, const unsigned char value[], unsigned short length); 41 | } 42 | 43 | class TuyaWifi 44 | { 45 | public: 46 | TuyaWifi(void); 47 | TuyaWifi(TY_UART *serial); 48 | 49 | unsigned char init(unsigned char *pid, unsigned char *mcu_ver); 50 | void uart_service(void); 51 | 52 | void dp_process_func_register(tuya_callback_dp_download _func); 53 | void dp_update_all_func_register(tuya_callback_dp_update_all _func); 54 | 55 | void set_dp_cmd_total(unsigned char download_cmd_array[][2], unsigned char download_cmd_num); 56 | 57 | unsigned long mcu_get_dp_download_data(unsigned char dpid, const unsigned char value[], unsigned short len); 58 | 59 | /* char * */ 60 | unsigned char mcu_dp_update(unsigned char dpid, const unsigned char value[], unsigned short len); /* char raw */ 61 | /* unsigned long / long */ 62 | unsigned char mcu_dp_update(unsigned char dpid, unsigned long value, unsigned short len); 63 | unsigned char mcu_dp_update(unsigned char dpid, long value, unsigned short len); 64 | /* unsigned char / char */ 65 | unsigned char mcu_dp_update(unsigned char dpid, unsigned char value, unsigned short len); 66 | unsigned char mcu_dp_update(unsigned char dpid, char value, unsigned short len); 67 | /* unsigned int / int */ 68 | unsigned char mcu_dp_update(unsigned char dpid, unsigned int value, unsigned short len); 69 | unsigned char mcu_dp_update(unsigned char dpid, int value, unsigned short len); 70 | 71 | #if WIFI_CONTROL_SELF_MODE 72 | void set_state_pin(unsigned char led_pin, unsigned char key_pin); 73 | #else 74 | unsigned char mcu_get_wifimode_flag(void); 75 | void mcu_set_wifi_mode(unsigned char mode); 76 | unsigned char mcu_get_reset_wifi_flag(void); 77 | void mcu_reset_wifi(void); 78 | unsigned char mcu_get_wifi_work_state(void); 79 | #endif /* WIFI_CONTROL_SELF_MODE */ 80 | 81 | #if SUPPORT_GREEN_TIME 82 | char get_green_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 83 | #endif /* SUPPORT_GREEN_TIME */ 84 | 85 | #if SUPPORT_RTC_TIME 86 | char get_rtc_time(TUYA_WIFI_TIME *time, const unsigned int timeout); 87 | #endif /* SUPPORT_GREEN_TIME */ 88 | 89 | 90 | private: 91 | 92 | #if WIFI_CONTROL_SELF_MODE 93 | unsigned char wifi_state_led = 16; 94 | unsigned char wifi_reset_key = 28; 95 | #else 96 | unsigned char reset_wifi_flag; //Reset wifi flag (TRUE: successful / FALSE: failed) 97 | unsigned char set_wifimode_flag; //Set the WIFI working mode flag (TRUE: Success / FALSE: Failed) 98 | unsigned char wifi_work_state; //Wifi module current working status 99 | #endif /* WIFI_CONTROL_SELF_MODE */ 100 | 101 | #if SUPPORT_GREEN_TIME 102 | TUYA_WIFI_TIME _green_time; 103 | #endif /* SUPPORT_GREEN_TIME */ 104 | 105 | #if SUPPORT_RTC_TIME 106 | TUYA_WIFI_TIME _rtc_time; 107 | #endif /* SUPPORT_RTC_TIME */ 108 | 109 | unsigned char product_id[PID_LEN]; 110 | unsigned char mcu_ver_value[VER_LEN]; 111 | 112 | unsigned char download_dp_number; 113 | unsigned char (*download_cmd)[2]; 114 | 115 | tuya_callback_dp_download dp_download_handle; 116 | tuya_callback_dp_update_all all_data_update; 117 | void data_handle(unsigned short offset); 118 | void heat_beat_check(void); 119 | void product_info_update(void); 120 | void get_mcu_wifi_mode(void); 121 | unsigned char data_point_handle(const unsigned char value[]); 122 | unsigned char get_dowmload_dpid_index(unsigned char dpid); 123 | }; 124 | 125 | #endif /* __TUYA_WIFI_H__ */ 126 | --------------------------------------------------------------------------------