资讯专栏INFORMATION COLUMN

涂鸦智能 ① tuya-wifi-mcu-sdk-arduino-library 简单剖析

EdwardUp / 2327人阅读

摘要:涂鸦模组中的固件应为通用固件,通用固件支持,两种波特率自适应。涂鸦智能将每个功能点抽象成数据点,数据点定义成不同的类型,例如布尔枚举数值等。指定通信协议下事件的。上报设备状态函数注册获取连接状态轮询串口数据在中调用。

1、简介

Tuya MCU SDK Arduino Library 基于涂鸦Wi-Fi 通用对接方案进行开发的,设备 MCU 通过串口与 Wi-Fi 模组连接实现设备联网。涂鸦模组中的固件应为通用固件,通用固件支持9600,115200两种波特率自适应。

注意点:

  • Arduino板子 + 涂鸦模块的开发方式,据说后期可以多带带模块开发。
  • 串口通信

2、配置Arduino环境

2.1 下载Arduino sdk

  • 方式一:

https://gitee.com/ant_onio/tuya-wifi-mcu-sdk-arduino-library 点击下载

解压到自己的电脑路径(此电脑->文档->Arduino->libraries)

  • 方式二(推荐):

Arduino IDE -> 工具 -> 管理库 -> 搜索 tuya-> 安装最新版本

3、剖析SDK

记住一点,这种方式是mcu + module 串口通信开发方式

简单来说,肯定数据是不断处理串口通信,那么从另外一个点来说就是模组已经内置了串口协议数据处理逻辑。

博哥大概代码看了一下:

3.1 TuyaUart —— 处理和模组进行串口通信(了解即可)

class TuyaUart{public:    // 主要是定义串口通信buffer缓存大小    volatile unsigned char wifi_uart_rx_buf[PROTOCOL_HEAD + WIFI_UART_RECV_BUF_LMT];     //Serial data processing buffer    volatile unsigned char wifi_uart_tx_buf[PROTOCOL_HEAD + WIFIR_UART_SEND_BUF_LMT];    //Serial receive buffer    volatile unsigned char wifi_data_process_buf[PROTOCOL_HEAD + WIFI_DATA_PROCESS_LMT]; //Serial port send buffer    TuyaUart(void);    ~TuyaUart(void);    void wifi_protocol_init(void);    //  接收数据    unsigned char uart_receive_input(unsigned char data);    void uart_receive_buff_input(unsigned char value[], unsigned short data_len);    unsigned char take_byte_rxbuff(void);    unsigned char with_data_rxbuff(void);    // 传输发送数据    void uart_transmit_output(unsigned char value);    void wifi_uart_write_data(unsigned char *in, unsigned short len);    void wifi_uart_write_frame(unsigned char fr_type, unsigned char fr_ver, unsigned short len);    unsigned short set_wifi_uart_byte(unsigned short dest, unsigned char byte);    unsigned short set_wifi_uart_buffer(unsigned short dest, const unsigned char *src, unsigned short len);    /* serial set */    bool _isHWSerial;    //  串口设置    void set_serial(HardwareSerial *serial);    void set_serial(SoftwareSerial *serial);    void begin(long baud_rate);    char read(void);    size_t write(char value);    int available(void);private:    volatile unsigned char *rx_buf_in;    volatile unsigned char *rx_buf_out;    Stream *_port;};

3.2 TuyaTools —— 工具类方法(了解即可)

class TuyaTools{public:    TuyaTools(void);    ~TuyaTools(void);    unsigned char hex_to_bcd(unsigned char Value_H, unsigned char Value_L);    // 计算字符串长度    unsigned long my_strlen(unsigned char *str);    // 设置字符串    void *my_memset(void *src, unsigned char ch, unsigned short count);    // 内存拷贝    void *my_memcpy(void *dest, const void *src, unsigned short count);    // 字符串拷贝    char *my_strcpy(char *dest, const char *src);    // 字符串对比    int my_strcmp(char *s1, char *s2);    // int 转字节数组    void int_to_byte(unsigned long number, unsigned char value[4]);    // 字节数组 转int    unsigned long byte_to_int(const unsigned char value[4]);    unsigned char get_check_sum(unsigned char *pack, unsigned short pack_len);private:};

3.3 TuyaDataPoint —— 处理数据节点(上传、下发)

class TuyaDataPoint{public:    // TuyaDataPoint(void);    // ~TuyaDataPoint(void);    // 下发节点数据    unsigned char mcu_get_dp_download_bool(const unsigned char value[], unsigned short len);    unsigned char mcu_get_dp_download_enum(const unsigned char value[], unsigned short len);    unsigned long mcu_get_dp_download_value(const unsigned char value[], unsigned short len);    // 上报节点数据    unsigned char mcu_dp_raw_update(unsigned char dpid, const unsigned char value[], unsigned short len);    unsigned char mcu_dp_bool_update(unsigned char dpid, unsigned char value);    unsigned char mcu_dp_value_update(unsigned char dpid, unsigned long value);    unsigned char mcu_dp_string_update(unsigned char dpid, const unsigned char value[], unsigned short len);    unsigned char mcu_dp_enum_update(unsigned char dpid, unsigned char value);    unsigned char mcu_dp_fault_update(unsigned char dpid, unsigned long value);private:};

注意区分一下数据类型。
DP为 Data Point 的缩写,即数据点,偶尔被称为 DP 点,表示智能设备所具备的功能点。

  • 涂鸦智能将每个功能点抽象成数据点,数据点定义成不同的类型,例如布尔、枚举、数值等。
  • 数据点具备读写属性。例如,一个两路的开关,可以抽象成两个数据点,每个数据点类型为布尔型,可取值为 TrueFalse
  • 数据点可读写,读表示获取开关目前的值,写表示改变开关目前的值。

DPID:指定通信协议下 DP 事件的 ID。

节点类型:

#define DP_TYPE_RAW     0x00    //RAW type#define DP_TYPE_BOOL    0x01    //bool type#define DP_TYPE_VALUE   0x02    //value type#define DP_TYPE_STRING  0x03    //string type#define DP_TYPE_ENUM    0x04    //enum type#define DP_TYPE_BITMAP  0x05    //fault type

3.4 TuyaWifi —— 处理wifi网络相关操作,重点内容

在Arduino中使用该库进行编程开发时,必须在你的Arduino工程文件中包含 TuyaWifi.h 头文件。

一般很多sdk的开发方式都是:

  • 1、创建对象 构造方法
  • 2、初始化 init
  • 3、回调配置、信息注册 register、callbackHandler
  • 4、不断轮询处理响应

3.4.1 unsigned char TuyaWifi::init(unsigned char *pid, unsigned char *mcu_ver) —— 初始化

PID通过在 Tuya IoT平台 上创建产品获取,wifi类的长度一般为16,mcu_ver 这个参数是软件的版本号。

3.4.2 void set_dp_cmd_total(unsigned char download_cmd_array[][2], unsigned char download_cmd_num) —— 配置节点

Tuya IoT平台创建产品,获取产品DP点信息。

DP为 Data Point 的缩写,即数据点,偶尔被称为 DP 点,表示智能设备所具备的功能点。

  • 涂鸦智能将每个功能点抽象成数据点,数据点定义成不同的类型,例如布尔、枚举、数值等。
  • 数据点具备读写属性。例如,一个两路的开关,可以抽象成两个数据点,每个数据点类型为布尔型,可取值为 TrueFalse
  • 数据点可读写,读表示获取开关目前的值,写表示改变开关目前的值。

DPID:指定通信协议下 DP 事件的 ID。

MCU SDK需要知道你创建了哪些DP点,他们是什么类型的。

3.4.3 void mcu_set_wifi_mode(unsigned char mode) —— 配网模式

/** * @description: MCU set wifi working mode * @param {unsigned char} mode : enter mode  *                               0(SMART_CONFIG):enter smartconfig mode *                               1(AP_CONFIG):enter AP mode * @return {*} */void TuyaWifi::mcu_set_wifi_mode(unsigned char mode);

3.4.4 void dp_process_func_register(tuya_callback_dp_download _func) —— 下发回调注册

当APP控制设备的时候,会从云端下发对应的DP命令到设备,设备对数据进行解析后,对下发的命令执行相对于的动作。

对下发命令的处理,通过回调函数来调用,所以我们需要把你的处理函数注册一下。

伪代码:

//register DP download processing callback function  my_device.dp_process_func_register(dp_process);/** * @description: DP download callback function. * @param {unsigned char} dpid * @param {const unsigned char} value * @param {unsigned short} length * @return {unsigned char} */unsigned char dp_process(unsigned char dpid, const unsigned char value[], unsigned short length){    switch (dpid) {        case DPID_BOOL:            DebugSerial.println("Bool type:");            dp_bool_value = my_device.mcu_get_dp_download_data(dpid, value, length);            DebugSerial.println(dp_bool_value);            /* After processing the download DP command, the current status should be reported. */            my_device.mcu_dp_update(DPID_BOOL, dp_bool_value, 1);        break;                    case DPID_VALUE:            DebugSerial.println("Value type:");            dp_value_value = my_device.mcu_get_dp_download_data(DPID_VALUE, value, length);            DebugSerial.println(dp_value_value);            /* After processing the download DP command, the current status should be reported. */            my_device.mcu_dp_update(DPID_VALUE, dp_value_value, 1);        break;        case DPID_ENUM:            DebugSerial.println("Enum type:");            dp_enum_value = my_device.mcu_get_dp_download_data(dpid, value, length);            DebugSerial.println(dp_enum_value);            /* After processing the download DP command, the current status should be reported. */            my_device.mcu_dp_update(DPID_ENUM, dp_enum_value, 1);        break;        case DPID_STRING:            DebugSerial.println("String type:");            /*  */            for (unsigned int i=0; i<length; i++) {                dp_string_value[i] = value[i];                DebugSerial.write(dp_string_value[i]);            }            DebugSerial.println("");            /* After processing the download DP command, the current status should be reported. */            my_device.mcu_dp_update(DPID_STRING, dp_string_value, length);        break;        case DPID_RAW:            DebugSerial.println("Raw type:");            /*  */            for (unsigned int i=0; i<length; i++) {                dp_raw_value[i] = value[i];                DebugSerial.write(dp_raw_value[i]);            }            DebugSerial.println("");            /* After processing the download DP command, the current status should be reported. */            my_device.mcu_dp_update(DPID_RAW, dp_raw_value, length);        break;        default:            break;    }        return SUCCESS;}

这里得注意一个方法:

mcu_get_dp_download_data  (`下发DP数据处理`)

对字节数组进行数据解析。

3.4.5 mcu_dp_update —— 真正上报设备状态

    /* char * */    unsigned char mcu_dp_update(unsigned char dpid, const unsigned char value[], unsigned short len); /* char raw */    /* unsigned long / long */    unsigned char mcu_dp_update(unsigned char dpid, unsigned long value, unsigned short len);    unsigned char mcu_dp_update(unsigned char dpid, long value, unsigned short len);    /* unsigned char / char */    unsigned char mcu_dp_update(unsigned char dpid, unsigned char value, unsigned short len);    unsigned char mcu_dp_update(unsigned char dpid, char value, unsigned short len);    /* unsigned int / int */    unsigned char mcu_dp_update(unsigned char dpid, unsigned int value, unsigned short len);    unsigned char mcu_dp_update(unsigned char dpid, int value, unsigned short len);

基本上大同小异。注意一下dpid和数据类型即可。

3.4.6 dp_update_all_func_register —— 上报设备状态函数注册

#include TuyaWifi my_device;#define DPID_SWITCH 20//Record the current status of the ledunsigned char switch_value = 0;...void setup() {    ...  //register DP download processing callback function  my_device.dp_update_all_func_register(dp_update_all);    ...}/** * @description: Upload all DP status of the current device. * @param {*} * @return {*} */void dp_update_all(void){  my_device.mcu_dp_update(DPID_SWITCH, switch_v

3.4.7 mcu_get_wifi_work_state —— 获取wifi连接状态

3.4.8 void TuyaWifi::uart_service(void) —— 轮询串口数据

/** * @description: Wifi serial port processing service * @param {*} * @return {*} */void TuyaWifi::uart_service(void)

在arduino loop中调用。不断检测串口数据。

4、官方案例

/* * @FileName: DataPointType.ino * @Author: Tuya * @Email:  * @LastEditors: Tuya * @Date: 2021-04-19 14:31:52 * @LastEditTime: 2021-04-28 19:47:36 * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD * @Company: http://www.tuya.com * @Description:  * @Github:https://github.com/tuya/tuya-wifi-mcu-sdk-arduino-library */#include #include TuyaWifi my_device;SoftwareSerial DebugSerial(8,9);/* Current LED status */unsigned char led_state = 0;/* Connect network button pin */int wifi_key_pin = 7;/* Data point define */#define DPID_BOOL   101#define DPID_VALUE  102#define DPID_ENUM   103#define DPID_STRING 104#define DPID_RAW    105#define DPID_FAULT  106/* Current device DP values */unsigned char dp_bool_value = 0;long dp_value_value = 0;unsigned char dp_enum_value = 0;unsigned char dp_string_value[8] = {"Hi,Tuya"};unsigned char dp_raw_value[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};int dp_fault_value = 0x01;/* Stores all DPs and their types. PS: array[][0]:dpid, array[][1]:dp type.  *                                     dp type(TuyaDefs.h) : DP_TYPE_RAW, DP_TYPE_BOOL, DP_TYPE_VALUE, DP_TYPE_STRING, DP_TYPE_ENUM, DP_TYPE_BITMAP*/unsigned char dp_array[][2] = {    {DPID_BOOL, DP_TYPE_BOOL},    {DPID_VALUE, DP_TYPE_VALUE},    {DPID_ENUM, DP_TYPE_ENUM},    {DPID_STRING, DP_TYPE_STRING},    {DPID_RAW, DP_TYPE_RAW},    {DPID_FAULT, DP_TYPE_BITMAP},};unsigned char pid[] = {"xxxxxxxxxxx"}; //  填上自己的产品IDunsigned char mcu_ver[] = {"1.0.0"};/* last time */unsigned long last_time = 0;void setup(){    Serial.begin(9600);    DebugSerial.begin(9600);    //Initialize led port, turn off led.    pinMode(LED_BUILTIN, OUTPUT);    digitalWrite(LED_BUILTIN, LOW);    //Initialize networking keys.    pinMode(wifi_key_pin, INPUT_PULLUP);    // 三部曲 —— 初始化、配置、注册回调    //Enter the PID and MCU software version    my_device.init(pid, mcu_ver);    //incoming all DPs and their types array, DP numbers    my_device.set_dp_cmd_total(dp_array, 6);    //register DP download processing callback function    my_device.dp_process_func_register(dp_process);    //register upload all DP callback function    my_device.dp_update_all_func_register(dp_update_all);    last_time = millis();}void loop(){    // 不断轮询    my_device.uart_service();    //Enter the connection network mode when Pin7 is pressed.    if (digitalRead(wifi_key_pin) == LOW) {        delay(80);        if (digitalRead(wifi_key_pin) == LOW) {            my_device.mcu_set_wifi_mode(SMART_CONFIG);        }    }    /* LED blinks when network is being connected */    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)) {        if (millis() - last_time >= 500) {            last_time = millis();            /* Toggle current LED status */            if (led_state == LOW) {                led           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119500.html

相关文章

  • redux 闲谈

    摘要:使用中间件后的也是通过中间件包装后的。在的位置则进行触发监听器,监听器设置则在中增加。现在来解释,和对应关系我当时回答的是对应的函数名称,如果一致的话就会执行。呵呵,那个涂鸦大工程师有问题了如何绑定的呢,怎么确定是而不是。 redux 闲谈 起因: 在与涂鸦智能一个web工程师交流过程中,他询问我dispatch一个action,是如何和reducer 绑定的,dispatch(act...

    levius 评论0 收藏0
  • STM32CubeMX学习教程之硬件I2C读取光照度

    摘要:使用库读写环境光照度传感器本文将教大家如何快速使用库读取光照度数据。五实验样机测试展示通过之前配置好的面板,通过涂鸦智能进行配网实时采集光照度传感器的数据。 使用STM32 HAL库读写环境光照度传感器(BH1750) 本文将教大家如何快速使用STM32HAL库读取光照度数据。 实现功能:通...

    tinylcy 评论0 收藏0
  • Android:涂鸦tuytaSDK实现逻辑

    摘要:开启扫描时需要设备处于配网状态一分类配网子设备可以通过使用手机蓝牙直接扫描获取设备到设备基础信息,再使用配网接口实现设备的本地配网。   (一)分类   (二)设备配置   (三)设备管理     设备管理,大体分为两类,mesh 和 其他     获取设备列表,给涂鸦sdk发送当前房间id...

    MorePainMoreGain 评论0 收藏0
  • 文森特系统用深度学习将涂鸦变成艺术创作

    摘要:研究者创建了一个名叫文森特的系统是的,就是梵高那个文森特使用深度学习,将简笔画转变为艺术品。研究人员认为,除了在艺术绘画方面大放异彩,类似文森特的技术还有一系列潜在的应用。 如果你喜欢艺术但下笔皆为灵魂画作,那么今天要介绍的这个项目肯定合你心意。AI研究者创建了一个名叫文森特(Vincet)的系统——是的,就是梵高那个文森特——使用深度学习,将简笔画转变为艺术品。用户在平板上的涂鸦经过文森特...

    PumpkinDylan 评论0 收藏0
  • 神经网络已经猜到了你要绘制的内容

    摘要:我们进行了一个交互式网络实验,让你能与一个名为的循环神经网络模型一起绘制作品。我们利用来自于游戏的数百万涂鸦训练该神经网络。一旦你停止涂鸦,神经网络将接管并试图猜测涂鸦的其余部分。在变分自动编码器演示中,你将绘制指定对象的完整图形。 对于通过蜂窝数据连接网络的移动用户:第一个演示大小约为 5 MB 数据。每次在演示中更改模型时,您将使用另外 5 MB 的数据。我们进行了一个交互式网络实验,让...

    wendux 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<