草庐IT

Orangepi Zero2——手机连接Linux与语音模块串口通信

Is Fang 2023-10-13 原文

文章目录

手机连接Linux

1、把手机接入开发板

2、安装 adb 工具,在终端输入 adb 安装指令:

sudo apt-get install adb

3、dmesg 能查看到手机接入的信息,但是输入adb devices会出现提醒

dinsufficient permissions for device: user in plugdev group; are your udev rules wrong?

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”

5、如果无法连接上,则需要在手机开发者选项中,打开USB调试,重新拔插手机,点击信任此设备

6、输入 adb devices 进行手机的连接

7、输入 adb shell 进行编程

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

语音模块控制手机

设备连接图

语音模块配置

  • 进入语音模块官网 http://www.smartpi.cn/#/,配置词条和识别后的串口输出指令,输出SDK
  • 使用固件烧录工具,通过串口烧录进语音识别模块的SDK
  • 先让语音固件先和电脑调试助手配合,验证数据

香橙派的配置

  • 通过远程连接平台输出控制语句,检验是否可以操作手机完成相应的动作

香橙派程序

  • 香橙派与语音固件通过串口进行通信

uartTest.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> 
#include <unistd.h> 
 
#include <pthread.h> 
#include "uartTool.h"
 
int fd; 
 
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 'L': 
				printf("last\n"); 	  
				system("adb shell input swipe 540 500 540 1300 100");
				break; 
			case 'Z': 
				printf("zan\n"); 
				system("adb shell \"seq 2 | while read i;do input tap 540 1050 & input tap 540 1050 & sleep 0.1;done;\"");
				break; 
			case 'Q': 
				printf("quit\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 = myserialOpen(deviceName, 115200)) == -1){ 
		printf("open %s error\n",deviceName); 
		return -1; 
	}
	
	pthread_create(&readt, NULL, readSerial,NULL); 
	
	while(1){sleep(10);} 
 
}

uartTool.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>
#include "wiringSerial.h"
 
char myserialGetchar (const int fd)
{
	char x ;
 
	if (read(fd , &x, 1) != 1)
		return -1 ;
 
	return x ;
}
 
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 ; 
	}
	if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) 
	return -1 ; 
	
	fcntl (fd, F_SETFL, O_RDWR) ; 
	
// Get and modify current options: 
 
	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 ; // Ten seconds (100 deciseconds) 
 
	tcsetattr (fd, TCSANOW, &options) ; 
 
	ioctl (fd, TIOCMGET, &status); 
 
	status |= TIOCM_DTR ; 
	status |= TIOCM_RTS ; 
 
	ioctl (fd, TIOCMSET, &status); 
	
	usleep (10000) ; // 10mS 
	
	return fd ; 	
}
 
void serialSendstring (const int fd, const char *s) 
{ 
	int ret;
	ret = write (fd, s, strlen (s)); 
	if (ret < 0) 
		printf("Serial Sendstring Error\n"); 
}
 
int serialGetstring (const int fd, char *buffer) 
{ 
	int n_read; 
	n_read = read(fd, buffer,32); 
	return n_read; 
}

uartTool.h

//香橙派获取语音固件发送的字符
char myserialGetchar (const int fd);
 
int myserialOpen (const char *device, const int baud);
 
void serialSendstring (const int fd, const char *s);
 
int serialGetstring (const int fd, char *buffer);

有关Orangepi Zero2——手机连接Linux与语音模块串口通信的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  7. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  8. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  9. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  10. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

随机推荐