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

来源:互联网 发布:二级域名推广淘宝客 编辑:程序博客网 时间:2024/06/03 07:17

本文主要解决一下几个问题:

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-10Description:从串口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=0Return: voidOthers: 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轴方向的模拟信号而已。

1 0
原创粉丝点击