【已提供】关于ADC采集速度慢的问题
Posted: 2022年 Nov 9日 15:25
您好,我这边使用老版的Tuya os 版本2.3.3 bk7231n的
ADC 使用 tuya_adc_convert 收集数据的速度非常慢——每秒只有几百个样本
想问下有什么办法可以提高 ADC 的速度吗
您好,我这边使用老版的Tuya os 版本2.3.3 bk7231n的
ADC 使用 tuya_adc_convert 收集数据的速度非常慢——每秒只有几百个样本
想问下有什么办法可以提高 ADC 的速度吗
bk7231n adc 实际上是一个adc,多个通道。 所以adc使用完需要close,把资源释放出来给其他通道使用。每次open->read->close, 会导致adc读取时速度变慢。具体代码如下:
Code: Select all
static int adc_dev_convert (tuya_adc_t *adc, uint16_t *result)
{
unsigned char i = 0;
unsigned int status;
int adc_hdl;
static unsigned short last_adc = 0;
unsigned char adc_channel = adc->cfg.pin;
if(!g_adc_init[adc_channel]){
LOG_ERR("adc not init!\r\n");
return OPRT_OS_ADAPTER_COM_ERROR;
}
GLOBAL_INT_DECLARATION();
*(unsigned short*)result = 0xFFFF;
memset(adc_desc[adc_channel].pData, 0, adc_desc[adc_channel].data_buff_size * SIZEOF(unsigned short));
GLOBAL_INT_DISABLE();
adc_hdl = ddev_open(SARADC_DEV_NAME, &status, (unsigned int)&adc_desc[adc_channel]);
if ((DD_HANDLE_UNVALID == adc_hdl) || (SARADC_SUCCESS != status))
{
if (SARADC_SUCCESS != status)
{
ddev_close(adc_hdl);
}
adc_hdl = DD_HANDLE_UNVALID;
GLOBAL_INT_RESTORE();
LOG_ERR("adv ddev_open err:%d\r\n", status);
return -1;
}
GLOBAL_INT_RESTORE();
while (adc_desc[adc_channel].all_done == 0)
{
i ++;
if (i > 100)
{
LOG_ERR("adc get timeout!\r\n");
break;
}
vTaskDelay(1);
}
if(adc_desc[adc_channel].current_sample_data_cnt >= 1) //此处简化直接就是采集1次,1这个数值后续可以优化
{
*(USHORT_T*)result = adc_desc[adc_channel].pData[0];
adc_desc[adc_channel].has_data = 0;
adc_desc[adc_channel].current_sample_data_cnt = 0;
last_adc = *(USHORT_T*)result;
} else {
*(USHORT_T*)result = last_adc;
}
ddev_close(adc_hdl);
saradc_ensure_close();
return OPRT_OS_ADAPTER_OK;
}
如果要求adc 采集速度快些, 可以自己重新封装下adc read接口,open->读取多个值->close. 可以参考下面代码:
Code: Select all
static int adc_dev_convert (tuya_adc_t *adc, uint16_t *result)
{
unsigned char i = 0;
unsigned int status, sum = 0;
int adc_hdl;
static unsigned short last_adc = 0;
unsigned short temp_adc_mv = 0;
unsigned int adc_max = 0, adc_min = 0;
unsigned char adc_channel = adc->cfg.pin;
if(!g_adc_init[adc_channel]){
LOG_ERR("adc not init!\r\n");
return OPRT_OS_ADAPTER_COM_ERROR;
}
GLOBAL_INT_DECLARATION();
*(unsigned short*)result = 0xFFFF;
memset(adc_desc[adc_channel].pData, 0, adc_desc[adc_channel].data_buff_size * SIZEOF(unsigned short));
GLOBAL_INT_DISABLE();
adc_hdl = ddev_open(SARADC_DEV_NAME, &status, (unsigned int)&adc_desc[adc_channel]);
if ((DD_HANDLE_UNVALID == adc_hdl) || (SARADC_SUCCESS != status))
{
if (SARADC_SUCCESS != status)
{
ddev_close(adc_hdl);
}
adc_hdl = DD_HANDLE_UNVALID;
GLOBAL_INT_RESTORE();
LOG_ERR("adv ddev_open err:%d\r\n", status);
return -1;
}
GLOBAL_INT_RESTORE();
while (1)
{
//bk_printf("d:%d,%d\r\n",saradc_desc->current_sample_data_cnt,p_ADC_drv_desc->current_sample_data_cnt);
if (adc_desc[adc_channel].current_sample_data_cnt == adc_desc[adc_channel].data_buff_size)
{
ddev_close(adc_hdl);
saradc_ensure_close();
break;
}
}
adc_max = adc_min = adc_desc[adc_channel].pData[34];
for (i = 32; i < 50; i++)
{
if(adc_max < adc_desc[adc_channel].pData[i])
adc_max = adc_desc[adc_channel].pData[i];
else if(adc_min > adc_desc[adc_channel].pData[i])
adc_min = adc_desc[adc_channel].pData[i];
sum += adc_desc[adc_channel].pData[i];
}
temp_adc_mv = saradc_calculate((UINT16)((sum - adc_max - adc_min) >> 4)) * 1000;
*(USHORT_T*)result = temp_adc_mv * ADC_REGISTER_VAL_MAX / ADC_VOLTAGE_MAX;
sum = 0;
adc_desc[adc_channel].current_read_data_cnt = 0;
return OPRT_OS_ADAPTER_OK;
}
chaser 2022年 Nov 9日 16:04bk7231n adc 实际上是一个adc,多个通道。 所以adc使用完需要close,把资源释放出来给其他通道使用。每次open->read->close, 会导致adc读取时速度变慢。具体代码如下:
Code: Select all
static int adc_dev_convert (tuya_adc_t *adc, uint16_t *result)
{
unsigned char i = 0;
unsigned int status;
int adc_hdl;
static unsigned short last_adc = 0;
unsigned char adc_channel = adc->cfg.pin;
if(!g_adc_init[adc_channel]){
LOG_ERR("adc not init!\r\n");
return OPRT_OS_ADAPTER_COM_ERROR;
}
GLOBAL_INT_DECLARATION();
*(unsigned short*)result = 0xFFFF;
memset(adc_desc[adc_channel].pData, 0, adc_desc[adc_channel].data_buff_size * SIZEOF(unsigned short));
GLOBAL_INT_DISABLE();
adc_hdl = ddev_open(SARADC_DEV_NAME, &status, (unsigned int)&adc_desc[adc_channel]);
if ((DD_HANDLE_UNVALID == adc_hdl) || (SARADC_SUCCESS != status))
{
if (SARADC_SUCCESS != status)
{
ddev_close(adc_hdl);
}
adc_hdl = DD_HANDLE_UNVALID;
GLOBAL_INT_RESTORE();
LOG_ERR("adv ddev_open err:%d\r\n", status);
return -1;
}
GLOBAL_INT_RESTORE();
while (adc_desc[adc_channel].all_done == 0)
{
i ++;
if (i > 100)
{
LOG_ERR("adc get timeout!\r\n");
break;
}
vTaskDelay(1);
}
if(adc_desc[adc_channel].current_sample_data_cnt >= 1) //此处简化直接就是采集1次,1这个数值后续可以优化
{
*(USHORT_T*)result = adc_desc[adc_channel].pData[0];
adc_desc[adc_channel].has_data = 0;
adc_desc[adc_channel].current_sample_data_cnt = 0;
last_adc = *(USHORT_T*)result;
} else {
*(USHORT_T*)result = last_adc;
}
ddev_close(adc_hdl);
saradc_ensure_close();
return OPRT_OS_ADAPTER_OK;
}如果要求adc 采集速度快些, 可以自己重新封装下adc read接口,open->读取多个值->close. 可以参考下面代码:
Code: Select all
static int adc_dev_convert (tuya_adc_t *adc, uint16_t *result)
{
unsigned char i = 0;
unsigned int status, sum = 0;
int adc_hdl;
static unsigned short last_adc = 0;
unsigned short temp_adc_mv = 0;
unsigned int adc_max = 0, adc_min = 0;
unsigned char adc_channel = adc->cfg.pin;
if(!g_adc_init[adc_channel]){
LOG_ERR("adc not init!\r\n");
return OPRT_OS_ADAPTER_COM_ERROR;
}
GLOBAL_INT_DECLARATION();
*(unsigned short*)result = 0xFFFF;
memset(adc_desc[adc_channel].pData, 0, adc_desc[adc_channel].data_buff_size * SIZEOF(unsigned short));
GLOBAL_INT_DISABLE();
adc_hdl = ddev_open(SARADC_DEV_NAME, &status, (unsigned int)&adc_desc[adc_channel]);
if ((DD_HANDLE_UNVALID == adc_hdl) || (SARADC_SUCCESS != status))
{
if (SARADC_SUCCESS != status)
{
ddev_close(adc_hdl);
}
adc_hdl = DD_HANDLE_UNVALID;
GLOBAL_INT_RESTORE();
LOG_ERR("adv ddev_open err:%d\r\n", status);
return -1;
}
GLOBAL_INT_RESTORE();
while (1)
{
//bk_printf("d:%d,%d\r\n",saradc_desc->current_sample_data_cnt,p_ADC_drv_desc->current_sample_data_cnt);
if (adc_desc[adc_channel].current_sample_data_cnt == adc_desc[adc_channel].data_buff_size)
{
ddev_close(adc_hdl);
saradc_ensure_close();
break;
}
}
adc_max = adc_min = adc_desc[adc_channel].pData[34];
for (i = 32; i < 50; i++)
{
if(adc_max < adc_desc[adc_channel].pData[i])
adc_max = adc_desc[adc_channel].pData[i];
else if(adc_min > adc_desc[adc_channel].pData[i])
adc_min = adc_desc[adc_channel].pData[i];
sum += adc_desc[adc_channel].pData[i];
}
temp_adc_mv = saradc_calculate((UINT16)((sum - adc_max - adc_min) >> 4)) * 1000;
*(USHORT_T*)result = temp_adc_mv * ADC_REGISTER_VAL_MAX / ADC_VOLTAGE_MAX;
sum = 0;
adc_desc[adc_channel].current_read_data_cnt = 0;
return OPRT_OS_ADAPTER_OK;
}
感谢 我这边测试下