这次期末的课程设计做了一个智能灯光控制系统,系统整体的功能不在此赘述,系统主要是要实现下位机同上位机的通信,上位机选用的是android手机端,下位机是52单片机,通过蓝牙模块实现通信。虽然系统很简单,但还是第一次完成的走完从下位机数据采集,数据传输,再到上位机的处理这个流程,故在这里做一个记录,也希望能够帮到有需要的人。
一、下位机通信
下位机选用的是52单片机,数据来自几个传感器,传感器采集到数据后通过串口发送到蓝牙模块,然后蓝牙模块发送到上位机。因代码量较大,所以只在这里贴出传输有关的函数。
//利用串口发送一个字符void sendonebyte(unsigned char c) {
sbuf = c;
while(!ti);
ti = 0;}//重写putchar函数,就可以直接调用printf()函数向串口发送数据,程序自动将printf()中的数据转换成char调用putchar发送char putchar(char ch) { es=0; sbuf=ch; while(!ti); ti=0; es=1; return 0;}//初始化串口void inituart() { tmod = 0x20; pcon = 0x00; scon = 0x50;
th1 = 0xfd; tl1 = 0xfd; tr1 = 1; es = 1; ea = 1;}//串口中断void uartinterrupt() interrupt 4{
//ri为1则表示串口接收到数据
if(ri)
{
ri = 0;
r_buf = sbuf; //价格sbuf中的数据赋给r_buf,然后就可以对数据进行处理
}}void main(){ inituart(); while(1) { }}
二、蓝牙模块
蓝牙模块我选用的是hc-05,这个模块我之前也没用使用过,查询了一些资料后就能够上手了,感觉还是很好用。模块有六个引脚,如果用的是带一个小按钮的hc-05,en就不用接;然后vcc和gnd分别接电源和地;txd 和 rxd在配置at指令的时候分别接单片机的txd和rxd,但是在正常使用时,hc-05的txd和rxd分别接单片机的rxd和txd,这个需要注意;还有一个引脚是state,当有蓝牙连接的时候会置1,将其随意连接到单片机的引脚上。
使用前先利用at指令集配置模块,设置波特率和主从模式等,然后就可以连线使用。连接后蓝牙模块会进入快闪模式,进入at指令集后会进入慢闪模式,当有蓝牙设备连接后会进入双闪模式。
三、android端程序
android端主要就是接受数据,做出一定处理,还需发送指令给单片机。我用的代码也是在网上找的然后又做了一些修改,源代码出处找不到了。主要代码如下:
1、deveicelistactivity类
public class devicelistactivity extends activity {
// 调试用
private static final string tag = devicelistactivity;
private static final boolean d = true;
// 返回时数据标签
public static string extra_device_address = 设备地址;
// 成员域
private bluetoothadapter mbtadapter;
private arrayadapter mpaireddevicesarrayadapter;
private arrayadapter mnewdevicesarrayadapter;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
// 创建并显示窗口
requestwindowfeature(window.feature_indeterminate_progress); //设置窗口显示模式为窗口方式
setcontentview(r.layout.device_list);
// 设定默认返回值为取消
setresult(activity.result_canceled);
// 设定扫描按键响应
button scanbutton = (button) findviewbyid(r.id.button_scan);
scanbutton.setonclicklistener(new onclicklistener() {
public void onclick(view v) {
dodiscovery();
v.setvisibility(view.gone);
}
});
// 初使化设备存储数组
mpaireddevicesarrayadapter = new arrayadapter(this, r.layout.device_name);
mnewdevicesarrayadapter = new arrayadapter(this, r.layout.device_name);
// 设置已配队设备列表
listview pairedlistview = (listview) findviewbyid(r.id.paired_devices);
pairedlistview.setadapter(mpaireddevicesarrayadapter);
pairedlistview.setonitemclicklistener(mdeviceclicklistener);
// 设置新查找设备列表
listview newdeviceslistview = (listview) findviewbyid(r.id.new_devices);
newdeviceslistview.setadapter(mnewdevicesarrayadapter);
newdeviceslistview.setonitemclicklistener(mdeviceclicklistener);
// 注册接收查找到设备action接收器
intentfilter filter = new intentfilter(bluetoothdevice.action_found);
this.registerreceiver(mreceiver, filter);
// 注册查找结束action接收器
filter = new intentfilter(bluetoothadapter.action_discovery_finished);
this.registerreceiver(mreceiver, filter);
// 得到本地蓝牙
mbtadapter = bluetoothadapter.getdefaultadapter();
}
@override
protected void ondestroy() {
super.ondestroy();
// 关闭服务查找
if (mbtadapter != null) {
mbtadapter.canceldiscovery();
}
// 注销action接收器
this.unregisterreceiver(mreceiver);
}
public void oncancel(view v){
finish();
}
/**
* 开始服务和设备查找
*/
private void dodiscovery() {
if (d)
log.d(tag, dodiscovery());
// 在窗口显示查找中信息
setprogressbarindeterminatevisibility(true);
settitle(查找设备中...);
// 显示其它设备(未配对设备)列表
findviewbyid(r.id.title_new_devices).setvisibility(view.visible);
// 关闭再进行的服务查找
if (mbtadapter.isdiscovering()) {
mbtadapter.canceldiscovery();
}
//并重新开始
mbtadapter.startdiscovery();
}
// 选择设备响应函数
private onitemclicklistener mdeviceclicklistener = new onitemclicklistener() {
public void onitemclick(adapterview av, view v, int arg2, long arg3) {
// 准备连接设备,关闭服务查找
mbtadapter.canceldiscovery();
// 得到mac地址
string info = ((textview) v).gettext().tostring();
string address = info.substring(info.length() - 17);
// 设置返回数据
intent intent = new intent();
intent.putextra(extra_device_address, address);
// 设置返回值并结束程序
setresult(activity.result_ok, intent);
finish();
}
};
// 查找到设备和搜索完成action监听器
private final broadcastreceiver mreceiver = new broadcastreceiver() {
@override
public void onreceive(context context, intent intent) {
string action = intent.getaction();
// 查找到设备action
if (bluetoothdevice.action_found.equals(action)) {
// 得到蓝牙设备
bluetoothdevice device = intent.getparcelableextra(bluetoothdevice.extra_device);
// 如果是已配对的则略过,已得到显示,其余的在添加到列表中进行显示
if (device.getbondstate() != bluetoothdevice.bond_bonded) {
mnewdevicesarrayadapter.add(device.getname() + \n + device.getaddress());
}else{ //添加到已配对设备列表
mpaireddevicesarrayadapter.add(device.getname() + \n + device.getaddress());
}
// 搜索完成action
} else if (bluetoothadapter.action_discovery_finished.equals(action)) {
setprogressbarindeterminatevisibility(false);
settitle(选择要连接的设备);
if (mnewdevicesarrayadapter.getcount() == 0) {
string nodevices = 没有找到新设备;
mnewdevicesarrayadapter.add(nodevices);
}
}
}
};}
2、client类
public class btclient extends activity {
private final static int request_connect_device = 1; //宏定义查询设备句柄
private final static string my_uuid = 00001101-0000-1000-8000-00805f9b34fb; //spp服务uuid号
private inputstream is; //输入流,用来接收蓝牙数据
private edittext edit0; //发送数据输入句柄
private textview lightswitch;
private textview lightstrength;
private textview lightmode;
private textview lightpower;
private string switchmsg= ;
private string strengthmsg= ;
private string modemsg= ;
bluetoothdevice _device = null;
//蓝牙设备
bluetoothsocket _socket = null;
//蓝牙通信socket
boolean brun = true;
boolean bthread = false;
boolean timesign=false;
private bluetoothadapter _bluetooth = bluetoothadapter.getdefaultadapter(); //获取本地蓝牙适配器,即蓝牙设备
/** called when the activity is first created. */
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.main); //设置画面为主画面 main.xml
edit0 = (edittext)findviewbyid(r.id.edit0); //得到输入框句柄
lightswitch = (textview) findviewbyid(r.id.lightswitch);
lightstrength=(textview) findviewbyid(r.id.lightstrength);
lightmode=(textview) findviewbyid(r.id.lightmode);
lightpower=(textview) findviewbyid(r.id.lightpower);
lightswitch.settext(关闭);
lightstrength.settext(8);
lightmode.settext(时间调节模式);
lightpower.settext(无数据);
//如果打开本地蓝牙设备不成功,提示信息,结束程序
if (_bluetooth == null){
toast.maketext(this, 无法打开手机蓝牙,请确认手机是否有蓝牙功能!, toast.length_long).show();
finish();
return;
}
// 设置设备可以被搜索
new thread(){
public void run(){
if(_bluetooth.isenabled()==false)
{
_bluetooth.enable();
}
}
}.start();
}
//发送按键响应
public void onsendbuttonclicked(view v){
try{
outputstream os = _socket.getoutputstream(); //蓝牙连接输出流
modemsg=edit0.gettext().tostring();
if(modemsg.equals(1)||modemsg.equals(2)||modemsg.equals(3))
{
if(modemsg.equals(1)) {
lightmode.settext(手动调节模式);
lightpower.settext(无数据);
timesign=false;
}
else if(modemsg.equals(2)) {
lightmode.settext(自动调节模式);
timesign=false;
}
else if(modemsg.equals(3)) {
lightmode.settext(时间调节模式);
lightpower.settext(无数据);
}
}
if(timesign)
{
final int timec = integer.valueof(modemsg).intvalue() * 1000;//
countdowntimer cdt = new countdowntimer(timec, timec) {//
@override//
public void ontick(long millisuntilfinished) {//
}////
@override//
public void onfinish() {//
edit0.settext(3);//
}//
};//
cdt.start();
try{
thread.currentthread().sleep(timec);
} catch (interruptedexception e) {
e.printstacktrace();
}
edit0.settext(3);
}
if(modemsg.equals(3)&& !timesign)
timesign=true;
byte[] bos = edit0.gettext().tostring().getbytes();
edit0.settext();
os.write(bos);
}catch(ioexception e){
}
}
//接收活动结果,响应startactivityforresult()
public void onactivityresult(int requestcode, int resultcode, intent data) {
switch(requestcode){
case request_connect_device:
//连接结果,由devicelistactivity设置返回
// 响应返回结果
if (resultcode == activity.result_ok) { //连接成功,由devicelistactivity设置返回
// mac地址,由devicelistactivity设置返回
string address = data.getextras()
.getstring(devicelistactivity.extra_device_address);
// 得到蓝牙设备
_device = _bluetooth.getremotedevice(address);
// 用服务号得到socket
try{
_socket = _device.createrfcommsockettoservicerecord(uuid.fromstring(my_uuid));
}catch(ioexception e){
toast.maketext(this, 连接失败!, toast.length_short).show();
}
//连接socket
button btn = (button) findviewbyid(r.id.button03);
try{
_socket.connect();
toast.maketext(this, 连接+_device.getname()+成功!, toast.length_short).show();
btn.settext(断开);
}catch(ioexception e){
try{
toast.maketext(this, 连接失败!, toast.length_short).show();
_socket.close();
_socket = null;
}catch(ioexception ee){
toast.maketext(this, 连接失败!, toast.length_short).show();
}
return;
}
//打开接收线程
try{
is = _socket.getinputstream(); //得到蓝牙数据输入流
}catch(ioexception e){
toast.maketext(this, 接收数据失败!, toast.length_short).show();
return;
}
if(bthread==false){
readthread.start();
bthread=true;
}else{
brun = true;
}
}
break;
default:break;
}
}
//接收数据线程
thread readthread=new thread(){
public void run(){
int num = 0;
byte[] buffer = new byte[1024];
brun = true;
//接收线程
while(true){
try{
while(is.available()==0){
while(brun == false){}
}
while(true){
num = is.read(buffer);
//读入数据
string s=new string(buffer,0,num);
switchmsg=s;
strengthmsg=s;
if(is.available()==0)break; //短时间没有数据才跳出进行显示
}
//发送显示消息,进行显示刷新
handler.sendmessage(handler.obtainmessage());
}catch(ioexception e){
}
}
}
};
//消息处理队列
handler handler= new handler(){
public void handlemessage(message msg){
super.handlemessage(msg);
}
};
//关闭程序掉用处理部分
public void ondestroy(){
super.ondestroy();
if(_socket!=null) //关闭连接socket
try{
_socket.close();
}catch(ioexception e){}
}
//连接按键响应函数
public void onconnectbuttonclicked(view v){
if(_bluetooth.isenabled()==false){ //如果蓝牙服务不可用则提示
toast.maketext(this, 打开蓝牙中..., toast.length_long).show();
return;
}
//如未连接设备则打开devicelistactivity进行设备搜索
button btn = (button) findviewbyid(r.id.button03);
if(_socket==null){
intent serverintent = new intent(this, devicelistactivity.class); //跳转程序设置
startactivityforresult(serverintent, request_connect_device); //设置返回宏定义
}
else{
try{
//关闭连接socket
_socket.close();
is.close();
_socket = null;
brun = false;
btn.settext(连接);
}catch(ioexception e){}
}
return;
}
//退出按键响应函数
public void onquitbuttonclicked(view v){
finish();
}}
一文看懂自动驾驶商业化落地场景
马克思发生器原理图
俄罗斯或对使用西方卫星互联网服务的公民等罚款
中兴员工发声:华为仅部分芯片自己设计,被美制裁一样得“死”
土壤湿度测量器电路
Android端 同 单片机 利用蓝牙模块的通信实现
2021中国智能传感器产业大会在青岛市香格里拉酒店隆重开幕
虚拟现实的技术创新为文旅应用提供了可能性
PD5系列测距仪
led恒流驱动电源原理
博世集团与cellcentric签订了长期协议为其供应集成功率电子
dfrobotMCP3424 18位AD转换模块介绍
打造开发者社区,涛思数据开源 TDengine物联网大数据平台
华为绝不仅是手机和5G的提供者
变频器和节电器有什么区别
西门子联合贝思科尔在3月和4月举办网络研讨会
示波器探头使用注意事项,示波器探头的选择
高频导体的电流分布
5G是推动经济高质量发展的重要支撑
什么是paas平台_paas逻辑架构图