首页 > 代码库 > 手把手教你做蓝牙小车(一)

手把手教你做蓝牙小车(一)

第1节 选择Arduino开发板

1.1 Arduino是什么

对Arduino,官方有一堆解释。
作为一个软件程序猿,在我眼里,Arduino是学习“可怕硬件”的一个便捷通道。它把复杂的硬件名称,属性给我们隐藏起来,只需要一些简单的软件知识,就可以学习硬件开发。

1.2 怎么选择Arduino开发板

1.2.1 官方版本还是兼容版本

Arduino是开源项目,硬件结构,软件设计都开源。
所以不存在盗版的问题。
官方版质量肯定是杠杠的,但价格也贵。
两者价格数字差不多,一个卖人民币,一个卖美元。
不差钱就买官方版,否则兼容版也不错。

1.2.2 Uno还是Mega

Arduino有一系列各种用途的开发板,最常见的有两种,Uno和Mega。
Uno价格便宜一些,功能简单。
Mega价格比Uno贵二十多块,官方版贵二十多美元,兼容版贵二十多人民币。

大家买Arduino开发板,主要用途就是学习,要求能方便的了解到更多特性。
Uno接口太少,比如做个小车,接了四个马达后,基本就不能再添加其他模块了。
如果你要做个蓝牙小车,调试时噩梦就来了。因为Uno只有一个串口,蓝牙和USB共用。
你的先拔下蓝牙模块的连接线才能上传程序,上传完成后,然后再插上蓝牙连接线才能开始测试。
如果你不只是学习,而是要研发产品,要考虑产品的成本价。。。
选择Mega也任然没有错,你可以现在Mega上完成开发,最后在Uno上做性能测试。

所以,我的建议是选Mega。

第2节 从HelloWorld开始

我记得从学习C语言开始,都是先写个HelloWorld程序。
Arduino我们也从这里开始吧。

2.1 搭建开发环境

官网下载Arduino集成开发环境(以后都简称Arduino IDE)。
解压后,双击此目录下的arduino.exe,启动Arduino IDE。
我这里是以Windows平台为例,Mac,Linux界面、操作基本相同,也可以参照本例学习。

2.2 新建工程

启动Arduino IDE,点击菜单 文件->新建(快捷键Ctrl+N),生成新的工程。

技术分享

点击菜单 文件->保存(快捷键Ctrl+S),保存生成的工程。
文件名这里我填“HelloWorld”,Arduino IDE会生成一个名称叫“HelloWorld”的文件夹,并在这个文件夹下生成一个同名的HelloWorld.ino文件。

技术分享

.ino文件是Arduino工程的主文件,Arduino要求ino文件必须置于一个同名文件夹下

2.3 Hello World

新生成的工程自动生成了setup()loop()两个函数。
我们先改改代码,输出“Hello World”,有点切身感受。稍后再来讲解代码结构。

在setup函数里设置串口波特率

void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
}

用串口输出”Hello world!”

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("Hello world!");
}

点右上角的按钮打开串口监视器(快捷键Ctrl+Shift+m)

技术分享

波特率必须和setup里设置的相同,本例是9600.

可以看到不断输出“Hello world!”

技术分享

2.4 代码结构

HelloWorld.ino文件就两个函数

void setup()

void loop()

它们是怎么运行起来的呢?

看下面这段代码

void setup(void);
void loop(void);

int main(void) {
  setup();

  while(1) {}
    loop();
  }

  return 0;
}

是不是很清楚了。

main和while这些代码去哪了呢?Arduino IDE隐藏了,让我们的代码结构更清晰。
setup()只执行一次,用来放初始化的函数
loop()不断循环执行,用来检查各传感器状态,驱动程序运行。

2.5 Serial

Arduino IDE通过串口和PC(或其他设备)通讯。
在Arduino IDE中Serial就是串口的化身。
注意,Serial是系统对象,不是类,所以使用时直接Serial.begin()。

2.5.1 官网详述

详细内容可以参看官网的描述:
https://www.arduino.cc/en/Reference/Serial
学习Arduino,官网要随时访问。

2.5.2 Serial硬件结构

Uno示例

技术分享

USB接口和0、1引脚都是接Serial

Mega示例

技术分享

USB接口和0、1引脚都是接Serial
18、19引脚是接Serial1
16、17引脚是接Serial2
14、15引脚是接Serial3

第3节 控制LED灯开关

Arduino自带了很多例子。
Blink是其中为数不多的只要有Arduino开发板就可以开始学习的例子。

菜单 文件->示例->01.Basic->Blink打开今天要讲的例子。

3.1 setup函数

void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

学习硬件开发,一个很大的门槛是要记住许多复杂的寄存器地址。
Arduino的NB之处就在于她简化了这许多地址,定义了几种不同类型的硬件插口,称为引脚。
编程时只需要对这几类引脚做操作就可以了。
今天先讲最常用的引脚,DigitalPins。
官网解释如下:
https://www.arduino.cc/en/Tutorial/DigitalPins
简单说就是一种可以输入或输出数字信号0,1的引脚。
某个引脚是用来输入还是输出信号,就通过pinMode函数来定义。

  pinMode(13, OUTPUT);

这段代码的意思是编号为D13的引脚,定义为输出模式。

3.2 为什么是D13引脚?

因为D13引脚连接着一个焊接在Arduino开发板上的LED灯。
所以,如果没有可外接的LED模块,就用D13引脚来做演示。

3.3 loop函数

void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

loop函数总共4行代码

digitalWrite(13, HIGH);

将D13置高,也就是通电。
切记,只有之前将引脚设置为OUTPUT,digitalWrite才能生效。

delay(1000);

延时1秒,在这1秒钟,LED灯状态不变,即点亮状态。

digitalWrite(13, LOW);

将D13置低,也就是断电。

delay(1000);

延时1秒,在这1秒钟,LED灯状态不变,即熄灭状态。
之后loop函数被再次执行,我们看到的现象就是LED灯一秒亮、一秒暗的不停闪烁。

3.4 D13控制的LED灯在哪个位置?

不同的开发板,D13控制的LED灯位置,颜色都略有不同。
相信大多数看官我在下一样,都是搞软件出身的。根本分不清LED灯长啥样:P
开发板连接到上电源(USB线接电脑也算)后,如果只有一个LED灯亮着,这个LED灯旁边肯定有一个“On”标记,这个是表示电源接通的LED灯。
上传本例到开发板后,闪烁的那个就是我们要找到D13 LED灯了。可以在这个LED灯旁看到个‘L’标记。

技术分享

第4节 控制LED灯的亮度

LED灯是最常见的Arduino模块,上一节我们讲了控制Arduino开发板自带的LED灯。
这一节还讲LED灯,讲外接、可控亮度的LED灯。

4.1 PWM

先介绍个概念,Pulse Width Modulation简称PWM。
数字接口只能输出0或1两种状态,PWM通过在0、1两种状态间快速切换,生成一个介于0、1之间的值。
比如1000ms中,平均400ms处于1(高),平均600ms处于0(低),两种状态均匀分布,就输出了一个0.4的值。

详细内容参加官网:
https://www.arduino.cc/en/Tutorial/PWM

4.2 LED模块

你的LED模块可能是这样子

技术分享

也可能是这样子

技术分享

不管长什么样,只要单色可调光LED,都是三根线。
标注字符IN的是控制线、VCC是电源线、GND是地线。

4.3 连接模块

Mega开发板,2-13引脚都支持PWM,随便选一个都可以。

技术分享

Uno开发板,3,5,6,9,10,11引脚支持PWM,可以在开发板上看到引脚数字边上有个’~’。

技术分享

LED灯IN连接到Mega D2引脚;VCC接到Mega 5V引脚;GND接到Mega GND引脚。

技术分享

早期的开发板,为了防止电压不稳定击穿电子器件,需要连接个电阻。
现在的开发板,只在接马达时才需要增加电阻,惯常的做法是增加一块扩展板。

4.4 修改代码

4.4.1 修改引脚

因为这次我们使用了D2引脚,所以需要修改此处的13为2

  pinMode(13, OUTPUT);

还要修改此处的13为2

void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

点击菜单 项目->上传,上传代码到开发板。
可以看到这个外接的LED灯也像内置的LED灯一样闪烁了。

4.4.2 优化代码

刚才我们因为更换引脚,修改了3处代码。
在arduoni开发中,更换引脚是很经常发生的事,常见的做法是在setup函数之前增加宏定义

define LED_PIN 2

void setup() {
...

将代码中的D2相关代码都用LED_PIN替换,以后再更换引脚就很方便了。

4.5 调节LED亮度

4.5.1 调整为固定值

用analogWrite函数控制PWM引脚,第一个参数是引脚序号,第二个是输出到这个引脚的值,范围0~255.
analogWrite(LED_PIN, 10)这行代码使LED灯发出微弱的光。

void loop() {
  analogWrite(LED_PIN, 10);
}

4.5.2 动态调整亮度

我们通过串口输入一个介于0-255的数字来调整LED灯亮度。

本例我们将演示四个Serial对象函数的使用方法。

4.5.1.1 初始化

使用begin()函数在setup函数里设置串口波特率。

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
}

4.5.1.2 检测串口是否有数据输入

Serial.available()返回true表示串口有数据待读取

void loop() {
  while (Serial.available()) {
  ...

4.5.1.3 从串口读入一个long型数字

Serial.parseInt()读取串口中输入的字符串。如果输入的是非数字,会被解析为0.

void loop() {
  while (Serial.available()) {
    Serial.parseInt();

4.5.1.4 改变LED灯亮度

analogWrite()函数用来给模拟接口写入数据。
第一个参数指定引脚序号,第二个参数指定写入引脚的值。

long ledLevel = 10;

void loop() {
  while (Serial.available()) {
    ledLevel = Serial.parseInt();
  }

  analogWrite(LED_PIN, ledLevel);
}

因为analogWrite接受的值在0-255之间,所以代码可以做些优化。
用uint8_t代替long型。

uint8_t ledLevel = 10;

void loop() {
  while (Serial.available()) {
    ledLevel = Serial.parseInt();
  }

  analogWrite(LED_PIN, ledLevel);
}

4.5.1.5 输出Debug信息

print在串口输出参数信息。
println在串口输出参数信息,并回车。

uint8_t ledLevel = 10;
void loop() {
  while (Serial.available()) {
    ledLevel = Serial.parseInt();
    Serial.print("ledLevel=");
    Serial.println(ledLevel);
  }

  analogWrite(LED_PIN, ledLevel);
}

4.5.1.6 串口模拟器设置修改

串口模拟器稍作修改,右下角这里改成“没有结束符”。
否则parseInt会把结束符解析成0,导致LED灯错误熄灭。

技术分享

4.6 测试

技术分享

/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。

*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino编程中购买相关硬件。同时也感谢大家对我们这些码农的支持。

*最后再次感谢各位读者对安豆的支持,谢谢:)
/*******************************************************************/

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    手把手教你做蓝牙小车(一)