基于 SIM800 的时间、天气语音播报服务机器人

本文介绍了一个使用STM32F103C8T6单片机和SIM800模块,通过HTTP服务获取天气和时间数据,并利用SYN6288语音模块进行播报的项目。硬件包括STM32最小系统、SIM800、OLED显示和按键模块。软件部分涉及API接口、JSON数据解析和串口通信。
摘要由CSDN通过智能技术生成

系列文章目录

项目一 基于 SIM800 的时间、天气语音播报服务机器人
等待后续添加……



前言

移动蜂窝网络已经渗透到了我们生活的方方面面,无论是即时聊天、视频电视、亦或是移动支付都深度依赖移动蜂窝网络。

经过几十年的发展,移动蜂窝网从 1G 到 5G,让人们的生活方式得到了翻天覆地的改变。

该项目使用 2G 网络,实现一个能语言播报天气和时间的服务机器人。


一、总体设计方案

1. 硬件

在这里插入图片描述

  1. 主控:STM32F103C8T6;
  2. 通信模块:SIM800模块;
  3. 显示模块:0.96 寸 OLED12864 显示屏幕;
  4. 语音模块:SYN6288 串口文字转语音模块;
  5. 独立按键模块。

2. 软件

  1. SIM800 的 HTTP 服务从服务器获取天气和时间数据;
  2. 单片机串口将天气和时间数据通过文字的方式发送给 SYN6288 模块;
  3. 设计一个闹钟和定时器功能,可以通过按键设置;
  4. 显示屏显示时间和天气。

二、硬件设计

在这里插入图片描述
设计所使用的所有模块全部采用模块式组装,方便省事。

1. STM32F103C8T6 最小系统

现在的芯片贼贵,原来几块钱的单片机,现在要买到三四十块。

经费紧张的,STM32F103C8T6 可以考虑使用国产芯片代替。现在和 STM32 PIN to PIN 的国产芯片一大把,用来自己玩一下还是没问题的。

2. SIM800 模块

SIM800 是一款四频 GSM/GPRS 模块,为城堡孔封装。其性能稳定,外观小巧,性价比高,能满足客户的多种需求。SIM800 工作频率为GSM/GPRS850/900/1800/1900MHz,可以低功耗实现语音、SMS和数据信息的传输。SIM800 尺寸为17.615.72.3mm,能适用于各种紧凑型产品设计需求。

该模块需要配合 SIM 卡使用。不同厂家对 SIM800 模块的设计稍有区别,有的是自动复位,有的需要手动复位;SIM 的大小也有区别:有的使用小卡,有的是大卡。购买的时候要注意一下这些参数。

现在我们日常使用的卡大多数已经是 5G 网络了,最少也是 4G 的,但基本上都支持 2G,所以可以拿自己的手机卡来测试。不过网上也有很多纯 2G 卡卖,可以很方便买到。

3. SYN6288 语音模块

这个模块没什么好说的,直接拿串口发文字,就可以转换成语音了。中英文都是可以直接转换的。

唯一需要注意一下的是中文编码问题。这个模块支持 GB2312,GBK,Unicode 等不同中文编码,而你采用的编码跟编译器有关,这个使用的时候需要作为参数设置一下。

详细功能可以参考一下这篇文章:SYN6288语音合成模块介绍

数据手册:SYN6288 数据手册

4. OLED 显示模块

屏幕模块尺寸约为 0.96 英寸,主要由裸屏和底板PCB组成,裸屏由 SSD1306驱动,这也是一种较为广泛使用的 LED 驱动芯片。

驱动接口有 SPI 和 IIC 两种,本设计使用 IIC 驱动。

5. 按键模块

直接买了四合一的独立按键模块。不知道为什么这个模块没有上拉电阻,所以使用的使用要配置成 上拉输入


三、软件设计

1 时间天气服务API

网上免费的天气和时间服务接口很多,可以自己去找一下。我这里使用 NowAPI。使用方式也很简单,去官网注册一个账号,然后申请免费使用。使用时间只有三个月,我只用做测试是够了。高德天气服务好像是有长期免费的接口。
在这里插入图片描述
申请一个天气预报接口和一个标准北京时间接口。

这里附上我申请的接口(过期无效):
天气预报
北京时间
要是失效了就自己注册一个账号,申请 API 后会自动生成 AppKey 和 Sign,替换一下上面连接里面的 AppKey 和 Sign 就行了。

2 SIM800 HTTP 服务

天气预报和北京时间服务都是使用 HTTP 协议的,所以我们要获取服务器数据,就需求启动 SIM800 的 HTTP 服务。

SIM800 使用 串口+AT 指令控制,实际我们只用发送几个 AT 指令,就可以获取到服务器返回给我们的数据了。

/*
获取服务器数据
url 是服务 API
获取到的数据存在串口接收 BUFF 里面
*/
u8 sim900a_get_http(u8 *url)
{
   
	static u8 http_not_init = 1;
	u8 cmd[200];
	
	sprintf((char*)cmd, "AT+HTTPPARA=\"URL\",");
	strcat((char*)cmd, (char*)url);
	
	//if(sim900a_send_cmd((u8 *)"ATE0",(u8 *)"OK",100))			return SIM_CSQ_ERR;
	if(http_not_init)
	{
   
		http_not_init = 0;
		if(sim900a_send_cmd((u8 *)"AT+CSQ",(u8 *)"OK",100))		return SIM_CSQ_ERR;
		if(sim900a_send_cmd((u8 *)"AT+CREG?",(u8 *)"OK",100))	return SIM_CREQ_ERR;
		if(sim900a_send_cmd((u8 *)"AT+CSCA?",(u8 *)"OK",100))	return SIM_CSCA_ERR;
		if(sim900a_send_cmd((u8 *)"AT+CGATT?",(u8 *)"OK",100))	return SIM_CGATT_ERR;
		if(sim900a_send_cmd((u8 *)"AT+SAPBR=3,1,\"APN\",\"CMNET\"",(u8 *)"OK",100))	return SIM_SAPBR_ERR;
		if(sim900a_send_cmd((u8 *)"AT+SAPBR=1,1",(u8 *)"OK",1000))	return SIM_SAPBR_ERR;
		if(sim900a_send_cmd((u8 *)"AT+HTTPINIT",(u8 *)"OK",300))	return SIM_HTTPINIT_ERR;
	}
	if(sim900a_send_cmd(cmd,(u8 *)"OK",300));//	return SIM_CMGS_ERR;
	if(sim900a_send_cmd((u8 *)"AT+HTTPACTION=0",(u8 *)"+HTTPACTION: 0,200",2000))	return SIM_HTTPACTION_ERR;
	sim900a_send_cmd((u8 *)"AT+HTTPREAD",(u8 *)"OK",100);
	
	return SIM_OK;
}

//向sim900a发送命令
//cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
   
	u8 res=0; 
	USART2_RX_STA=0;USART2_RX_REC_ATCOMMAD=1;
	if((u32)cmd<=0XFF)
	{
   
		while(DMA1_Channel7->CNDTR!=0);	//等待通道7传输完成   
		USART2->DR=(u32)cmd;
	}else u2_printf("%s\r\n",cmd);//发送命令
	if(ack&&waittime)		//需要等待应答
	{
   
		while(--waittime)	//等待倒计时
		{
   
			delay_ms(10);
			if(USART2_RX_STA&0X8000)//接收到期待的应答结果
			{
   
				if(((USART2_RX_STA & 0x7FFF) > 200) && (strstr((const char*)USART2_RX_BUF,"{")))
				{
   
					memset(http_buff, 0, USART2_MAX_RECV_LEN);
					strcpy((char*)http_buff, (char*)USART2_RX_BUF); //大于200字节认为是http数据
				}
				if(sim900a_check_cmd(ack))break;//得到有效数据 
				USART2_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	USART2_RX_STA=0;USART2_RX_REC_ATCOMMAD=0;
	return res;
} 

/// 
//usmart支持部分 
//将收到的AT指令应答数据返回给电脑串口
//mode:0,不清零USART2_RX_STA;
//     1,清零USART2_RX_STA;
void sim_at_response(u8 mode)
{
   
	if(USART2_RX_STA&0X8000)		//接收到一次数据了
	{
    
		USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
		printf("%s"
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值