电量统计

更新时间:2022-11-24 09:20:26下载pdf

电量统计适用于需要计量的产品。该层逻辑对设备的工作功率,工作电压,工作电流,电量进行采样并上报到涂鸦。

电量统计功能需要对电量数据进行相关处理,需要包含 app_uf_db 组件。

API 概览

如下是对电量统计组件主要 API 的介绍,更多 API 详细信息见 tuya_measure_com.h 文件。

API 说明
tuya_dev_measure_reg 注册电量统计相关参数
tuya_dev_measure_start 启动计量功能
tuya_get_measure_rms 获取当前电压、电流、功率
tuya_get_emasure_energy 获取周期内的电量增量,读取周期由应用决定,读取后自动清0,重新开始累计
tuya_get_measure_rslt 获取产测结果
tuya_get_calibration_para 获取产测内容,一般是返回电压,电流,功率,电量校准系数
tuya_clear_calibration_date 清除校准结果数据

原理

计量采样方式

目前支持两种采样方式:

  • 脉冲采样:计量芯片在固定时间内,输出一定的脉冲数来标识采样数据

  • 串口采样:计量芯片通过 UART 通信传输采样数据

计量芯片

电量统计组件支持多种电量统计芯片,可根据硬件电路进行选择,详细的说明如下:

  • BL0937: 脉冲采样,采样电阻1R/2R可选

  • HLW8012:脉冲采样,采样电阻1R/2R可选

  • HLW8032:串口采样,采样电阻1R

  • BL0942:串口采样,采样电阻1R,免校准芯片,如果要通过产测进行校准,供电电压必须和默认值0误差,一般需要在交流电源上校准。

电量统计存储交互逻辑

电量统计

推荐您使用涂鸦方案,如您需自行设计,可通过tuya_get_measure_rmstuya_get_emasure_energy 接口获取相关采样数据进行开发设计。

功能说明

  • 支持 4 款电量统计芯片驱动
  • 支持 220V/120V 标准下的电压,电流,功率,增加电量采样
  • 校准后的计量精度大约 3%

使用示例

  1. device_init中初始化电量统计功能。

    OPERATE_RET device_init(VOID)
    {
    	OPERATE_RET op_ret = OPRT_OK;
    
    	/*
    	其他初始化
    	...
    	*/
    
    	// 注册电量统计参数
    	op_ret = user_dltj_params_register();
    	if (OPRT_OK != op_ret) {
    		return op_ret;
    	}
    	// 注册成功,开启计量,非校准模式
    	op_ret = tuya_dev_measure_start(FALSE);
    	if (OPRT_OK != op_ret) {
    		return op_ret;
    	}
    
    	/*[采用涂鸦的电压,电流,功率,电量
    	的上报/存储方案(具体设计逻辑见:docs/tuya_电压_电流_功率_上报存储逻辑.png),
    	需要初始化tuya_dltj_init接口,如下:]*/
    	COE_DLTJ_TYPE_S dp_info;
    	dp_info.vol_dp = DPID_VOLT;
    	dp_info.cur_dp = DPID_CURR;
    	dp_info.pow_dp = DPID_POWER;
    	dp_info.energy_dp = DPID_ADD_ELE;
    
    	op_ret = tuya_dltj_init(dp_info, tuya_get_measure_rms, tuya_get_emasure_energy);
    	if (OPRT_OK != op_ret) {
    		PR_ERR("dltj unit init err:%d", op_ret);
    		return op_ret;
    	}
    /*[自行设计上报和存储方案,
    	可通过tuya_get_measure_rms和tuya_get_emasure_energy
    	接口获取相关采样数据,进行设计]*/
    
    	/*
    	...
    	*/
    
    return op_ret;
    }
    
    /**
    * @brief user_dltj_params_register
    *        注册电量统计相关参数
    * @param[in] VOID_T
    * 
    * @return VOID_T 
    */
    OPERATE_RET user_dltj_params_register(VOID_T)
    {
    	TY_DEV_MEASURE_PAPR_S devinfo;
    
    	extern UCHAR_T get_dltj_ele_pin(VOID_T);
    	extern UCHAR_T get_dltj_vi_pin(VOID_T);
    	extern UCHAR_T get_dltj_sel_pin(VOID_T);
    
    	memset(&devinfo, 0, SIZEOF(devinfo));
    	if (0 == MEASURE_DEF_VLOT_TYPE) {
    		devinfo.v_ref       = V_DEF_220; // 220V规格
    		devinfo.i_ref       = I_DEF_220; // 220V下560欧的参考电流
    		devinfo.p_ref       = P_DEF_220; // 220V下560欧的参考功率
    		PR_DEBUG("dev vlot type 220v");
    	} else {
    		devinfo.v_ref       = V_DEF_120; // 120V规格
    		devinfo.i_ref       = I_DEF_120; // 120V
    		devinfo.p_ref       = P_DEF_120; // 120v
    		PR_DEBUG("dev vlot type 110v");
    	}
    	devinfo.type        = MEASURE_CHIP; // 计量芯片类型 0:DEV_BL0937 1:DEV_HLW8012 2:DEV_HLW8032 3:DEV_BL0942
    	devinfo.uart_no     = TY_UART0; // 串口通信芯片对应使用的串口号
    	devinfo.timer_no    = TUYA_TIMER0; // 硬件定时器
    	devinfo.resval      = MEASURE_RES;
    	devinfo.epin        = get_dltj_ele_pin();
    	devinfo.ivpin       = get_dltj_vi_pin();
    	devinfo.ivcpin.pin  = get_dltj_sel_pin();
    	devinfo.ivcpin.type = MEASURE_SEL_PIN_TYPE;
    	devinfo.if_measure  = TRUE; // 带计量功能
    
    	return tuya_dev_measure_reg(devinfo);
    }
    
  2. mf_user_callback授权回调里增加清保存电量和校准参数。

    VOID mf_user_callback(VOID)
    {
    	/*
    	...
    	*/
    	tuya_clear_calibration_date(); // 清校准参数
    	tuya_clear_all_energy(); // 清电量数据
    }
    
  3. gw_reset_cb网关复位里增加清保存电量。

    VOID gw_reset_cb(IN CONST GW_RESET_TYPE_E type)
    {
    	/*
    	...
    	*/
    	if (GW_REMOTE_RESET_FACTORY == type) {
    		tuya_clear_all_energy(); // 清电量数据
    		return;
    	}
    }
    
  4. app_init里增加重复产测信标设置。

    VOID app_init(VOID)
    {
    	/*
    	...
    	*/
    
    	if (tuya_get_measure_rslt()) {
    		set_prod_ssid("tuya_mdev_test2");
    	}
    }
    
  5. status_changed_cb里增加校准参数上报。

    VOID status_changed_cb(IN CONST GW_STATUS_E status)
    {
    	if (GW_NORMAL == status) {
    		/*
    		...
    		*/
    	user_dltj_upload_coe_params(); // 上报电量统计校准参数
    	}
    	/*
    	...
    	*/
    }
    
    /**
    * @brief user_dltj_upload_coe_params
    *        上报电量统计校准参数
    * @param[in] VOID_T
    * 
    * @return OPERATE_RET 
    */
    OPERATE_RET user_dltj_upload_coe_params(VOID_T)
    {
    	OPERATE_RET ret = OPRT_OK;
    	PROD_MEASURE_COE_S *date = tuya_get_calibration_para();
    
    	if(NULL == date) {
    		return OPRT_INVALID_PARM;
    	}
    
    	TY_OBJ_DP_S dp_pvi[5] = {
    		{
    			.dpid = DPID_PT_FLAG,
    			.type = PROP_VALUE,
    			.time_stamp = 0,
    			.value.dp_value = date->prod_result
    		},
    
    		{
    			.dpid = DPID_VOLT_COE,
    			.type = PROP_VALUE,
    			.time_stamp = 0,
    			.value.dp_value = ((GENERAL_COE_S *)(date->prod_date_struct))->v_ref
    		},
    
    		{
    			.dpid = DPID_CURR_COE,
    			.type = PROP_VALUE,
    			.time_stamp = 0,
    			.value.dp_value = ((GENERAL_COE_S *)(date->prod_date_struct))->i_ref
    		},
    
    		{
    			.dpid = DPID_POWER_COE,
    			.type = PROP_VALUE,
    			.time_stamp = 0,
    			.value.dp_value = ((GENERAL_COE_S *)(date->prod_date_struct))->p_ref
    		},
    
    		{
    			.dpid = DPID_ELE_COE,
    			.type = PROP_VALUE,
    			.time_stamp = 0,
    			.value.dp_value = ((GENERAL_COE_S *)(date->prod_date_struct))->e_ref
    		}
    	};
    
    	ret = dev_report_dp_json_async(get_gw_cntl()->gw_if.id, dp_pvi, 5);
    	if (OPRT_OK != ret) {
    		PR_ERR("upload_dltj_coe_param ret:%d", ret);
    	}
    
    	return ret;
    }
    
  6. tuya_app_prod_enter信标产测接口里增加计量芯片校准。

    VOID tuya_app_prod_enter(IN BOOL_T flag, IN CHAR_T rssi)
    {
    	/*
    	禁止继电器控制操作,如:按键控制,需要禁止按键操作,等待校准结束再进行别的测试
    	*/
    	key_ctrl_en = FALSE;
    
    	/*注册电量统计参数*/
    	op_ret = user_dltj_params_register(); // 此函数定义见第一步device_init里
    	if(OPRT_OK != op_ret) {
    		return;
    	}
    
    	/*打开继电器*/
    	app_set_channel_stat(TRUE);
    	/*等待3s*/
    	tuya_hal_system_sleep(3000);
    	/*启动校准测试*/
    	ret = tuya_dev_measure_start(TRUE);
    	/*校准结束关闭继电器*/
    	app_set_channel_stat(FALSE);
    
    	if (OPRT_OK == ret) {
    		/*
    		校准成功,可以增加指示灯来显示
    		*/
    	} else {
    		/*
    		校准失败,可以增加指示灯来显示
    		*/
    	return; // 停止别的项测试,直接return
    	}
    
    	/*开启按键测试...*/
    	key_ctrl_en = TRUE;
    
    	/*
    	...
    	*/
    }
    

产测流程

在产品批量生产时,要对产品的电量统计功能进行自动化验证,涂鸦根据多年智能产品量产经验,整理了一套标准的产测流程,详情请参考 计量产测流程