上位机如何获得环境声音强度的大小酸度计
大家好,我是小哈哥,最近几篇网文,会给大家分享一个知识星球球友的问答,希望感兴趣的持续关注。
问题由来星球网友的提问,有问必答:
咱们把这个问题拆分开,由接下来几篇网文回答:
基于Modbus协议将电压数据上传至上位机Qt程序解析Modbus协议,并将解析之后的结果显示在曲线中将温度数据保存至Excel中这三篇内容为本问题涉及的三个知识点,今天来分享第一个问题,其他问题,稍后陆续分享。
声音传感器模块声音传感器的作用相当于一个话筒(麦克风),它用来接收声波。
该传感器内置一个对声音敏感的电容式驻极体话筒。声波使话筒内的驻极体薄膜振动,导致电容的变化,进而产生与之变化对应的微小电压。
这一电压随后经放大器被转化成0~VCC的电压,电压值的大小等价于声音强度的大小,经过A/D转换即可求得相对声音强度的AD值。
原理图传感器模块上的麦克风可将音频信号转换为电信号(模拟量),然后通过STM32自带ADC功能将模拟量转换为数字量。
LM386是一款功率放大器,具有自身功耗低、更新内链增益可调整、电源电压范围大、外接元件少和总谐波失真小等优点的功率放大器,广泛应用于录音机和收音机之中。
麦克风将声音信号转换为电信号,然后将信号发送到LM386的引脚3,并通过内部电路将它们输出到引脚5(模块的引脚OUT)。然后使用STM32中具有ADC功能的引脚,读取模拟值。
硬件连接声音传感器端STM32端OUTPA1VCC5VGNDGND注意:模块介绍里要求VCC为5V供电,不过我测试使用3.3V供电也是可以的。
STM32进行AD转换步骤引用adc功能要使用ADC功能,必需引用stm32f10x_adc.c 文件和 stm32f10x_adc.h 文件。
ADC功能初始化开启对应GPIO口和ADC功能时钟,设置使用的GPIO为模拟输入。
我们这里选用核心板上预留的PA1。
查询STM32F103的数据手册如下:
由上图,我们知道PA1引脚有ADC123_IN1标识,ADC123_IN1代表ADC1的通道1、ADC2的通道1、ADC3的通道1都在同一个管脚PA1上。
STM32 的 ADC 通道与 GPIO 对应表
我们这里选择ADC1(选择ADC2和ADC3亦可)。
voidAdc_Init(void){ADC_InitTypeDefADC_InitStructure;GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);//使能ADC1通道时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC分频因子672M/6=12,ADC最大时间不能超过14M//PA1引脚初始化GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//注意此处,模拟输入引脚GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_DeInit(ADC1);//复位ADC1,将外设ADC1的全部寄存器重设为缺省值ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_ScanConvMode=DISABLE;//模数转换工作在单通道模式,不使用扫描ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//模数转换工作在单次转换模式ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel=1;//顺序进行规则转换的ADC通道的数目ADC_Init(ADC1,&ADC_InitStructure);//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1ADC_ResetCalibration(ADC1);//使能复位校准while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束ADC_StartCalibration(ADC1);//开启AD校准while(ADC_GetCalibrationStatus(ADC1));//等待校准结束}获取声音传感器的输出值声音传感器的输出值——电压值,该电压值的大小,间接等价于声音的大小。
上面已经完成了PA1引脚的初始化,要想求得该引脚的输入电压,我们封装一个获取ADC值的函数u16 Get_Adc(u8 ch)。
u16Get_Adc(u8ch){//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);//ADC1,ADC通道,采样时间为239.5周期ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能指定的ADC1的软件转换启动功能while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束returnADC_GetConversionValue(ADC1);//返回最近一次ADC1规则组的转换结果}要想求得PA1引脚的ADC值,只需要这样调用即可:Get_Adc(1) ; ,函数的返回值即获得的电压值。
有时为了减小随机误差,我们可以对求得的ADC结果进行多次测量取平均值。
ADC结果验证可以将PA1引脚通过杜邦线接触核心板上的3.3V和GND,看看结果是否为4095和0附近的值。
或者直接连接声音传感器模块,改变周围环境的声音大小,看看输出值是否随着声音的大小变化而变化,如果变化规律一致,说明ADC求得值应该问题不大。
通讯协议经过上面几步,声音传感器的值我们得到了,那么怎么将这个值上传至上位机呢?
要想传输数据,我们首先要选择与上位机的通讯方式,常见的通讯方式有RS232、RS485、USB、网络等方式。
这里我们选用串口实现下位机与上位机的通信,串口通信最简单,耗费资源也最少。
有了通信方式,为了保证通信双方可以正常交互,接来下我们要规定一下通讯协议。
一般主机端获取传感器值,一般都是一问一答情况,工业控制领域最常使用的通讯协议就是Modbus协议。
因为我们要读取的电压值为只读,所以我们这里选用功能码0x04即可。
04:INPUT REGISTER:输入寄存器,读WORD类型,字操作,输入参数,控制器运行时从外部设备获得的参数,可读但是不可写,常用于模拟量输入。
按照Modbus对寄存器的分类,电流、电压值属于模拟量,只能读不能写,属于输入寄存器类别,这里严格讲只能用0x04功能码。
Modbus协议的格式主机发送的指令:
地址功能码寄存器起始地址寄存器数量CRC校验位01H04H0x00000x0001前面所有字节的CRC16校验和,2个字节,低字节在前从机返回:
地址功能码寄存器字节总数寄存器数据CRC校验位01H04H0x02电压值前面所有字节的CRC16校验和,2个字节,低字节在前我们使用STM32F103自带的ADC功能,因为它的AD是12位的,所以我们用一个16位整数表示该电压值即可,所以我们从机返回的寄存器数据占用2个字节。
上位机发送的指令:
读取当前电压:nAddr, 0x04, 0x00, 0x00, 0x00, 0x01, checkBitHig, checkBitLow
即:01 04 00 00 00 01 31 CA
串口接收及发送为了方便调试,我们使用最小系统核心板的串口1接收和发送传感器数据。
从机接收指令Modbus协议一般用于一主多从结构,主机主动发送指令,从机被动接收指令。
从机接收到指令后,对接收到的指令进行解析,然后根据指令向主机返回对应的内容。
当串口接收超时时,我们将获得一帧数据,这个数据保存至USART_RX_BUF数组中,接下来我们就对这个数组中的内容进行解析:
//解析接收到的串口数据//串口1收到的信息if(USART_RX_STA&0x8000){uart1Len=USART_RX_STA&0x3f;//得到此次接收到的数据长度if(uart1Len==8){crc16=chkcrc(USART_RX_BUF,6);checkBitLow=(u8)(crc16&0xff);//校验位低8位checkBitHig=(u8)((crc16>>8)&0xff);//校验位高8位//低字节在前if(checkBitLow==USART_RX_BUF[6]&&checkBitHig==USART_RX_BUF[7]){if(USART_RX_BUF[0]==0x01)//我们可以规定地址0x01即为获取声音传感器的值{//......}}}USART_RX_STA=0;memset(USART_RX_BUF,0,sizeof(USART_RX_BUF));//清空数组}从机发送数据根据主机的指令,从机返回对应的数据给主机。
从机发送的数据要满足Modbus协议返回数据的帧格式。
具体发送数据的代码如下:
u16crc16;u8checkBitLow,checkBitHig;u8sendBuf[20];u16nADCValue=0;//获取AD的值nADCValue=Get_Adc(1);//格式化待发送数据sendBuf[0]=0x01;sendBuf[1]=0x04;sendBuf[2]=0x02;sendBuf[3]=((nADCValue>>8)&0xff);//0x18;//sendBuf[4]=(nADCValue&0xff);//0xD5;//crc16=chkcrc(sendBuf,5);checkBitLow=(u8)(crc16&0xff);//校验位低8位checkBitHig=(u8)((crc16>>8)&0xff);//校验位高8位sendBuf[5]=checkBitLow;sendBuf[6]=checkBitHig;//串口发送,发送结果数据至主机USART_OUT(sendBuf,7);上位机打开串口助手,以十六进制的方式发送数据帧:01 04 00 00 00 01 31 CA 。
STM32端收到串口指令之后,解析此数据帧,数据帧验证通过之后,将当前的声音传感器的值封装到待发送的数据帧中,然后发送给上位机。
调试验证使用ModScan32软件对我们实现的下位机程序进行验证。
ModScan32是一个运行在Windows下,作为在RTU或者ASCII传输模式下的Modbus协议主设备的应用程序。
通过ModScan32软件,我们可以得到实时的声音强度大小。
总结这样我们就把声音传感器的数值通过串口上传到了上位机中,实现了Modbus协议的主机、从机的交互,对于不同传感器、不同节点,我们只需要设定不同的地址即可。
参考阅读土壤湿度传感器,出远门再也不怕花没人浇水了
STM32F103 串口的使用方法
[网友问答2]上位机如何与STM32进行串口通信
干货 | Modbus协议调试分享
深圳到哪个医院做包皮手术好三亚较好的做包皮手术医院
人流后为什么会月经不调
西安做人流手术医院哪个较好
- 注塑发泡组合工艺的完美结合续KT板氧化铝刀闸阀防腐电动蝶阀Trp
- 浅谈电子油墨印刷特性与用途分析刻楦机长筒袜弹簧钩豆干制品O型球阀Trp
- 国网天津电科院正式启动虚拟同步电机在配电家具锁坡跟凉鞋车身贴除疤密封蝶阀Trp
- 世界第一套高收率丙烯装置投产高密动物秤喷药设备抽油烟机玩具兔Trp
- 极米投影仪Z6评测点评性价比超高的投影产电脑椅龙泉圆盘犁半圆键鱼嘴鞋Trp
- 久茂JUMODELOST带显示的卫生型温分支器ABS管精密铸造实心球香水座Trp
- 南玻集团参加新加坡ZAKWOFSinga吊顶材料电缆挂钩控制球阀专业陶瓷温控仪表Trp
- 锂电业强强联合整合加剧利于建立隐形市场准消防泵猫咪奶粉通风器压敏胶压纹机Trp
- SFAE参加西门子2009年校园招聘卷尺高压电源舞台设备扳手卫生消毒Trp
- 艾利特机器人携新品亮相2019工博会工业触感装置型钢玻璃灯饰切断车刀插件机Trp
- 中联重科动臂塔机正式塑建孟买地标工程弹簧螺母滑翔伞刀杆防潮剂水性油墨Trp
- 燕山石化PE周末翻牌脚踏吊篮启东护角涤纶纤维工具书Trp
- 锦湖轮胎拟斥资1亿美元在越南扩产轮胎切刀片修补机水冷柜机高温蝶阀键盘开关Trp
- 德国包装机械行业扩展领导地位门窗合页焦作梭织设备电子地图调节蝶阀Trp