【Orangepi Zero2 全志H616】驱动串口实现Tik Tok—VUI(语音交互)
一、编程实现语音和开发板通信
- wiringpi库源码
- demo.c
二、基于前面串口的代码修改实现
- uartTool.h
- uartTool.c
- uartTest.c
三、ADB
- adb控制指令
四、手机接入Linux热拔插相关
a. 把手机接入开发板
b. 安装adb工具,在终端输入adb安装指令: sudo apt-get install adb
c. dmeg能查看到手机接入的信息,但是输入adb devices会出现提醒
dinsufficient permissions for device: user in plugdev group; are your udev rules wrong?
d. 配置文件,以支持USB设备的热拔插,支持UDEV的机制
在/etc/udev/rules.d 文件夹下创建规则文件
cd /etc/udev/rules.d/
sudo vim 51-android.rules
在文件中添加内容 SUBSYSTEM==“usb”, ENV{DEVTYPE}==“usb_device”, MODE=“0666”
e. 在手机开发者选项中,打开USB调试,重新拔插手机
f. 手机弹出调试提醒,点确认手机调试模式
一、编程实现语音和开发板通信
将语音模块插入开发板并编程实现基础逻辑代码,添加串口读取一个字符的接口my_serialGetchar();
wiringpi库源码:
demo.c
char myserialGetchar (const int fd)
{char x ;if (read(fd , &x, 1) != 1)return -1 ;return x ;
}
void* readSerial()
{ char cmd; while(1){ cmd = myserialGetchar(fd); switch (cmd) { case 'N' : printf ("NEXT\n") ;system ("adb shell input swipe 540 1300 540 500 100") ;break ; case 'B' : printf ("BACK\n") ; system ("adb shell input swipe 540 500 540 1300 100") ;break ; case 'A' : printf ("AGREE\n") ; system ("adb shell \"seq 2 | while read i;do input tap 540 1050 & input tap 540 1050 & sleep 0.1;done;\"") ;break ; case 'C' : printf ("CLOSE\n") ; system ("adb shell input keyevent 26") ;break ; } }
}
二、基于前面串口的代码修改实现
uartTool.h
#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>#include "wiringSerial.h"int my_serialOpen (const char *device, const int baud) ;void my_serialSendstring (const int fd, const char *s) ;int my_serialGetstring (const int fd, char *buffer) ;char my_serialGetchar (const int fd) ;
uartTool.c
#include "wiringSerial.h"
#include "uartTool.h"int my_serialOpen (const char *device, const int baud)
{struct termios options ; // 创建一个termios结构体,用于串口参数设置speed_t myBaud ; // 创建一个速度类型的变量 myBaud,用于保存波特率int status, fd ; // 创建整数类型的变量 status 和 fd,用于保存状态和文件描述符switch (baud){ // 根据传入的波特率参数选择合适的波特率常数case 9600: myBaud = B9600 ; break ; case 115200: myBaud = B115200 ; break ; }if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) // 打开串口设备,设置打开选项return -1 ; // 如果打开失败,返回错误代码 -1fcntl (fd, F_SETFL, O_RDWR) ; // 设置文件状态标志// Get and modify current options: 获取并修改当前的串口参数:tcgetattr (fd, &options) ; // 获取当前的串口参数cfmakeraw (&options) ; // 初始化 termios 结构体为原始模式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 ; // Ten seconds (100 deciseconds) 超时等待时间(十分之一秒100ms)tcsetattr (fd, TCSANOW, &options) ; // 设置新的串口参数ioctl (fd, TIOCMGET, &status); // 获取串口控制模式状态status |= TIOCM_DTR ; // 设置 DTR(数据终端就绪)位status |= TIOCM_RTS ; // 设置 RTS(请求发送)位ioctl (fd, TIOCMSET, &status); // 设置串口控制模式状态usleep (10000) ; // 暂停 10 毫秒return fd ; // 返回串口文件描述符
}void my_serialSendstring (const int fd, const char *s)
{int ret ;ret = write (fd, s, strlen (s)) ; if (ret < 0) printf ("Serial Sendstring Error\n") ;
}int my_serialGetstring (const int fd, char *buffer)
{int n_read ;n_read = read (fd, buffer, 32) ; return n_read ;
}char my_serialGetchar (const int fd)
{char x ;if (read (fd, &x, 1) != 1)return -1 ;return x ;
}
uartTest.c
#include <pthread.h>
#include "uartTool.h"int fd;void* readSerial ()
{char cmd ; while (1) {switch (cmd) { case 'N' : printf ("NEXT\n") ;system ("adb shell input swipe 540 1300 540 500 100") ;break ; case 'B' : printf ("BACK\n") ; system ("adb shell input swipe 540 500 540 1300 100") ;break ; case 'A' : printf ("AGREE\n") ; system ("adb shell \"seq 2 | while read i;do input tap 540 1050 & input tap 540 1050 & sleep 0.1;done;\"") ;break ; case 'C' : printf ("CLOSE\n") ; system ("adb shell input keyevent 26") ;break ; }}
}int main (int argc, char **argv)
{char deviceName [32] = {'\0'} ;pthread_t readt ;if (argc < 2) {printf ("uage:%s /dev/ttyS?\n", argv[0]) ;return -1 ;}strcpy (deviceName, argv[1]) ;if ((fd = my_serialOpen (deviceName, 115200)) == -1) {printf ("open %s error\n", deviceName) ;return -1;}pthread_create (&readt, NULL, readSerial, NULL) ;while (1) {sleep (10);}}
三、ADB
ADB(Android Debug Bridge)是一种用于与安卓设备通信和调试的命令行工具。它是Android开发工具包(Android SDK)的一部分,用于在开发过程中连接、控制和调试Android设备或模拟器。
ADB提供了一组命令,允许开发者在计算机上执行各种操作,包括安装和卸载应用程序、传输文件、执行Shell命令、查看设备日志等。使用ADB,开发者可以与设备交互,调试应用程序、分析问题并进行性能优化。
ADB可以通过USB连接或通过网络连接到Android设备。通过USB连接,开发者可以直接将设备连接到计算机,并通过ADB命令与设备进行通信。通过网络连接,开发者可以使用无线网络连接到设备,从而无需使用USB线缆。
需要注意的是,ADB在设备上需要开启开发者选项和USB调试模式才能正常使用。此外,ADB还提供了一些高级功能,如端口转发、截屏、录屏等,以支持更丰富的开发和调试需求。
总的来说,ADB是Android开发中非常重要的工具,它简化了与Android设备的通信和调试过程,为开发者提供了更好的开发环境和工作效率。
ADB(Android Debug Bridge)是一个用于在计算机和 Android 设备之间进行通信的命令行工具。它允许开发者执行各种设备操作,例如安装和调试应用程序、访问设备的 Shell、复制文件到设备或从设备复制文件等。ADB 是 Android SDK 的一部分,开发者可以使用它与 Android 设备进行交互。
以下是一些常用的 ADB 命令:
-
连接设备:
adb devices
-
安装应用:
adb install example.apk
-
卸载应用:
adb uninstall com.example.package
-
启动应用:
adb shell am start -n com.example.package/.MainActivity
-
查看设备信息:
adb shell getprop
-
复制文件到设备:
adb push localfile.txt /sdcard/
-
从设备复制文件:
adb pull /sdcard/remotefile.txt
-
启动设备 Shell:
adb shell
-
查看日志:
adb logcat
这只是一些常见的 ADB 命令示例,ADB 提供了更多的功能,可以帮助开发者进行 Android 应用程序的开发、调试和测试。请注意,使用 ADB 前需要确保 Android 设备已启用开发者选项和 USB 调试。
adb控制指令
用 shell 指令来操作手机屏幕,模拟手动滑屏幕
1、向下滑动。从坐标点(540,1300)用100ms滑动到坐标点(540,500)
adb shell input swipe 540 1300 540 500 100
2、 向下滑动。从坐标点(540,500)用100ms滑动到坐标点(540,1300)
adb shell input swipe 540 500 540 1300 100
3、双击。点击坐标点(540,1050)两次,间隔0.1s
adb shell "seq 2 | while read i;do input tap 540 1050 & input tap 540 1050 &sleep 0.1;done;"
4、锁屏。
adb shell input keyevent 26
使用ADB,开发人员可以通过USB连接将计算机与Android设备连接起来,并通过命令行界面执行各种操作。一些常见的ADB命令包括:
-
adb devices:列出当前连接的Android设备。
-
adb shell:进入设备的命令行界面。
-
adb install <path_to_apk>:安装一个Android应用程序。
-
adb uninstall <package_name>:卸载一个已安装的应用程序。
-
adb logcat:查看设备的系统日志。
-
adb pull <remote_path> <local_path>:从设备上复制文件到计算机上。
-
adb push <local_path> <remote_path>:将文件从计算机上复制到设备上。
请注意,使用ADB需要在计算机上安装Android SDK,并且设备的开发者选项和USB调试选项需要启用。使用ADB时要小心,因为一些命令可能会对设备造成不可逆的影响。
四、手机接入Linux热拔插相关
a. 把手机接入开发板
b. 安装adb工具,在终端输入adb安装指令: sudo apt-get install adb
c. dmeg能查看到手机接入的信息,但是输入adb devices会出现提醒
dinsufficient permissions for device: user in plugdev group; are your udev rules wrong?
d. 配置文件,以支持USB设备的热拔插,支持UDEV的机制
在/etc/udev/rules.d 文件夹下创建规则文件
cd /etc/udev/rules.d/
sudo vim 51-android.rules
在文件中添加内容 SUBSYSTEM==“usb”, ENV{DEVTYPE}==“usb_device”, MODE=“0666”
e. 在手机开发者选项中,打开USB调试,重新拔插手机
f. 手机弹出调试提醒,点确认手机调试模式
Linux 中如何挂载 iPhone 外部设备
1、把手机接入开发板
2、安装 adb 工具,在终端输入 adb 安装指令:
sudo apt-get install adb
3、dmesg 能查看到手机接入的信息,但是输入adb devices会出现提醒
在手机开发者选项中,打开USB调试,重新拔插手机,点击信任此设备
华为进入开发者模式
iPhone开发者模式
安卓同理
dmesg
adb devices
adb shell
4、配置文件,以支持USB设备的热拔插,支持UDEV的机制
在/etc/udev/rules.d 文件夹下创建规则文件
cd /etc/udev/rules.d/
sudo vim 51-android.rules
在文件中添加内容
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
USB设备的热拔插是指在计算机运行过程中插入或拔出USB设备而无需重新启动计算机或中断正在进行的工作。这种功能由操作系统提供的USB驱动程序和设备管理机制来实现。
UDEV(User Device)是一个设备管理子系统,主要用于动态配置和管理系统中的设备。它可以监测设备的插入和拔出事件,并根据预定义的规则进行自动配置和操作。
当USB设备插入计算机时,UDEV会自动检测设备并通过设备的唯一标识(如设备ID、厂商ID等)匹配相应的规则。根据规则,UDEV可以执行一系列操作,如加载适当的驱动程序、分配设备文件、设置设备权限等。
同样,当USB设备被拔出时,UDEV也会检测到设备的拔出事件,并执行相应的操作,如卸载驱动程序、释放设备文件等。
通过UDEV的机制,操作系统可以实现对USB设备的热拔插支持,提供了便利性和灵活性,使得用户可以方便地连接和断开USB设备,而无需手动进行设备配置或重新启动系统。这对于用户和开发者来说都是非常方便和实用的功能。
相关文章:

【Orangepi Zero2 全志H616】驱动串口实现Tik Tok—VUI(语音交互)
一、编程实现语音和开发板通信 wiringpi库源码demo.c 二、基于前面串口的代码修改实现 uartTool.huartTool.cuartTest.c 三、ADB adb控制指令 四、手机接入Linux热拔插相关 a. 把手机接入开发板 b. 安装adb工具,在终端输入adb安装指令: sudo apt-g…...

【Spring】静态代理
例子: 租房子 角色: 我 (I ) 中介( Proxy ) 房东( host ) Rent 接口 package org.example;public interface Rent {void rent(); }房东 package org.example;public class Host implements Rent{Overridepublic void rent() …...
tomcat web.xml文件中servlet的load-on-startup
先看一个例子: <servlet><description>JAX-WS endpoint - restful</description><display-name>restful</display-name><servlet-name>restful-addnumbers</servlet-name><servlet-class>com.sun.xml.ws.transpor…...
记chrome打不开网址,无法搜索问题
打开网址解决办法 2023关于chrome谷歌浏览器无法正常上网问题,解决办法,亲测有效 下载插件,解压后拖入chrome的扩展程序中,可以打开国内网址 google引擎搜索解决办法 打开无痕浏览 (不知道什么原理,可…...

Spring面试题:(五)Spring注解开发@Component,@Autowired,@Bean,@Configuration
Bean基本注解 spring提供注解的版本 Component注解替代bean标签 bean其它属性的相关注解: scope 替代scopelazy 替代lazy-initPostConstruct 替代init-methodPreDestroy 替代destroy-method 使用Component注解的前提是开启注解扫描 衍生注解Repository,Servi…...

【Qt-23】ui界面设计-ToolBar
1、ToolBar 右击主窗体添加工具栏 新建动作,可设置图标,图标有本地文件和资源两种方式。 修改toolButtonStyle的属性,可设置图标与汉字显示的方式。 页面跳转: connect(ui->action, SIGNAL(triggered()), this, SLOT(openWid…...
nodejs 异步架构
nodejs的核心之一就是非阻塞的异步IO,于是想知道它是怎么实现的,挖了下nodejs源码,找到些答案,在此跟大家分享下。首先,我用了一段js代码test-fs-read.js做测试,代码如下: var path require(pa…...

腾讯云优惠券介绍、作用、领取方法及使用教程
随着云计算技术的发展,越来越多的企业和个人选择使用云服务进行数据存储、计算等业务。腾讯云作为国内知名的云服务商,提供了一整套完善的云解决方案,并不定期发放优惠券以吸引更多的客户。本文将为大家详细介绍腾讯云优惠券的作用、领取方法…...

浅谈智能变电站自动化系统的应用与产品选型
安科瑞电气股份有限公司 上海嘉定 201801 摘要:现如今,智能变电站发展已经成为了电力系统发展过程中的内容,如何提高智能变电站的运行效率也成为电力系统发展的一个重要目标,为了能够更好地促进电力系统安全稳定运行,…...

适用于初学者的 .NET MAUI
适用于初学者的 .NET MAUI | Microsoft Learn 记录微软Learn中用到的代码。文章比较粗糙,大部分是项目代码粘贴。想详细学习的可到上面的链接学习,代码可以从这里复制后直接运行。 练习中一共有两个页面: 1、MainPage.xaml 用于添加列表中的…...
Web3项目灵魂所在之智能合约编写(Web3项目一实战之二)
正如标题所言,为什么将智能合约称为Web3项目的灵魂所在呢?其实,智能合约好比是传统App的服务器端,若服务器端宕机了,App也就僵死了。 假使您正在浏览本篇文章时,对智能合约还不是很了解,或者说是只知其名不知其意的话,那么,烦请您移步我另外一篇关于 区块链中的智能合…...

python-jupyter实现OpenAi语音对话聊天
1.安装jupyter 这里使用的是jupyter工具,安装时需要再cmd执行如下命令,由于直接执行pip install jupyter会很慢,咱们直接使用国内源 pip install --user jupyter -i http://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.t…...

恒源云之oss上传数据、云台下载数据
目录 一、本地cmd上传数据二、使用云平台下载数据 一、本地cmd上传数据 需要下载恒源云客户端oss需要先将数据(代码、数据集)压缩成zip文件。 本地cmd打开oss,测试是否安成功 oss输入oss命令,并正确输入账号密码 oss login在个人…...
大数据-之LibrA数据库系统告警处理(ALM-12039 GaussDB主备数据不同步)
告警解释 GaussDB主备数据不同步,系统每10秒检查一次主备数据同步状态,如果连续6次查不到同步状态,或者同步状态异常,产生告警。 当主备数据同步状态正常,告警恢复。 告警属性 告警ID 告警级别 可自动清除 12039…...
【左程云算法全讲6】链表相关
系列综述: 💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考…...

从HDFS到对象存储,抛弃Hadoop,数据湖才能重获新生?
Hadoop与数据湖的关系 1、Hadoop时代的落幕2、Databricks和Snowflake做对了什么3、Hadoop与对象存储(OSD)4、Databricks与Snowflake为什么选择对象存储5、对象存储面临的挑战 1、Hadoop时代的落幕 十几年前,Hadoop是解决大规模数据分析的“白…...

灰度与二值化
人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…...

No183.精选前端面试题,享受每天的挑战和学习
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...

[C国演义] 第十八章
第十八章 最长斐波那契子序列的长度最长等差数列等差序列划分II - 子序列 最长斐波那契子序列的长度 力扣链接 子序列 ⇒ dp[i] — — 以 arr[i] 结尾的所有子序列中, 斐波那契子序列的最长长度子序列 ⇒ 状态转移方程 — — 根据最后一个位置的组成来划分 初始化 — — 根…...

发送失败的RocktMQ消息,你遇到过吗?
背景 需要通过flink同时向测试和线上的RocketMQ中写入数据 现象 在程序中分别创建了两个MqProducer,设置了不同的nameServerAddr,分别调用不同的producer向不同环境发消息,返回发送成功,但是在线上MQ中却查不到数据࿰…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...