前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开发者成长激励计划-基于TencentOS Tiny 的加热不燃烧烟具温度检测设备

开发者成长激励计划-基于TencentOS Tiny 的加热不燃烧烟具温度检测设备

原创
作者头像
Torry
修改2022-08-08 20:37:02
2420
修改2022-08-08 20:37:02
举报
文章被收录于专栏:网连物网连物

一、作品简介:

代码语言:txt
复制
   我们在开发加热不燃烧烟具的过程中,需要吧烟具内部的温度加到一个比较高的温度(200-300摄氏度),烟具内部本身有测温器件,但是不能保证烟具自己测试的温度就是准确的,所以就需要一个外部也要增加设备来辅助测试一下,并且把整个加热过程中的温度变化画出曲线,有助于对整个设备的研究。所以我们这次开发所用的硬件除了赤兔CH32V307开发板以外,还增加一个NTC的检测电路。如下图所示:
开发板加上NTC测温器件
开发板加上NTC测温器件
NTC原理图
NTC原理图

二、软件开发过程

1、软件环境

此次开发和编译坏境是沁恒微的MounRiver Studio软件,此软件用熟了感觉你keil好用太多了,并且还是免费的开发软件。具体如何好,只有真正使用来开发的各位工程师能明白,在此就不多说了。界面如下图所示:

MounRiver Studio开发软件界面
MounRiver Studio开发软件界面

2、基础例程测试:

本次设计的基础例程是本次活动提供的例程“TencentOS_DVP”。此代码已经包含了LCD屏的驱动,摄像头的驱动,以及AT指令以及MQTT协议等功能。只要稍加运用就可以做成一个可以连上腾讯云的网络产品。如下图所示就是本次测试连到腾讯云的日志记录:

腾讯云端日志图
腾讯云端日志图

3、云端开发:

根据学习视频和PPT学习,自己测试了一些简单的测试开发,开发还是比较方便的。只是时间紧,工作忙,没有实际真正开发成产品,等忙完这段时间,过段时间直接在公司立个预研项目直接开发,从此一个单片机工程师转变成一个全能物联网工程师还是有可能的。开发小程序如下图所示:

腾讯云小程序开发界面图
腾讯云小程序开发界面图

4、温度检测程序实现

NTC的温度检测,其原理就是使用热敏电阻的特性,根据厂家给出的热敏电阻对应温度参数,然后设计一个电路,使用电阻分压的情况下读取分压电阻的电压值,从而查表得出测试环境的实际温度值。程序代码如下:

代码语言:javascript
复制
#include "debug.h"
#include "tos_k.h"
#include "lcd.h"
#include "lcd_init.h"
#include "user_read_temperature.h"
#define M_COUNT_OF(Obj)         (sizeof(Obj) / sizeof(Obj[0]))//总长度除以个体长度等于个数

Dev_ADC vDev_ADC;

s16 Calibrattion_Val = 0;
const uint16_t list_N_V[330] =
{
4090,4089,4089,4088,4088,4087,4087,4086,4086,4085,
4085,4084,4083,4083,4082,4081,4080,4080,4079,4078,
4077,4076,4075,4074,4073,4071,4070,4069,4067,4066,
4065,4063,4061,4060,4058,4056,4054,4052,4050,4048,
4046,4044,4041,4039,4036,4034,4031,4028,4025,4022,
4019,4015,4012,4008,4004,4000,3996,3992,3988,3983,
3978,3973,3968,3963,3958,3952,3946,3940,3934,3927,
3921,3914,3907,3899,3892,3884,3876,3868,3859,3850,
3841,3832,3822,3812,3802,3791,3781,3770,3758,3747,
3735,3722,3710,3697,3684,3670,3656,3642,3628,3613,
3598,3582,3566,3550,3534,3517,3500,3482,3464,3446,
3427,3409,3389,3370,3350,3330,3309,3288,3267,3246,
3224,3201,3178,3154,3131,3107,3082,3058,3033,3007,
2982,2956,2930,2904,2877,2851,2824,2797,2770,2742,
2714,2687,2659,2631,2603,2574,2546,2517,2489,2460,
2414,2368,2340,2312,2284,2255,2227,2199,2171,2143,
2115,2087,2059,2031,2004,1976,1949,1922,1895,1868,
1841,1815,1788,1762,1737,1711,1685,1660,1635,1610,
1585,1561,1537,1514,1491,1467,1445,1422,1400,1377,
1355,1334,1312,1291,1270,1249,1229,1209,1189,1169,
1150,1131,1112,1093,1075,1057,1039,1021,1004,987 ,
970 ,954 ,937 ,921 ,905 ,890 ,874 ,859 ,845 ,830 ,
815 ,801 ,787 ,773 ,760 ,747 ,734 ,721 ,709 ,696 ,
684 ,672 ,661 ,649 ,638 ,626 ,616 ,605 ,594 ,584 ,
574 ,564 ,554 ,545 ,535 ,526 ,517 ,508 ,499 ,490 ,
482 ,474 ,465 ,457 ,450 ,442 ,434 ,427 ,420 ,413 ,
405 ,398 ,392 ,385 ,379 ,372 ,366 ,360 ,354 ,348 ,
342 ,336 ,331 ,325 ,320 ,315 ,309 ,304 ,299 ,294 ,
289 ,285 ,280 ,276 ,271 ,267 ,262 ,258 ,254 ,250 ,
245 ,242 ,238 ,234 ,230 ,226 ,223 ,220 ,216 ,213 ,
209 ,206 ,203 ,200 ,197 ,194 ,191 ,188 ,185 ,182 ,
179 ,176 ,174 ,171 ,168 ,166 ,163 ,161 ,159 ,156 ,
153 ,151 ,149 ,147 ,145 ,143 ,140 ,138 ,136 ,135 ,
};
int uGetHeaterTemperature(uint8_t ch)//NTC测温
{
    int data_len,x=0;
    static uint16_t Adcn;
    data_len=M_COUNT_OF(list_N_V);
    Adcn = vDev_ADC.Read_ADC[ch];//userADC_var.ADC_uDATA[ch];
    if((Adcn<=list_N_V[0])&&(Adcn>=list_N_V[data_len-1]))
    {
        for(x=0;x<data_len-1;x++)
        {
            if(Adcn>=list_N_V[x])
            {
                break;
            }
        }
    }
    return x;
}
/*********************************************************************
 * @fn      ADC_Function_Init
 *
 * @brief   Initializes ADC collection.
 *
 * @return  none
 */
void ADC_Function_Init(void)
{
    ADC_InitTypeDef ADC_InitStructure={0};
    GPIO_InitTypeDef GPIO_InitStructure={0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_DMACmd(ADC1, ENABLE);
    ADC_Cmd(ADC1, ENABLE);

    ADC_BufferCmd(ADC1, DISABLE);   //disable buffe
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
    Calibrattion_Val = Get_CalibrationValue(ADC1);

    ADC_BufferCmd(ADC1, ENABLE);   //enable buffe
}

/*********************************************************************
 * @fn      Get_ADC_Val
 *
 * @brief   Returns ADCx conversion result data.
 *
 * @param   ch - ADC channel.
 *            ADC_Channel_0 - ADC Channel0 selected.
 *            ADC_Channel_1 - ADC Channel1 selected.
 *            ADC_Channel_2 - ADC Channel2 selected.
 *            ADC_Channel_3 - ADC Channel3 selected.
 *            ADC_Channel_4 - ADC Channel4 selected.
 *            ADC_Channel_5 - ADC Channel5 selected.
 *            ADC_Channel_6 - ADC Channel6 selected.
 *            ADC_Channel_7 - ADC Channel7 selected.
 *            ADC_Channel_8 - ADC Channel8 selected.
 *            ADC_Channel_9 - ADC Channel9 selected.
 *            ADC_Channel_10 - ADC Channel10 selected.
 *            ADC_Channel_11 - ADC Channel11 selected.
 *            ADC_Channel_12 - ADC Channel12 selected.
 *            ADC_Channel_13 - ADC Channel13 selected.
 *            ADC_Channel_14 - ADC Channel14 selected.
 *            ADC_Channel_15 - ADC Channel15 selected.
 *            ADC_Channel_16 - ADC Channel16 selected.
 *            ADC_Channel_17 - ADC Channel17 selected.
 *
 * @return  none
 */
u16 Get_ADC_Val(u8 ch)
{
    u16 val;

    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
    val = ADC_GetConversionValue(ADC1);

    return val;
}
/*********************************************************************
 * @fn      DMA_Tx_Init
 *
 * @brief   Initializes the DMAy Channelx configuration.
 *
 * @param   DMA_CHx - x can be 1 to 7.
 *          ppadr - Peripheral base address.
 *          memadr - Memory base address.
 *          bufsize - DMA channel buffer size.
 *
 * @return  none
 */
void DMA_Tx_Init( DMA_Channel_TypeDef* DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize)
{
    DMA_InitTypeDef DMA_InitStructure={0};

    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );

    DMA_DeInit(DMA_CHx);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr;
    DMA_InitStructure.DMA_MemoryBaseAddr = memadr;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = bufsize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init( DMA_CHx, &DMA_InitStructure );
}
/*********************************************************************
 * @fn      Get_ConversionVal
 *
 * @brief   Get Conversion Value.
 *
 * @param   val - Sampling value
 *
 * @return  val+Calibrattion_Val - Conversion Value.
 */
u16 Get_ConversionVal(s16 val)
{
    if((val+Calibrattion_Val)<0) return 0;
    if((Calibrattion_Val+val)>4095||val==4095) return 4095;
    return (val+Calibrattion_Val);
}

void user_Read_ADC(void)
{
    uint8_t temp_D[50];
    u16 ADC_Buf[1],Temperature[2];
    ADC_Function_Init();
    printf("CalibrattionValue:%d\n", Calibrattion_Val);
    while(1)
    {
        ADC_Buf[0] = Get_ADC_Val(ADC_Channel_8);
        //Temperature[1] = TempSensor_Volt_To_Temper(Get_ADC_Val(ADC_Channel_TempSensor));
        vDev_ADC.Read_ADC[0] = Get_ConversionVal(ADC_Buf[0]);
        Temperature[0] = uGetHeaterTemperature(ADC_CH8);
        sprintf(temp_D,"%d     ",Temperature[0] );
        printf("Temperature:%d\r\n", Temperature[0]);
        LCD_ShowString(30,140+16+16+16,"T=:",YELLOW,BLACK,32,0);        
        LCD_ShowString(100,140+16+16+16,temp_D,BRRED,BLACK,32,0);
        tos_task_delay(500);
    }
}

5、测量结果

通过串口示波器软件打印出来分析,与我们设计的温度曲线基本吻合。打印的图如下所示:

6、视频展示测试过程:

设备测试过程

三、开发总结

本次开发的TencentOS Tiny系统的最大优势在可以直接使用手上的硬件链接到腾讯云的工作。大大简化了开发的流程和工作量。只是对于之前只是做单片机开发的我来说,还是有难度的。因为之前连腾讯小程序都还没开发成功过。但是通钢这次的学习,发现了使用智能硬件联网并不是特别难的事情。后续将通过更多的学习,把单片机联网来开发。这样才能使自己不落后于这个时代。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、作品简介:
  • 二、软件开发过程
    • 1、软件环境
      • 2、基础例程测试:
        • 3、云端开发:
          • 4、温度检测程序实现
            • 5、测量结果
              • 6、视频展示测试过程:
              • 三、开发总结
              相关产品与服务
              物联网
              腾讯连连是腾讯云物联网全新商业品牌,它涵盖一站式物联网平台 IoT Explorer,连连官方微信小程序和配套的小程序 SDK、插件和开源 App,并整合腾讯云内优势产品能力,如大数据、音视频、AI等。同时,它打通腾讯系 C 端内容资源,如QQ音乐、微信支付、微保、微众银行、医疗健康等生态应用入口。提供覆盖“云-管-边-端”的物联网基础设施,面向“消费物联”和 “产业物联”两大赛道提供全方位的物联网产品和解决方案,助力企业高效实现数字化转型。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档