JQ8900语音模块+光照传感器+4G模块数据上传阿里云物联网
- 硬件设计
- 4G模块
- 语音模块(JQ8900)
- 光照传感器和一氧化碳传感器
- 阿里云物联网
硬件设计
原理图
PCB
实物图
4G模块
选用EC200U模块,集成4g和GPS以及蓝牙功能
通过串口2与4G模块串口连接,串口传输数据指令。
第一个命令 Uart2_SendStr("ATE1\r\n"); 获取模块的版本 Uart2_SendStr("ATI\r\n"); 获取卡号,类似是否存在卡的意思 Uart2_SendStr("AT+CIMI\r\n"); 查询激活状态 Uart2_SendStr("AT+CGATT?\r\n"); 查看获取CSQ值 Uart2_SendStr("AT+CSQ\r\n");
这个时候4g模块已经成功启动,下一步注册进阿里云物联网平台
关闭当前的连接,保证这次的使用 Uart2_SendStr("AT+QMTDISC=0\r\n"); 发送阿里云的配置参数(设备三要素) sprintf(ATSTR,"AT+QMTCFG=\"ALIAUTH\",0,\"%s\",\"%s\",\"%s\"\r\n" ,PRODUCEKEY,DEVICENAME,DEVICESECRET); 登录阿里云平台 Uart2_SendStr("AT+QMTOPEN=0, \"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883\r\n"); 发送链接到阿里云 sprintf(ATSTR,"AT+QMTCONN=0,\"%s\"\r\n",DEVICENAME); Uart2_SendStr(ATSTR);
然后就是上发数据给阿里云平台
发送命令 sprintf(ATSTR,"AT+QMTPUB=0,0,0,0,\"/sys/%s/%s/thing/event/property/post\"\r\n",PRODUCEKEY,DEVICENAME); Uart2_SendStr(ATSTR); 再组建CJSON数据,自己定义编写就行了 json[]="{\"id\":\"123\",\"version\":\"1.0\",\"params\": {\"adc1\":{\"value\":%d},\"adc2\": {\"value\":%d},\"GeoLocation\":{ \"value\": {\"Latitude\":%s,\"Longitude\":%s,\"Altitude\":39.9935723,\"CoordinateSystem\":2}}},\"method\":\"thing.event.property.post\"}"; 再发送 Uart2_SendStr((char *)send_json);
上发了之后阿里云就可以收到这些数据
语音模块(JQ8900)
根据厂家提供的手册资料,可以知道这款芯片可以有多种触发方式。根据手册上的内容以及商家提供的语音合成软件,把语音载入进去,按照特定的方式播放出来。
用一线串口触发的方式就体现了读取芯片数据的协议
/******************************************************* 功能描述: 单线控制单字节发送函数 入口参数: DATA:发送数据 返 回 值: none 其他说明: 将需要发送的数据作为形参传入 *******************************************************/ void OneLine_SendData(uint8_t DATA) { uint8_t i; JQ8x00_VPP_Set(); //开始信号 JQ8x00_us(100); JQ8x00_VPP_Clr(); JQ8x00_ms(3); for(i=0;i JQ8x00_VPP_Set(); if(DATA & 0x01) { JQ8x00_us(1500); JQ8x00_VPP_Clr(); JQ8x00_us(500); } else { JQ8x00_us(500); JQ8x00_VPP_Clr(); JQ8x00_us(1500); } DATA >= 1; } JQ8x00_VPP_Set(); }
光照传感器和一氧化碳传感器
这两款传感器都是可以输出模拟信号,所以我们只需要用单片机的AD转换功能就可以读取到这些传感器的数据。
void Adc_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1) == SET); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1) == SET); } //获得ADC值 //ch:通道值 0~3 u16 Get_Adc(u8 ch) { //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //使能 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //等待转换结束 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); //返回最近一次ADC1规则组的转换结果 return ADC_GetConversionValue(ADC1); } //计算ADC采集的数据 第二个参数是采集多少次 最后算平均值 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times; }