一,前言
这段时间接触到了一些蓝牙通信的设计,大多想要实现的功能是将单片机采集的一些数据显示到手机上,或者是想要用手机来控制外部设备,比如点灯,蜂鸣器报警,加湿,除湿,小车前进,后退,停止等等,如果想要用手机来控制单片机来进行工作的话,制作一款符合要求的App是必不可少的了,昨天和今天这两天时间里我在学习这个App Inventer制作App的过程,想把经验和大家分享一下。
二,设计要求
本次设计目的是采用STM32单片机将电池电压,电池电量和电量设定下限值显示在LCD1602上,通过STM32串口1将3个值发送至手机App上,如果电量小于设定下限阈值,单片机将控制发出声光报警。
三,部件设计
先给大家看下软件页面。
连接蓝牙为列表选择框,启用蓝牙后,点击连接蓝牙选择需要连接的蓝牙设备。
电池电压,电池电量,电量下限阈值为三个文本输入框,显示来自于单片机采集的数据。
部件列表如下图:
四,逻辑设计
个人感觉App Inventer写逻辑代码这部分还是比较人性化的,代码语句比较通俗易懂,把整个逻辑代码分享一下,如下图:
现在分析一下代码的逻辑。
第一部分是创建三个变量,分别为电池电压batteryVolt,电池容量batteryCap,设定电池容量下限阈值SetNum,用于存储接收来自单片机串口发送的数据,因为我使用了定时器用于1秒钟接收一次数据,在软件打开,屏幕初始化时,需将定时器关闭。
第二部分是选择需要连接的蓝牙设备,如上图连接蓝牙为列表选择框,显示蓝牙名称和地址,连接状态为文本框,用于显示是否连接成功。首先我们需要打开手机的蓝牙,这样软件才能开始搜索,如果没有开启手机蓝牙的话,软件将提示我们“蓝牙未启动”。如果蓝牙启动完成了,设置列表选择框中的列表选项为外部蓝牙设备的地址和名称,
第三部分当外部蓝牙设备选择完成后,将列表选择框中选中项(外部蓝牙设备)与手机的蓝牙进行连接 ,此时关闭列表选择框,连接状态文本提示“正在连接”,如果手机蓝牙与外部蓝牙设备连接成功,连接状态文本提示“连接成功“,此时开启定时器开始定时,如果没有连接成功,连接状态文本提示“连接失败”,将列表选择框打开,可以尝试重新选择连接。
以上定时器部分代码块是比较重要的部分,光这一部分客户端代码块还不够清晰,将设备串口部分代码再发一下。
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 r_buf;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE)==1) //接收中断
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
r_buf=USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
if(r_buf==1)//接收到数据为1
{
USART_SendData(USART1,num1&0x00ff);//发送电池容量数据低8位
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==0);//等待发送结束
USART_SendData(USART1,num1>>8);//发送电池容量数据高8位
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==0);//等待发送结束
}
else if(r_buf==2)//以下原理相同
{
USART_SendData(USART1,num2);//num2为电池容量值
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==0);
}
else if(r_buf==3)
{
USART_SendData(USART1,setNum);//发送电池容量设定值
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==0);
}
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
为了在对应框中显示正确的信息,建立起一一对应的关系,在接收数据之前先向设备端发送数据,通过蓝牙客户端发送数字1,2,3,发送1表示客户端想要接收电池电压数据,发送2表示客户端想要接收电池容量数据,发送3表示客户端想要接收设定电池容量下限阈值数据,当单片机接收到所对应的数字时,发送设备所采集的电压或电量或设定下限阈值,由于电池电压可能会带有小数部分,如果直接通过串口按8位发送,发送前单片机会对其进行取整,如果电压值为4.7V时,会直接按4V发送出去,客户端接收显示的数与实际值偏差有些大,所以在发送电池电压这部分代码上,我是将采集到的电池电压值放大100倍,放大100倍后,数据可能大于255(单片机通过串口发送,一次发送8位数据),就需要对数据进行两次发送,在客户端接收部分代码块中选择接收双字节无符号数字。
发送16位数据就要考虑是先发送高8位还是先发送低8位了,经过试验,蓝牙客户端接收双字节数据是先接收低8位的(比较重要!),所以在单片机进行发送时,先发送低8位,后发送高8位,客户端这边接受到双字节数据后,将数据乘以0.01然后显示至电池电压文本中,电池电量和设定下限阈值皆为8位数据,串口发送一次即可,客户端也只用接收一次,接收单字节无符号数字即可,定时器内部代码块1秒执行一次,实现不断更新数据。
五,总结
App Inventer软件的功能还是很强大的,软件设计与32单片机写串口两部分学到的东西挺多的,将设计的一些经验与大家分享,后面的旅途大家一起加油!