Arduino实现方向盘开车

Arduino实现方向盘开车

之前做过一个手势遥控蓝牙小车的,但是感觉这辆车并不炫酷,于是就去开了极品飞车。就像这样

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

QQ图片20160829161236

当然大家也发现了,这个方向盘非常简陋,基本只能实现基本控制功能,我用倾角传感器来读取左右,按键控制油门刹车,以后会进一步做一些改进,到时候会来更新的。

这里简单说明一下原理,就是利用倾角传感器读出现在方向盘角度,向电脑模拟键盘输入来控制极品飞车,但是我手头目前没有Arduino  leonardo这个板子,只有UNO R3。我还是推荐用Arduino Lenoardo这个板子,因为这个可以直接向电脑模拟输出键位,但是UNO也可以通过一些特殊方法来实现,不过比较麻烦。当然,如果你只有UNO的话,就接着往下看看吧。

用到的材料有

UNO R3  *1

ADXL345  *1

按键            *3

10k电阻      *3

杜邦线       若干

ADXL345和Arduino
↑         ADXL345和Arduino

先看读取ADXL345的角度吧,这个部分在上一个教程也有写到,这是一个I2C模块,接法是

ADXL345                 UNO

3.3V        ————   3.3V

GND       ———–    GND

SCL         ———–    A5

SDA        ———–    A4

在Arduino IDE里添加一下ADXL345的库之后直接调用accel.getAcceleration(&ax, &ay, &az)这个函数就可以得到倾角了,十分方便。库的添加方法之前也有说过。

接下来是按键部分,我这里用了3个按键,可以模拟三个按键,键值可以自定义。电路部分很简单,就是普通的开关接法,如下

QQ截图20160829163211

IMG_20160829_154956

 

我用的是大一点的按键开关,这样按起来比较舒适,电阻用的是10k的。每个开关的焊法都是这样,接法就是VCC接VCC GND接GND,另外一个接到Arduino的数字口,我用的是2,4,7这几个口,在程序中一开始有定义,改成自己用的那几个口就行了。消抖我用的是软件延时消抖的方法,写了一个子函数可以拿来调用

int xiaodou(int i)
{   
    int flag=0;
    int now1=digitalRead(i);
    if(now1==0)
    {
      delay(20);
      int now2=digitalRead(i);
       if(now2==0)
          flag=1;
    }
    else
    flag=0;
    return flag; 
}

 

 

至此硬件连接都已经好了,剩下就是软件方面的了,如果你是Leonado,那可以直接调用模拟键盘的函数,具体用法网上很多,善用搜索;如果你是UNO的板子,接下来就还要做一些操作。首先,UNO是可以通过给板子上那块Atmel 16u2重新烧写hex文件实现模拟键盘功能的,需要配个usbkeyboard库文件,这个我在后面也有上传。但是这个烧写hex文件和平时烧写代码方法不一样,需要进入dfu模式,如果是正版uno可以试试短接一下这两个引脚,但是我手上的都不能,可能是因为国产的原因。

QQ图片20160829164726

这里我介绍一下我用的方法,参考了这篇帖子http://www.cnblogs.com/LittleTiger/p/4825749.html,我用的是USBASP下载器,如果你是其他下载器例如USBtiny可以搜索一下使用方法。

首先要安装USBASP的驱动,有些电脑可能会因为驱动签名问题无法安装,可以用无视驱动签名强制安装的办法,具体自行搜索一下,这里不做过多讨论。烧录软件推荐使用progisp这个 ,这些我在文章结尾都会上传的。建议买USBASP下载器的时候买一个10pin转6pin的转接板,也不贵,因为这个用杜邦线插的时候容易搞混引脚。

下载流程如下

QQ截图20160829213416

QQ截图20160829213554
第四步配置熔丝位的具体数值

QQ截图20160829213951第五步调用的hex文件

 

关于usbkeyboard的库文件,网上现在的版本功能比较多,我看了一下,有很多功能好像我都用不到。。。于是我就把那些全都注释掉了,如果你需要原版的可以上网自行下载。我去看了一下HID的实现,个人理解不知道对不对,这里有一个8位的数组,前面一位代表一些功能按键,ctrl shift之类的每个键占用一个bit,数组第一位可以表示8个按键的状态11111111代表全部按下,第二位不知道有啥用,后面的六位可以代表一些普通按键,比如第三位是4,那就代表A被按下去,具体映射查看hid_keys.h文件。再比如这个数组全都是0的时候代表没有按键被按下。这是从论坛里找到的一张图片,其实去仔细研究一下原版的库文件就可以理解这个实现的功能了。为了单独控制每个按键,我就直接对数组的一位进行操作,比如按下A键就是sendKey[7]=KEY_A;释放A键就是 sendKey[7]=0;

哦对了,很重要的一点,当uno刷了新的hex模拟键盘状态的时候是不能下载程序的,如果要改动程序,需要下载回原来的hex,下载完代码再烧入keyboard的那个hex。。这就是为啥我推荐用Leonardo的原因。而且我发现我模拟shift是正常的模拟ctrl就不正常,不知道是不是uno兼容性原因还是啥的锅。。

最后贴上我的源代码,代码写的不好,请多包涵

#include<USBKeyboard.h>
#include "Wire.h"
#include "I2Cdev.h"
#include "ADXL345.h"
ADXL345 accel;
int16_t ax, ay, az;
int up=2;
int ctrl=7;
int shift=4;
int i=5;
int val1,val2,val3;
uint8_t sendKey[8]={0,0,0,0,0,0,0,0};            //这个就是发送的那个数组
void setup() 
{
   Wire.begin();
   Keyboard.init();
   accel.initialize();
   accel.testConnection();
   readstate();
   xiaodou(i);
   pinMode(up,INPUT);
   pinMode(ctrl,INPUT);
   pinMode(shift,INPUT);
}

void loop() 
{  
    val1=xiaodou(up);
    val2=xiaodou(ctrl);
    val3=xiaodou(shift);
    i=readstate();

    if(val1==1)
      sendKey[6]=KEY_UP_ARROW;
    else
      sendKey[6]=0;
    if(val2==1)
      sendKey[0]=0x02;
    else
      sendKey[0]=0;
    if(val3==1)
      sendKey[7]=KEY_A;
    else
      sendKey[7]=0;
    switch(i)
    {
      case 4:   sendKey[4]=KEY_LEFT_ARROW;           //按下方向左
                sendKey[5]=0;                        //同时释放方向右
                break;
      case 6:   sendKey[4]=0;
                sendKey[5]=KEY_RIGHT_ARROW;                
                break;
      case 5:   sendKey[4]=0;
                sendKey[5]=0;              
                break;
     }
    Serial.write(sendKey,8);
}
int readstate()
{
    int a;
    accel.getAcceleration(&ax, &ay, &az);
    if(ay>80)         //向右倾斜
    a=6;
    else if(ay<-80)        //向左倾斜
    a=4;
   else
    a=5; 
    return a;
}
int xiaodou(int i)
{   
    int flag=0;
    int now1=digitalRead(i);
    if(now1==0)
    {
      delay(20);
      int now2=digitalRead(i);
       if(now2==0)
          flag=1;
    }
    else
    flag=0;
    return flag; 
}

文章中所要用到到文件打包下载方向盘需要资料

====================写在最后=========================

这个东西呢现在只是一个雏形,很多地方还不完善,大家可以进行改良,有什么好的意见和建议都可以到下沙创客空间群讨论492086387  备注一下最好。

 

 



发表评论