当前位置: 首页 > news >正文

嵌入式人工智能(41-基于树莓派4B的串口蓝牙模块AT09-cc2541)

1、串口蓝牙模块AT-09

AT-09是一种串口蓝牙模块,可实现串口与蓝牙之间的数据传输。AT-09模块基于蓝牙4.0技术,具有低功耗、高传输速率和广泛的应用范围。

AT-09模块支持AT指令,通过串口与外部设备进行通信。用户可以使用AT指令对模块进行配置和控制,例如设置蓝牙名称、密码、通信速率等。通过串口,用户可以与AT-09模块进行数据传输,实现与蓝牙设备的无线通信。

AT-09模块通常用于无线传输、数据采集等应用场景。它可以与各种主控板和设备进行连接,如Arduino、Raspberry Pi等。通过AT-09模块,用户可以方便地将串口设备无线化,实现无线控制和数据传输。

有了这个串口蓝牙模块,我们就可以用手机远程控制很多物联网设备了。有了通信网,整个世界都变得更加丰富多彩了。

2、蓝牙cc2541模块

串口蓝牙模块所用的蓝牙芯片是CC2541,而真正的无线通信是靠CC2541收发数据。串口仅仅是用来将无线收发的数据通过串口送开发板微处理器。

CC2541是一款针对低能耗以及私有2.4GHz应用的功率优化的真正片载系统(SoC)解决方案。它使得使用低总体物料清单成本建立强健网络节点成为可能。CC2541将领先RF收发器的出色性能和一个业界标准的增强型8051MCU、系统内可编程闪存存储器、8kBRAM和很多其它功能强大的特性和外设组合在一起。CC2541非常适合应用于需要超低能耗的系统。

通过下图可以看出真正片载系统Soc即串口底板+片上蓝牙模块。具体的原理,内部结构,功能,引脚等等请看数据手册把。

通过USB-TTL与电脑或者开发板连接,与电脑的连接可以参考我这个专栏的语音模块syn6288那一部分。

我们这里还是介绍与树莓派的接线,引脚引出线只有4根,这样就好接线了,VCC接开发板5V,GND接地,TXD接开发板的RXD0(BOARD10),RXD接开发板的TXD0(BOARD8)

3、手机蓝牙助手连接CC2541

这个部分最简单,但是也最重要,因为手机上要有应用程序和蓝牙模块建立连接。手机上的蓝牙应用程序可不是C或Python写的,具体我们也不要管它了,我们下载一个别人写好的能用的蓝牙助手,安卓手机安装包的名称为HCbluetooth.apk。然后将蓝牙模块也插上电,上电后蓝牙模块的指示灯不停闪烁。

在手机上找到刚刚安装的HC蓝牙助手,点击打开,打开后搜索到该模块,点击连接就OK了。

连接上之后,蓝牙模块的灯就不会闪了,一直亮着,然后把这几个模块都看看。

这个发送速度就设置为中就可以,经测试为波特率为9600,停止位1位,数据位8位,奇偶校验无,回头开发板的串口也设置为一样即可。

4、踩坑必看

本以为很简单的事情,运行程序后收到的数据不正常,或者收不到数据。耽误了大半天时间,经过我一顿思考和尝试,这里有个坑,同学们注意。如果你还没有运行程序,请先看第5部分。

(1)如果在运行程序出现:(提示权限问题,可以sudo chmod 666 /dev/ttyS0 暂时解决)

(3)手机HC蓝牙助手也出现这样的echo:

这些看似很多问题,可能是由于同一个问题导致的,就是蓝牙串口使用了ttyS0设备,该设备默认让用户通过串口登录,很久以前,windows有个超级终端的串口登录,估计同学们都不知道了,那已经是20多年前的事情了,以前都是都过串口登录到设备,做一些调试,比如路由器、交换机。该树莓派也是打开串口让用户登录。所以在通过蓝牙串口发送数据给树莓派时,开启了串口终端登录。我们到树莓派配置里面将这个功能给关闭。

点击OK后重启。估计就不会出现上述问题了。

4、实验代码与现象

有了这个模块我们就可以发送数据给开发板了,比如打开第1个灯,关闭第1个灯;或者开1,关1;总之python语言中对字符串的处理是非常方便的。只要包含开关这两个字就知道状态给0还是1;然后再从字符串中提取数字,把这个值赋值给变量即可。我这边为了节省IO口,仍然用TM1638扩展板做,如果同学们没有就直接放2个LED实现效果即可。

iimport serial
import TM1638
import time
import redef init():global tmtm=TM1638.TM1638(stb=36,clk=38,dio=40) tm.brightness(2)DEVICE = "/dev/ttyS0"global serser=serial.Serial(DEVICE,baudrate=9600,bytesize=8,parity="N",stopbits=1,timeout=0.1)def main_loop():while True:if ser.in_waiting > 0:# 读取串口数据data = ser.readall().decode('utf-8').strip()print("收到的数据:", data)if '开' in data:status = 1elif '关' in data:status = 0elif data=='结束程序':breakelse:ser.write(bytes('没有给出正确的指令','utf-8'))   firstnum = re.search(r'\d',data)if firstnum:first_number = firstnum.group() if int(first_number)>0 and int(first_number)<=8:tm.led(int(first_number)-1,status) else:ser.write(bytes('没有给出正确的LED号码(1-8)','utf-8'))if __name__ == '__main__':init()try:main_loop()except KeyboardInterrupt:print("程序结束!")finally:tm.clear()ser.close()

程序解释:

(1)程序代码没有多少行,这就体现了Python语言的精练,同样的代码用C来写你试试把。可能有同学觉得树莓派毕竟是一台口袋电脑,用来做物联网成本有点高,而低成本的处理器可能不支持python。我这里有个想法,但是还没有考虑成熟,等我把树莓派栏目写完,我打算用ESP32或ESP8266做MicroPython的实验或项目,看看MicroPython在物联网上面和C的性能差距有多少。

(2)串口设置,不管有些参数是不是默认值,还是将波特率、数据位、停止位、奇偶校验都设置下。ser=serial.Serial(DEVICE,baudrate=9600,bytesize=8,parity="N",stopbits=1,timeout=0.1)

串口通信超时解决方案在进行串口通信时,可能会遇到以下两个问题:a读取串口数据时阻塞时间过长,造成程序无法及时响应。b进行写操作时,设备没有及时响应。
为了解决这些问题,我们可以使用Python的serial库提供的timeout参数来设置超时时间。timeout参数是一个浮点数,代表等待数据的最长时间(以秒为单位)。当没有数据可读时,等待超过指定的超时时间后,将触发超时异常。

(3)serial-三方库,提供了一系列的方法来处理串行通信。

in_waiting:返回输入缓冲区中的字节数。

        if ser.in_waiting > 0:
            # 读取串口数据
            data = ser.readall().decode('utf-8').strip()

收到的数据都是以字节流的形式放到接收缓冲区,上面是正确的接收,我之前写的代码是

data = ser.readall()

if data:

        text = data..decode('utf-8')

结果发现utf8编码的汉字被拆成3个字节,一个一个的print,python就没有办法解码了。

(4)输入相关指令对LED进行控制,可以先让程序发一段解释说明给手机,这样最好。

            if '开' in data:status = 1elif '关' in data:status = 0elif 'help' in data:ser.write(bytes('请输入开/关 1-8的字样\n','utf-8'))   elif data=='结束程序':breakelse:ser.write(bytes('没有给出正确的指令\n','utf-8'))   

当然我这个程序if的嵌套逻辑结构不是最好的,如果业务逻辑比较丰富的话,可以参考模块化编程的思想和方法。

(5)指令包括2个参数,一个是第几个灯,一个是状态,所以状态通过开关来给定,第几个灯要从用户输入的内容里面提取数字再判断数字的有效范围。

从字符串里面提取第一个数字firstnum = re.search(r'\d',data)这里用到了正则表达式,需要导入re库,‌正则表达式是一种强大的文本处理工具,用于匹配、查找、替换复杂的文本模式。它由普通字符和特殊字符(元字符)组成,能够描述和匹配一系列符合特定规则的字符串。

相关文章:

嵌入式人工智能(41-基于树莓派4B的串口蓝牙模块AT09-cc2541)

1、串口蓝牙模块AT-09 AT-09是一种串口蓝牙模块&#xff0c;可实现串口与蓝牙之间的数据传输。AT-09模块基于蓝牙4.0技术&#xff0c;具有低功耗、高传输速率和广泛的应用范围。 AT-09模块支持AT指令&#xff0c;通过串口与外部设备进行通信。用户可以使用AT指令对模块进行配…...

C++ 动态规划

子序列子串相关 单个指一个数组或字符串&#xff0c;两个指两个数组或字符串。 最长上升子序列-单个 dp[i]&#xff1a;以下标i为结尾的递增的最长子序列长度。 位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 class Solution { public:int l…...

回溯问题总结

一、子集问题 模板问题 给定一个序列[1,n],求这个序列的所有子集 输入描述&#xff1a; 一个正整数n(1 < n < 12) 输出描述&#xff1a; 每个子集一行&#xff0c;输出所有子集。 输出顺序为&#xff1a; &#xff08;1&#xff09;元素个数少的子集优先输出&#xff1b;…...

GraphRAG如何使用ollama提供的llm model 和Embedding model服务构建本地知识库

使用GraphRAG踩坑无数 在GraphRAG的使用过程中将需要踩的坑都踩了一遍&#xff08;不得不吐槽下&#xff0c;官方代码有很多遗留问题&#xff0c;他们自己也承认工作重心在算法的优化而不是各种模型和框架的兼容性适配性上&#xff09;&#xff0c;经过了大量的查阅各种资料以…...

.net # 检查 带有pdf xss

1.解决pdf含javasprct脚本动作&#xff0c;这里是验证pdf内部事件。相关pdf文件下载&#xff1a; 测试pdf文件 相关包 iTextSharp 5.5.13.4 iTextSharp using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser;private Boolean IsPdfSafe(Stream stream){// PdfReader…...

【React】探讨className的正确使用方式

文章目录 一、className的正确用法二、常见错误解析三、实例解析四、错误分析与解决五、注意事项六、总结 在React开发中&#xff0c;正确使用className属性对组件进行样式设置至关重要。然而&#xff0c;由于JavaScript和JSX的特殊性&#xff0c;开发者常常会犯一些小错误&…...

打靶记录5——靶机hard_socnet2

靶机&#xff1a; https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova目标&#xff1a; 取得root权限 涉及攻击方法 主机发现端口扫描SQL注入文件上传蚁剑上线XMLRPC命令执行逆向工程动态调试漏洞利用代码编写 方法 CVE-2021-3493缓冲器溢出漏洞 学习目标 …...

独立站+TikTok达人:自主营销与创意内容的完美结合

在全球电商市场迅猛发展的今天&#xff0c;独立站和TikTok达人的结合正在创造一种全新的电商营销模式。独立站作为电商平台&#xff0c;其自主性和灵活性为商家提供了广阔的发展空间&#xff1b;而TikTok达人凭借其独特的内容创作能力和庞大的粉丝基础&#xff0c;成为推动销售…...

【启明智显分享】适用于多功能养生壶、茶吧机的2.8寸触摸彩屏解决方案

健康生活理念不断深入人心&#xff0c;多功能养生壶、茶吧机等智能产品成为现代家庭的热门小家电。为推动智能家居个性化、多样化发展&#xff0c;启明智显推出了基于SC05 Plus 2.8寸触摸彩屏的多功能养生壶、茶吧机的解决方案&#xff0c;旨在提升养生壶与茶吧机的用户体验与操…...

WAF绕过技术(PKAV团队)

目录 主流WAF的绕过技术 Web容器的特性 1. IIS+ASP的神奇% 2. IIS的Unicode编码字符 3. HPP(HTTP Parameter Pollution): HTTP参数污染 4. 畸形HTTP请求 Web应用层的问题 1. 多重编码问题 2. 多数据来源的问题 WAF自身的问题 1. 白名单机制 2. 数据获取方式存在缺陷…...

『 Linux 』POSIX 信号量与基于环形队列的生产者消费者模型

文章目录 信号量概念POSIX 信号量基于环形队列的生产者消费者模型基于环形队列的生产者消费者模型编码实现基于环形队列的生产者消费者模型发送任务测试 信号量概念 信号量是一种用于多线程或多进程间同步的机制; 其定义是一个整形变量,本质上信号量可以看成是一个计数器,用来描…...

python中的字符串方法

python中的字符串 举个例子先 name = 貂蝉开大 #声明了一个字符串 print(name) # 打印了一个字符串 print(name[0:1] #输出貂蝉 print(name[2:3] #输出开大 扩展方法 find() # 查找字符串中某个字符的索引 index_ = name.find("貂") print(index_) # 输出 …...

python实现consul的服务注册与注销

我在使用consul的时候主要用于prometheus的consul服务发现&#xff0c;把数据库、虚拟机信息发布到consul&#xff0c;prometheus通过consul拿到数据库、虚拟机信息去采集指标信息。 此篇文章前提是已经安装好consul服务以后&#xff0c;安装consul请参考二进制方式部署consul…...

校园选课助手【2】-重要的登录模块

用户登录模块技术要点&#xff1a; 密码通过MD5加密传输分布式session存储用户登录信息自定义注解进行字段校验自定义拦截器完成登录验证 下面依次给出代码和详细解释&#xff1a; 1.使用 MD5 二次加密用户登录信息&#xff0c;前端先通过密码加上盐进行MD5加密交给服务器&a…...

4章2节:从排序到分组和筛选,通过 R 的 dplyr 扩展包来操作

dplyr是R语言中一个强大且高效的数据处理包,专门设计用于处理数据框(data frames)。它的语法简洁明了,操作高效,尤其适用于大数据集。dplyr提供了一系列函数,使得数据的筛选、变换、聚合和排序等操作变得简单直观。本文将详细介绍dplyr扩展包如何进行数据的排序到分组和筛…...

C语言实现 -- 单链表

C语言实现 -- 单链表 1.顺序表经典算法1.1 移除元素1.2 合并两个有序数组 2.顺序表的问题及思考3.链表3.1 链表的概念及结构3.2 单链表的实现 4.链表的分类 讲链表之前&#xff0c;我们先看两个顺序表经典算法。 1.顺序表经典算法 1.1 移除元素 经典算法OJ题1&#xff1a;移除…...

WSL和Windows建立TCP通信协议

1.windows配置 首先是windows端&#xff0c;启动TCP服务端&#xff0c;用来监听指定的端口号&#xff0c;其中IP地址可以设置为任意&#xff0c;否则服务器可能无法正常打开。 addrSer.sin_addr.S_un.S_addr INADDR_ANY; recv函数用来接收客户端传输的数据&#xff0c;其中…...

Android Gradle开发与应用(一):Gradle基础

文章目录 引言一、Gradle简介二、Gradle基础语法1. 项目结构2. 插件应用3. 仓库与依赖4. 任务&#xff08;Tasks&#xff09; 三、Gradle在Android项目中的深入应用1. 构建变体&#xff08;Build Variants&#xff09;2. 依赖管理3. 自定义构建逻辑 四、Gradle WrapperGradle W…...

Linux多线程服务器编程-1-线程安全的对象生命期管理

对象的生与死不能由对象自身拥有的mutex&#xff08;互斥器&#xff09;来保护. 如何避免对象析构时可能存在的race condi​t​ion&#xff08;竞态条件&#xff09;是C多线程编程面临的基本问题。 对象的销毁可能出现多种竞态条件(race condi​t​ion)&#xff1a; 在即将析构…...

Couchbase 技术详解

文章目录 Couchbase 原理数据模型数据分布数据访问与同步官网链接 基础使用安装与配置数据操作 高级使用数据分片与负载均衡数据索引与查询安全性与权限管理 优点高性能可扩展性高可用性灵活性 总结 Couchbase 是一个高性能、分布式、可扩展的 NoSQL 数据库系统&#xff0c;基于…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...