手势控制小车 随着科技的发展,人与计算机的交互活动越来越成为人们日常生活的一个重要组成部分,特别是视觉计算机的发展,使计算机能“看懂”用户的动作。其中手势识别是实现新一代人机交互不可缺少的一项关键技术。众周所知,手势识别是一项复杂的技术,包括运动建模、运动分析、模式识别等机器学习技术。能否通过Arduino控制器与传感器简单的识别说手势的方向呢,为此小白做了一些尝试。 手势方向有多种,如手势从左到右、从右到左、从上到下、从下到上等。为此手势方向的识别成为了本次尝试的重点和难点。 在经过一番思考之后,想了一种比较简单的手势识别思路,即通过两个传感器检测到手的时间顺序来识别手势方向。 然后通过两个控制器来实现手势控制小车;其中一个是手势控制端;另外一个是小车控制端。 手势控制端将识别出来的手势方向通过蓝牙传输给小车控制端;小车控制端也需要添加一个蓝牙,用以接受手势控制端发过来的指令。 第一步:基本功能 手势从下到上,小车前进;手势从下到上,小车后退;手势从左到右,小车小车左转;手势从右到左,小车右转。 第二步:蓝牙配置 两块蓝牙之间要实现通信,我们先要给其配置。 本次实验选用的蓝牙模块,波特率均为9600,可以暂时不用配置;记得编写代码的时候波特率写为9600。 在两块蓝牙模块建立连接时,最重要的一个配置就是必须有蓝牙模块是主角色,另一个蓝牙模块设置为从角色;具体配置如下所示。 我们先将蓝牙模块额的AT模式开关拨到ON这一端,然后将其插在USB Serial to 串口上,在连接的时候注意引脚。 接下来我们使用AT指令来配置蓝牙模块。 首先打开Arduino IDE 自带的串口监视器,选择波特率为38400,选择“换行和回车模式”(Both NL&CR)。 然后输入AT(小写也可以),点击发送,会输出OK。 接下来我们需要配置蓝牙的角色,我们将这块蓝牙设置为主角色,设置命令为:AT+ROLE=1;点击发送,会返回OK。 查询蓝牙模块角色,可以使用AT+ROLE?,会返回该角色的类型。 接下来配置另外一块蓝牙,配置方法同上,但是有一点不同,就是蓝牙角色,这块蓝牙的角色要设置为从角色 AT+ROLE=0。 到此为止,蓝牙配置已经完成,然后将其分别插到Romeo控制器的蓝牙端口。 第三步:硬件搭建 (1)将一块Romeo控制器安装到小车上面,并将其电机线分别接在电机接线柱1和2上面,蓝牙模块插到控制器上。 (2)将四个数字防跌落传感器分别接在另外一个Romeo控制器的数字口上面,暂时接在数字口8,9,10,11上面;另外一个块蓝牙模块也插到控制器上。 第四步:编写程序 手势识别控制端程序:
- int k=0;
- void setup() {
- // put your setup code here, to run once:
- for(int i=8;i<11;i++)
- pinMode(i,INPUT);
- Serial.begin(9600);
- }
- void loop() {
- // put your main code here, to run repeatedly:
- if(!digitalRead(8))//手势从上到下,小车前进
- {
- while(k<30)
- {
- k++;
- delay(30);
- if(!digitalRead(9)&&k<30)
- {
- Serial.println("w");
- k=0;
- break;
- }
- if(k==30)
- {
- k=0;
- break;
- }
- }
- }
- if(!digitalRead(9))//手势从下到上,小车后退
- {
- while(k<30)
- {
- k++;
- delay(30);
- if(!digitalRead(8)&&k<30)
- {
- Serial.println("s");
- k=0;
- break;
- }
- if(k==30)
- {
- k=0;
- break;
- }
- }
- }
- if(!digitalRead(10))//手势从左到右,小车左转
- {
- while(k<30)
- {
- k++;
- delay(30);
- if(!digitalRead(11)&&k<30)
- {
- Serial.println("a");
- k=0;
- break;
- }
- if(k==30)
- {
- k=0;
- break;
- }
- }
- }
- if(!digitalRead(11))//手势从右到左,小车右转
- {
- while(k<30)
- {
- k++;
- delay(30);
- if(!digitalRead(10)&&k<30)
- {
- Serial.println("d");
- k=0;
- break;
- }
- if(k==30)
- {
- k=0;
- break;
- }
- }
- }
- }
复制代码
小车控制端程序: - int E1 = 5; //M1 Speed Control
- int E2 = 6; //M2 Speed Control
- int M1 = 4; //M1 Direction Control
- int M2 = 7; //M1 Direction Control
- void stop(void) //Stop
- {
- digitalWrite(E1,LOW);
- digitalWrite(E2,LOW);
- }
- void advance(char a,char b) //Move forward
- {
- analogWrite (E1,a); //PWM Speed Control
- digitalWrite(M1,HIGH);
- analogWrite (E2,b);
- digitalWrite(M2,HIGH);
- }
- void back_off (char a,char b) //Move backward
- {
- analogWrite (E1,a);
- digitalWrite(M1,LOW);
- analogWrite (E2,b);
- digitalWrite(M2,LOW);
- }
- void turn_L (char a,char b) //Turn Left
- {
- analogWrite (E1,a);
- digitalWrite(M1,LOW);
- analogWrite (E2,b);
- digitalWrite(M2,HIGH);
- }
- void turn_R (char a,char b) //Turn Right
- {
- analogWrite (E1,a);
- digitalWrite(M1,HIGH);
- analogWrite (E2,b);
- digitalWrite(M2,LOW);
- }
- void setup() {
- // put your setup code here, to run once:
- for(int i=4;i<8;i++)
- pinMode(i,OUTPUT);
- Serial.begin(9600);
- }
-
- void loop() {
- // put your main code here, to run repeatedly:
- if(Serial.available()){
- char val = Serial.read();
- Serial.println(val);
- if(val != -1)
- {
- switch(val)
- {
- case 'w'://Move Forward
- advance (255,255); //move forward in max speed
- break;
- case 's'://Move Backward
- back_off (255,255); //move back in max speed
- break;
- case 'a'://Turn Left
- turn_L (255,255);
- break;
- case 'd'://Turn Right
- turn_R (255,255);
- break;
- case 'z':
- break;
- }
- }
- }
- }
复制代码
第五步:下载程序,观察现象 怎么样?你的手势有没有控制了你的小车?
|