您的位置:首页 > 产品设计 > UI/UE

Arduino的模数转换(以Arduino读取摇杆信息为例)——人人都能玩硬件

2017-04-10 15:53 477 查看
本文主要解决一下几个问题:

1 单片机中的信息是如何表达的

2 什么是模数转换

3 Arduino如何做模数转换

4 实操 —— Arduino读取摇杆信息

单片机中的信息是如何表达的

我们都知道,计算机实际上只是几块电路板。那么计算机是如何在这些芯片和电子元件上做计算的呢?或许你知道计算机只识别0和1,而且你或许还知道高电平表示1,低电平表示0。

什么是模数转换

计算机中,我们可以简单的理解这些0和1组成的信号是数字信号(这是很不严谨且不算正确的说法,这里为了便于理解,我们先这么说了,有兴趣的可以自己了解详细定义),与数字信号相对的是模拟信号,我们常常也需要收发模拟信号,比如播放音乐,使用话筒,随意调整光线亮度(随意调整,也就是任何亮度,而不是分段的那种),称重,测量压力,测量电压或者电流或者电阻。这是比较直观的,此外还有一些可能你不太了解的,比如热释电红外传感器(他通常用来做人体检测传感器) ,火焰传感器,红外测距,磁场传感器等等。还有游戏手柄上的摇杆。

在这些场合下,我们就需要对信息做个数模转换或这模数转换,所谓数模转换就是将数字信号变模拟信号,模数转换就是模拟信号变数字信号。

Arduino如何做模数转换

对于Arduino UNO,有6个专门用于AD转换的引脚(A0-A5),任何传感器,输出的模拟信号无非是电压信号或者电流信号,其中,电压信号各类传感器模块中更常见,arduino可以将电压信号转换为用10bit表示的数值。量程是0-5V,也就是说最大值是2^10-1=1023,最小值是0

先了解一个函数

int analogRead ( uint8_t ) :这是arduino的一个模数转换函数,括号里可以填模拟信号输入口,这里我们用的Arduino UNO ,我们就可以填0-5分别对应Arduino UNO的A0-A5口(他们就在单片机上,和其他针脚排在一起,位置很明显)。他的返回值就是模拟信号转换的数字值,这个数值占10bit,也就是说模数转换的最大值是1023(二的十次方减一)代表5V,最小值是0代表0V,需要注意的是你的Arduino的模数转换可能并不灵敏,不准确,后面我会写使用I2C通信接口的AD芯片ADXL345,它结合Arduino可以提供更精确,更灵敏模数转换。如果还是不理解,没关系,你再看看下面的代码,或许能理解了。

我们再来了解摇杆的工作原理

摇杆实际上是两个电位器和一个微动按钮,所谓电位器你可以理解为圆形的滑动电阻,所谓微动按钮就是普通的按钮,但是它不能保持按下状态,也就是说,按下去以后,手一松开,他就自自动弹起了。

实操 —— Arduino读取摇杆信息

在正式上手之前我们需要了解了两个点(analogRead函数,摇杆基本原理)
/**************************************************************************

Copyright:FUNCO_小风

Author: FUNCO_小风

Date:2017-04-10

Description:从串口A0 A1 GPIO12 口读入摇杆数据并通过串口输出

**************************************************************************/

/* 定义串口发送编码 */
#define CAR_ADVANCE '1'
#define CAR_BACK '2'
#define CAR_LEFT '3'
#define CAR_RIGHT '4'
#define CAR_STOP '0'

/*************************************************
Function: void get_rocker(int *buff)
Description: 获取摇杆按钮状态(12针) x轴数据(A0针) y轴数据(A1) 并存储于
Calls: digitalRead()
analogRead()
Table Accessed: // 被访问的表(此项仅对于牵扯到<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库" target='_blank' style='color:#df3434; font-weight:bold;'>数据库</a>操作的程序)
Table Updated: // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input: buff 整型指针,获取一个指向3*sizeof(int)大小的存储空间
Output: buff[0] 摇杆是否被按下 1-按钮未按下 0-按钮被按下
buff[1] 存储y轴数据 max=2^10-1=1023 min=0
buff[2] 存储x轴数据 max=2^10-1=1023 min=0
Return: void
Others: void
*************************************************/
void get_rocker(int *buff)
{
buff[0]=digitalRead(12);
buff[1]=analogRead();
buff[2]=analogRead(0);
}

void setup() {
Serial.begin(115200);
pinMode(12,INPUT);
digitalWrite(12,HIGH);//上拉
}

void loop() {
int rocker_data[3]; //用于临时存储摇杆x轴y轴以及switch状态

get_rocker(rocker_data); //传递存储摇杆状态的数组首地址

//判断摇杆y轴状态 >这里定义>600表示正推 <300表示反推
if(rocker_data[1]>600){
Serial.println(CAR_LEFT);
}else if(rocker_data[1]<300) {
Serial.println(CAR_RIGHT);
}
//判断摇杆x轴状态 >这里定义>600表示正推 <300表示反推
if(rocker_data[2]>600){
Serial.println(CAR_BACK);
}else if(rocker_data[2]<300) {
Serial.println(CAR_ADVANCE);
}
//判断摇杆按钮状态 当按钮被按下,读取值为0 则经过逻辑非'!'运算取非,值变为真(0为假),则串口输出数据
if(!rocker_data[0]){
Serial.println(CAR_STOP);
}
//一般玩家手指反应时间长于100ms,因此定义延时100ms
//建议定义延时是为了避免串口发送保持忙碌,给接收端处理数据时间
//具体延时时间视情况而定
delay(100);
}
实物如下





运行结果如下



在上面代码中,可以注意到,我读数取的是范围值,而不是具体值,比如当摇杆的Y轴读数>600我便当摇杆正推,是因为我发现Arduino的模数转换并不灵敏,不准确,后面我会推荐一款使用I2C通信接口的AD芯片ADXL345,它结合Arduino可以提供更精确,更灵敏模数转换。

这里顺带一提,摇杆的使用不要太死脑筋,怎样算左怎样算右,怎样算前怎样算后,完全看你的代码怎么定义,摇杆只能提供X轴和Y轴方向的模拟信号而已。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息