树莓派之蓝牙编程

news/2024/10/17 14:19:10/

一、蓝牙配置及与手机通信

1、蓝牙介绍

(1)四种基本蓝牙profile
1. GAP Profile: Generic Access Profile,该Profile保证不同的Bluetooth产品可以互相发现对方并建立连接。 

2.SDAP Profile: Service Discovery Application Profile,通过该Profile,一个Bluetooth设备可以找到其它Bluetooth设备提供的服务,以及查询相关的信息。

3.SPP Profile: Serial Port Profile,模拟串口通讯。

4.GOEP Profile: Generic Object Exchange Profile,通用对象交换。这个Profile的名字有些费解,它定义的是数据的传输,包括同步,文件传输,或者推送其它的数据。你可以把它理解为内容无关的传输层协议,可以被任何应用用来传输自己定义的数据对象.

(2)九种应用协议(usage profile)
1.CTP Profile: Cordless Telephone Profile,无绳电话。 
2.IP Profile: Intercom Profile,这是在两个设备之间建立语音连接,换句话说,把两个昂贵的兰牙设备变成廉价的对讲机。
3. HS Profile: HeadSet Profile,用于连接耳机。  
4.DNP Profile: Dial-up Networking Profile,用于为PC提供拨号网络功能。 
5.FP Profile: Fax Profile,传真功能。 
6.LAP Profile: LAN Access Profile,使用PPP协议建立局域网。
7.OPP Profile: Object Push Profile,用于设备之间传输数据对象。 
8.FTP Profile: File Transfer Profile,用于文件传输。  
9.SP Profile: Synchronization Profile,用于不同的Bluetooth设备同步,保持数据的一致性

2、安装蓝牙相关软件包

sudo apt-get install pi-bluetooth bluez bluez-firmware blueman

3、添加pi用户到蓝牙组

sudo usermod -G bluetooth -a pi
sudo reboot
之后蓝牙可以使用

4、开启蓝牙设备

sudo vi /etc/systemd/system/dbus-org.bluez.service


修改文件中这两个语句(要根据自己的路径修改)

重启树莓派,输入hciconfig(类似ifconfig)命令查看蓝牙服务

5、查看适配器提供的各种功能

sudo sdptool browse local

6、等待连接

通过hciconfig看到我们的本地的设备是hci0,运行一下命令等待连接
sudo rfcomm watch hci0

让手机能够搜到我们的蓝牙
法1:点击Make Discoverable
这里写图片描述

法2:运行sudo hciconfig hci0 piscan

7、手机串口软件连接

这里写图片描述

手机连接上后ls /dev可以看到rfcomm0
这里写图片描述
只有在有蓝牙连接上去的时候才有这个设备

8、手机树莓派通信

  1. 树莓派上安装minicom–>设置串口为rfcomm0
  2. 手机上打开蓝牙串口,即可通信
    这里写图片描述
    这里写图片描述

参考网页:http://blog.csdn.net/wanyeye/article/details/52909869
https://www.raspberrypi.org/forums/viewtopic.php?p=919420
https://jasiek.me/2014/10/04/bluetooth-console-on-a-raspberry-pi-using-a-usb-adapter.html

9、绑定设备号 到某个MAC和channel上

创建设备节点:mknod /dev/rfcomm0 c 216 0
216是RFCOMM的设备号,可以参考…./bluez-utils-2.x/scripts/create_dev脚本
绑定:rfcomm bind /dev/rfcomm0 [MAC] [channel]
解除绑定:rfcomm release /dev/rfcomm0
查看绑定:rfcomm show /dev/rfcomm0

二、应用编程

1. 蓝牙串口操作所需要的头文件

 #include     <stdio.h>      /*标准输入输出定义*/  #include     <stdlib.h>     /*标准函数库定义*/  #include     <unistd.h>     /*Unix 标准函数定义*/  #include     <sys/types.h>    #include     <sys/stat.h>     #include     <fcntl.h>      /*文件控制定义*/  #include     <termios.h>    /*PPSIX 终端控制定义*/  #include     <errno.h>      /*错误号定义*/  

2.打开蓝牙串口

例如:fd = open( “/dev/rfcomm0 “, O_RDWR | O_NOCTTY | O_NDELAY);
标志O_NOCTTY可以告诉UNIX这个程序不会成为这个端口上的“控制终端”.如果不这样做的话,所有的输入,比如键盘上过来的Ctrl+C中止信号等等,会影响到你的进程.而有些程序比如getty(1M/8)则会在打开登录进程的时候使用这个特性,但是通常情况下,用户程序不会使用这个行为.
O_NDELAY标志则是告诉UNIX,这个程序并不关心DCD信号线的状态——也就是不关心端口另一端是否已经连接.如果不指定这个标志的话,除非DCD信号线上有space电压否则这个程序会一直睡眠.

3.设置蓝牙串口

波特率设置

struct termios options;
/** Get the current options for the port...*/
tcgetattr(fd, &options);
/** Set the baud rates to 19200...*/
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);/** Enable the receiver and set local mode...*/
options.c_cflag |= (CLOCAL | CREAD);/** Set the new options for the port...*/
tcsetattr(fd, TCSANOW, &options);

设置字符大小

设置字符大小的时候,这里却没有像设置波特率那么方便的函数.所以,程序中需要一些位掩码运算来把事情搞定.字符大小以比特为单位指定:
options.c_flag &= ~CSIZE; / * Mask the character size bits */
options.c_flag |= CS8; /* Select 8 data bits */

设置奇偶校验和停止位

  • No parity (8N1)
    options.c_cflag &= ~PARENB
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
  • Even parity (7E1)
    options.c_cflag |= PARENB
    options.c_cflag &= ~PARODD
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS7;
  • Odd parity (7O1)
    options.c_cflag |= PARENB
    options.c_cflag |= PARODD
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS7;
  • Space parity is setup the same as no parity (7S1)
    options.c_cflag &= ~PARENB
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

设置输入输出

如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,那么使用原始模式(Raw Mode)方式来通讯,设置方式如下:
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/

经典输入是以面向行设计的.在经典输入模式中输入字符会被放入一个缓冲之中,这样可以以与用户交互的方式编辑缓冲的内容,直到收到CR(carriage return)或者LF(line feed)字符.
选择使用经典输入模式的时候,你通常需要选择ICANON,ECHO和ECHOE选项:
options.c_lflag |= (ICANON | ECHO | ECHOE);

通过在c_oflag成员变量中设置OPOST选项的方法程序可以选择加工过的输出.
options.c_oflag |= OPOST;
在所有选项当中,你可能只需要使用ONLCR选项来将行分隔符映射到CR-LF组合对上.其他选项主要是历史遗留,仅仅与行打印机和终端跟不上串行数据的年代有关.

设置硬件流控制

某些版本的UNIX系统支持通过CTS(Clear To Send)和RTS(Request To Send)信号线来设置硬件流控制.如果系统上定义了CNEW_RTSCTS和CRTSCTS常量,那么很可能它会支持硬件流控制.使用下面的方法将硬件流控制设置成有效:
options.c_cflag |= CNEW_RTSCTS;
将它设置成为无效的方法与此类似:
options.c_cflag &= ~CNEW_RTSCTS;

4.读写串口

发送数据

char  buffer[1024];    
int    Length;  
int    nByte;  
nByte = write(fd, buffer ,Length)     

读取数据

char  buff[1024];  
int    Len;  
int  readByte = read(fd,buff,Len);  

使用文件操作read函数读取,如果设置为原始数据模式(Raw Date Mode)传输数据,那么read函数返回的字符数是实际串口收到的字符数,也就是返回从串口输入缓冲区中实际得到的字符的个数.在不能得到数据的情况下,read(2)系统调用就会一直等着,只到有端口上新的字符可以读取或者发生超时或者错误的情况发生.
如果需要read(2)函数迅速返回的话,可以使用操作文件的函数来实现异步读取,如fcntl,或者select等来操作 。
fcntl(fd, F_SETFL, FNDELAY);
标志FNDELAY可以保证read(2)函数在端口上读不到字符的时候返回0.需要回到正常(阻塞)模式的时候,需要再次在不带FNDELAY标志的情况下调用fcntl(2)函数:
fcntl(fd, F_SETFL, 0);
当然,如果你最初就是以O_NDELAY标志打开串口的,你也可在之后使用这个方法改变读取的行为方式.

5.关闭串口

close(fd);


http://www.ppmy.cn/news/662949.html

相关文章

树莓派跑一个简单c++小程序教程

我用的是树莓派3代b型&#xff0c;所使用的是Debian系统的衍生系统raspbian(对系统不太了解不清楚)。树莓派开发c程序需要的工具有编辑器vim,调试器gdb,编译器gcc或者g.&#xff08;大神飘过就行~~ 记录一下&#xff09;用红笔涂得地方是我命令敲错的地方&#xff0c;大家忽略就…

年轻人的第一个开发板——树莓派

目录 开始玩树莓派我们需要准备什么硬件准备安装树莓派系统到SD卡配置树莓派Raspberry debian9&#xff1a;Ubuntu-server 18.04 前言 本来作为一个只要敲敲代码的程序猿&#xff0c;是不会接触单片机这种硬件的&#xff0c;一个偶然的机会宿舍的路由器坏了&#xff0c;只能刷机…

树莓派的linux可以编程吗,解答树莓派上用什么编程

描述 树莓派&#xff0c;英文为Raspberry Pi&#xff0c;也会被缩写称之为RPi&#xff0c;是一种只有扑克牌大写的为计算机编程教育而设计的微型计算机&#xff0c;其系统基于Linux。 树莓派的创造者想让更多小孩学会编程&#xff0c;去用电脑实现自己有趣的想法。本来打算只让…

分享一下自己玩树莓派的心得

树莓派嘛,玩ROS的接触还是很深的!没啥别的原因,便宜!相比其他的,树莓派的性价比算是相当高的! 记得前几年玩树莓派的时候,第一个接触到的树莓派系统是Ubuntu Mate,那时候还是树莓派3B,古月老师的课程刚出。 我的Linux系统学习,就是从玩树莓派开始。很多初学者觉得ROS…

树莓派瞎玩~5~控制GPIO之Python

树莓派瞎玩~5~控制GPIO之Python 控制GPIO输出读取GPIO引脚的状态轮询读取GPIO引脚的状态中断 在Raspbian中已经预装了Python2.7.9&#xff0c;直接在命令行输入python即可看到如下信息 piraspberrypi:~ $ python Python 2.7.9 (default, Mar 8 2015, 00:52:26) [GCC 4.9.2] o…

DIY树莓派Raspberry Pi

以前&#xff0c;登录公司的linux服务器时&#xff0c;经常受限于各种权限问题&#xff0c;甚至连服务器长什么样都不知道。 之后&#xff0c;经常用ssh/串口/adb登录公司的linux/android设备。还用adb/usb登录过自己的小米手机&#xff0c;远程操作手机。 后来&#xff0c;在W…

[玩转树莓派]树莓派配置成路由器

现在手头上正好有一个树莓派3b的板子&#xff0c;想折腾一下&#xff0c;用树莓派搞个简单的路由器玩玩。 树莓派3B / 4B板载了无线网络适配器&#xff0c;不需要额外增加无线网卡就可以把它打造成一个无线路由器。有一种方法是给树莓派刷上OpenWRT等路由器固件&#xff0c;这…

Arduino与树莓派:到底该选择哪个?

的人来说&#xff0c;它们可能看起来非常类似&#xff1a;它们都是带有电阻、电容的电路板&#xff0c;ICU焊接在顶部&#xff0c;接口从侧面引出。 然而&#xff0c;如果我们仔细看一看的话&#xff0c;Arduino和树莓派在架构和设计目的上各有不同。我们编写了本篇文章以阐明…