微雪官网产品资料
立即注册 找回密码

QQ登录

只需一步,快速开始

微雪课堂

搜索
微雪课堂 首页 智能车 查看内容

树莓派智能车AlphaBot教程12:蓝牙控制

2017-5-3 12:04| 发布者: kaloha| 查看: 6964| 评论: 0|原作者: 微雪电子

摘要: 一、安装蓝牙依赖库升级安装蓝牙相关软件包 cpp代码:sudo apt-get update sudo apt-get upgrade -y sudo apt-get dist-upgrade -y sudo apt-get install pi-bluetooth bluez bluez-firmware blueman 最关键一点:添 ...
一、安装蓝牙依赖库

升级安装蓝牙相关软件包

cpp代码:

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
sudo apt-get install pi-bluetooth bluez bluez-firmware blueman


最关键一点:添加pi用户到蓝牙组

cpp代码:

sudo usermod -G bluetooth -a pi


重启树莓派

cpp代码:

sudo reboot


二 ,开启蓝牙设备

启动/增加SPP

cpp代码:

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


修改文件中这两个语句。


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

如果有看到hci0设备则蓝牙已经开启工作。如果没有则没有识别到蓝牙设备。

注意:如果/boot/config.txt文件中有 dtoverlay=pi3-miniuart-bt 这语句需要注释掉,否则蓝牙设备不能正常工作。

查看蓝牙适配器提供的各种功能

cpp代码:

pi@raspberrypi:~ $ sudo sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service RecHandle: 0x10000
Service Class ID List:
  "PnP Information" (0x1200)
Profile Descriptor List:
  "PnP Information" (0x1200)
    Version: 0x0103
 
Browsing FF:FF:FF:00:00:00 ...
Service Search failed: Invalid argument
Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10001
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100
 
Service Name: Generic Access Profile
Service Provider: BlueZ
Service RecHandle: 0x10002
Service Class ID List:
  "Generic Access" (0x1800)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 31
  "ATT" (0x0007)
    uint16: 0x0001
    uint16: 0x0008
 
Service Name: Generic Attribute Profile
Service Provider: BlueZ
Service RecHandle: 0x10003
Service Class ID List:
  "Generic Attribute" (0x1801)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 31
  "ATT" (0x0007)
    uint16: 0x0010
    uint16: 0x0010
 
Service Name: AVRCP CT
Service RecHandle: 0x10004
Service Class ID List:
  "AV Remote" (0x110e)
  "AV Remote Controller" (0x110f)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0105
 
Service Name: AVRCP TG
Service RecHandle: 0x10005
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0104

三、链接蓝牙设备


输入如下命令进入蓝牙控制界面,(可进入界面输入help查看命令列表)

cpp代码:

sudo bluetoothctl

agent on


然后进入界面之后(可进入界面输入help查看命令列表)

cpp代码:

agent on
default-agent

scan on之后 就可以看到扫描得到的蓝牙设备的物理地址了,类似XX:XX:XX:XX:XX:XX之类的地址

配对使用以下命令(以下请把XX:XX:XX:XX:XX:XX替换为你自己设备的地址,android手机可以在设置->关于手机->状态信息中看到蓝牙地址。)
pair XX:XX:XX:XX:XX:XX


配对之后把设备添加到信任列表
trust XX:XX:XX:XX:XX:XX

之后连接设备
connect XX:XX:XX:XX:XX:XX

最后quit退出就可以了,以后蓝牙设备开机后树莓派会自动进行连接。

四,手机端通过蓝牙发送数据到树莓派

运行如下命令后等待链接

cpp代码:

sudo rfcomm watch hci0

手机端打开蓝牙软件(例如 WS EDR),搜索蓝牙设备并链接到树莓派


如果没有搜索到树莓派蓝牙,可以运行如下命令开启蓝牙可发现。




另外打开一个终端运行如下命令可以看到/dev目录下有一个rfcomm0设备,只有蓝牙设备连接上树莓派后才有这个设备。

运行如下命令,用串口软件minicom 打开这个设备。(如果没有安装minicom,可以运行sudo apt-ge install minicom 安装)

cpp代码:

sudo minicom -D /dev/rfcomm0


minicom界面如下,此时按下手机中的方向键,minicom会接受到相应的指令。


Ctrl+A,再按Z进入菜单,再按Q退出minicom。

四,蓝牙控制小车示例程序
废话也不多说,直接上代码。bluetooth.py文件

cpp代码:

#!/usr/bin/python
# -*- coding:utf-8 -*-
import serial
import time
import json
from AlphaBot import AlphaBot
 
LOW_SPEED    =  30
MEDIUM_SPEED =  50
HIGH_SPEED   =  80
 
Ab = AlphaBot()
BT = serial.Serial("/dev/rfcomm0",115200)
print('serial test start ...')
BT.flushInput()
 
try:
    while True:
        data = ""
        while BT.inWaiting() > 0:
            data += BT.read(BT.inWaiting())
        if data != "":
            #print data
            try:
                s = json.loads(data)             
                cmd =  s.get("Forward")
                if cmd != None:
                    if cmd == "Down":
                        BT.write("{\"State\":\"Forward\"}")
                    elif cmd == "Up":
                        BT.write("{\"State\":\"Stop\"}")
                        Ab.stop()
 
                cmd = s.get("Backward")
                if cmd != None:
                    if cmd == "Down":
                        BT.write("{\"State\":\"Backward\"}")
                    elif cmd == "Up":
                        BT.write("{\"State\":\"Stop\"}")
                        Ab.stop()
                 
                cmd = s.get("Left")
                if cmd != None:
                    if cmd == "Down":
                        BT.write("{\"State\":\"Left\"}")
                    elif cmd == "Up":
                        BT.write("{\"State\":\"Stop\"}")
                        Ab.stop()
                         
                cmd = s.get("Right")
                if cmd != None:
                    if cmd == "Down":
                        BT.write("{\"State\":\"Right\"}")
                    elif cmd == "Up":
                        BT.write("{\"State\":\"Stop\"}")
                        Ab.stop()
                         
                cmd = s.get("Low")
                if cmd == "Down":
                    BT.write("{\"State\":\"Low\"}")
                    Ab.setPWMA(LOW_SPEED);
                    Ab.setPWMB(LOW_SPEED);
 
                cmd = s.get("Medium")
                if cmd == "Down":
                    BT.write("{\"State\":\"Medium\"}")
                    Ab.setPWMA(MEDIUM_SPEED);
                    Ab.setPWMB(MEDIUM_SPEED);
 
                cmd = s.get("High")
                if cmd == "Down":
                    BT.write("{\"State\":\"High\"}")
                    Ab.setPWMA(HIGH_SPEED);
                    Ab.setPWMB(HIGH_SPEED);                 
 
                BT.flushInput()                 
            except ValueError:       #not json format
                continue
except KeyboardInterrupt:
    if BT!= None:
        BT.close()




{程序分析]:
1.由上一节可知,蓝牙只需作为串口使用即可,不需要了解复杂的蓝牙协议。关于Python串口控制可以参考树莓派系列教程13:Serial串口
2.BT = serial.Serial("/dev/rfcomm0",115200) 创建蓝牙设备示例,波特率115200
3.BT.flushInput() 清空接受缓存,丢弃之前的数据。
4.BT.inWaiting() 读取接受缓冲区是否有数据。
5.BT.read() 读取数据
6.BT.write() 发送数据
7.s = json.loads(data) 将json格式的字符转化为Python字典对象。如果蓝牙发送的字符串不是json格式,则会出现ValueError异常,数据丢弃继续接收。
8.cmd = s.get("Forward") 查询字典中是否有Forward键,返回的是键值,如果没有则返回None

运行如下命令启动程序

cpp代码:

sudo rfcomm watch hci0 1 python bluetooth.py


[命令分析]:
通过rfcomm 命令检测 hci0设备,当蓝牙设备连接到树莓派时,会创建/dev/rfcomm0 节点。
参数 1 表示有设备连接时创建一个进程来运行 python bluetooth.py
当连接成功时进程启动,连接断开时进程结束,或当进程结束时连接断开。


142

顶一下

刚表态过的朋友 (142 人)

相关阅读

最新评论

智能车

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号  

GMT+8, 2019-1-18 18:43 , Processed in 0.082037 second(s), 26 queries .

Powered by Discuz! X3.2 © 2001-2013 Comsenz Inc & Style Design

返回顶部