14、搭建外部 LED 及掌握 Arduino 编程基础

搭建外部 LED 及掌握 Arduino 编程基础

1. 外部 LED 设计

1.1 电压限制的必要性

在搭建第一个小装置时,使用电阻来限制电压以制作合适的外部 LED 至关重要。Arduino 引脚稳定输出 5.0V 电压,但不同颜色的 LED 所需电压仅为 2V 到 3.5V,且只消耗约 15mA 的电流。例如,红色 LED 通常需要约 2.5V,黄色 LED 可能需要 2.8V,绿色 LED 则可能需要高达 3.4V。如果不进行电压限制,过高的电压可能会损坏 LED。

1.2 电阻计算

我们可以使用 Python 函数来计算所需电阻。计算公式为 (R = \frac{V_s - V_{led}}{I_{led}}),其中 (V_s) 是电源电压,(V_{led}) 是 LED 所需电压,(I_{led}) 是 LED 消耗的电流。以下是相应的 Python 代码:

def LED_R( V_led, I_led=.015, V_s=5.0):
    """LED resistor required to reduce V_s to V_led."""
    R = (V_s-V_led)/I_led
    R = std_resistor(R)
    print( "V_s={V_s:.1f}V, V_led={V_led:.1f}V,"
          " I_led={I_led:.3f}A, R={R:.0f}Ω".format_map(vars()))

1.3 标准电阻值

计算出的电阻值可能不是标准值,因此需要将其转换为标准电阻值。10% 公差的电阻值遵循国际标准,每十年(10 的幂)被分为 12 个步骤。以下是标准电阻值列表:

E12 = (1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2) 

我们可以使用以下 Python 函数来计算合适的标准电阻:

import math

def std_resistor(r, series=E12):
    # 1. What decade?
    decade= 10**(int(math.log10(r)))
    # 2. R value within the decade.
    r_d= r/decade
    # 3. What are the bracketing values?
    above= decade*min( s for s in series if s >= r_d )
    below = decade*max( s for s in series if s <= r_d )
    # 4. Pick closest value.
    if (above-r)/r <= (r-below)/r: return above
    return below

2. 组装工作原型

2.1 工程图与面包板设置

我们可以使用 Fritzing 软件绘制工程图,图中 Arduino 处理器用大矩形表示,引脚分布在外部;LED 用带线和箭头的小三角形表示,并标注电流负载和颜色;电阻用波浪线表示,并标注所需电阻值。

在面包板上搭建电路时,需要使用两根跳线连接 Arduino 和面包板,将电阻的引脚弯曲后插入面包板,将 LED 的阳极连接到电阻,阴极连接到 Arduino 的接地端。

2.2 电阻颜色编码

对于新手来说,电阻的颜色编码可能会让人困惑。电阻的颜色编码规则如下:前两个色带表示电阻值的前两位数字,第三个色带表示十位数,第四个色带通常为银色,表示 10% 公差的电阻。

2.3 LED 极性

LED 是二极管,电流只能单向流动。如果插反,LED 将无法工作,这是面包板电路设置中常见的错误。

3. 掌握 Arduino 编程语言

3.1 基础语法差异

Arduino 编程语言基于 C++,与 Python 有一些语法差异。例如,Arduino 使用 {} 来标识代码块,而不是 Python 的缩进;Arduino 语句以 ; 结尾,而 Python 语句在行尾或匹配的 () [] {} 结束。

3.2 数据类型

Arduino 有多种整数类型,包括 boolean char byte int unsigned int long unsigned long 。我们需要根据所需值的范围选择合适的数据类型,以节省内存。此外,Arduino 支持 float double 浮点值,但应尽量减少使用,因为它们会消耗大量存储空间。

3.3 运算符

Arduino 支持常见的算术运算符( + - * / % )和位运算符( & | ~ >> << ),逻辑运算符为 && || ! ,比较运算符与 Python 相同。此外,Arduino 还提供 ++ -- 运算符,但使用时需要注意语义。

3.4 处理语句

Arduino 有赋值语句、增强赋值语句( += -= |= 等)、条件语句( if-else if-else switch )和循环语句。建议使用 if-else if-else 语句,避免使用 switch 语句,以减少调试难度。以下是一个 Arduino if-else if-else 语句的示例:

if( push >= 2000 ) {
  // 2 second press.
  digitalWrite( BUTTON_LED, HIGH );
}
else if ( push >= 500 ) { 
  // 0.5 sec press.
  digitalWrite( BUTTON_LED, LOW );
}
else { 
  // too short.
}

4. 开发周期与优化

4.1 开发周期

Arduino 的开发周期为 Edit-Compile-Test-Break 循环,具体步骤如下:
1. 在 Arduino IDE 或 Fritzing 代码标签中创建或修改草图。
2. 将草图下载到开发板,编译草图并报告语法错误。如果草图有效,将其传输到开发板,开发板将自动重置并开始运行。
3. 测试开发板是否正常工作,观察 LED、按下按钮、转动旋钮或在距离传感器前挥手等。
4. 如果出现问题,通过更改硬件组件或编写不同的软件来修复。如果有新的功能想法,可以重新开始循环。

4.2 优化闪烁 LED

传统的闪烁 LED 草图使用 delay(1000) 函数暂停 1 秒,这会导致装置响应不及时。我们可以使用 millis() 函数来优化闪烁 LED,使其能够与其他操作并行执行。以下是优化后的代码:

const int LED=13; // the on-board LED
void setup() {
    pinMode( LED, OUTPUT );
}
void loop() {
    // Other Work goes here.
    heartbeat();
}
// Blinks LED 13 once per second.
void heartbeat() {
  static unsigned long last= 0;
  unsigned long now= millis();
  if (now - last > 1000) {
    digitalWrite( LED, LOW );
    last= now;
  }
  else  if (now - last > 900) {
    digitalWrite( LED, HIGH );
  }
}

通过以上步骤,我们可以设计并组装一个外部 LED 装置,掌握 Arduino 编程语言的基础知识,并优化闪烁 LED 的代码,使其更加高效和响应灵敏。

以下是一个 mermaid 流程图,展示了 Arduino 开发的基本流程:

graph LR
    A[创建或修改草图] --> B[编译草图]
    B --> C{是否有语法错误?}
    C -- 是 --> A
    C -- 否 --> D[传输到开发板]
    D --> E[测试开发板]
    E --> F{是否正常工作?}
    F -- 否 --> G[修复问题]
    G --> A
    F -- 是 --> H[有新功能想法?]
    H -- 是 --> A
    H -- 否 --> I[完成]

此外,我们还可以使用表格总结 Arduino 和 Python 的语法差异:
| 特性 | Python | Arduino |
| ---- | ---- | ---- |
| 代码块标识 | 缩进 | {} |
| 语句结束符 | 行尾或匹配的 () [] {} | ; |
| 注释 | # | // /* */ |
| 逻辑运算符 | and or not | && || ! |
| 比较运算符 | 2 <= a < 10 | (2 <= a) && (a < 10) |

4. 深入探讨 Arduino 编程与应用

4.3 变量作用域与存储类型

在 Arduino 编程中,变量的作用域和存储类型十分重要。变量的作用域决定了它在代码中可被访问的范围,而存储类型则影响着变量的生命周期和存储位置。

Arduino 中有两种主要的存储类型:静态存储和自动存储。静态存储的变量使用 static 关键字声明,如在前面的 heartbeat() 函数中的 last 变量。静态变量在函数调用之间保持其值,不会在每次函数执行时重新初始化。而自动存储的变量则在函数每次执行时创建和销毁,例如 heartbeat() 函数中的 now 变量。

以下是一个简单的示例,展示了静态变量和自动变量的区别:

void setup() {
  Serial.begin(9600);
}

void loop() {
  static int staticVar = 0;
  int autoVar = 0;

  staticVar++;
  autoVar++;

  Serial.print("Static Variable: ");
  Serial.println(staticVar);
  Serial.print("Auto Variable: ");
  Serial.println(autoVar);

  delay(1000);
}

在这个示例中, staticVar 会在每次 loop() 函数执行时递增,而 autoVar 每次都会被初始化为 0,然后递增到 1。

4.4 中断处理

Arduino 提供了中断处理机制,允许在特定事件发生时立即执行一段代码,而不必等待主循环的正常执行。中断可以提高程序的响应速度,特别是在需要实时处理某些事件的情况下。

要使用中断,首先需要选择一个支持中断的引脚。在 Arduino Uno 上,引脚 2 和 3 支持外部中断。以下是一个简单的中断处理示例:

const int interruptPin = 2;
volatile int state = LOW;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
}

void loop() {
  digitalWrite(LED_BUILTIN, state);
}

void blink() {
  state = !state;
}

在这个示例中,当引脚 2 上的信号从高电平变为低电平时,会触发 blink() 函数,该函数会切换 LED 的状态。

4.5 传感器与数据采集

Arduino 常用于传感器数据采集。不同类型的传感器可以测量各种物理量,如温度、湿度、光照强度等。要采集传感器数据,通常需要进行以下步骤:

  1. 连接传感器 :将传感器的引脚连接到 Arduino 的相应引脚。
  2. 配置引脚模式 :根据传感器的要求,将连接引脚设置为输入或输出模式。
  3. 读取传感器数据 :使用相应的函数读取传感器输出的数值。

以下是一个简单的光照传感器数据采集示例:

const int lightSensorPin = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int lightLevel = analogRead(lightSensorPin);
  Serial.print("Light Level: ");
  Serial.println(lightLevel);
  delay(1000);
}

在这个示例中,光照传感器连接到模拟引脚 A0,通过 analogRead() 函数读取传感器的输出值,并将其打印到串口监视器上。

5. 项目示例:智能环境监测系统

5.1 项目概述

我们可以基于前面所学的知识,构建一个智能环境监测系统。该系统可以实时监测环境的温度、湿度和光照强度,并通过串口将数据传输到计算机。

5.2 硬件连接

  • 温度湿度传感器(DHT11) :数据引脚连接到 Arduino 的引脚 2。
  • 光照传感器 :连接到模拟引脚 A0。

5.3 代码实现

#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

const int lightSensorPin = A0;

void setup() {
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  int lightLevel = analogRead(lightSensorPin);

  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print("%  Temperature: ");
  Serial.print(temperature);
  Serial.print("°C  Light Level: ");
  Serial.println(lightLevel);

  delay(2000);
}

5.4 项目流程

以下是项目的 mermaid 流程图:

graph LR
    A[初始化系统] --> B[读取温度湿度]
    B --> C[读取光照强度]
    C --> D[传输数据到串口]
    D --> E{是否继续?}
    E -- 是 --> B
    E -- 否 --> F[结束]

6. 总结与展望

6.1 知识回顾

通过本文,我们学习了如何设计和组装外部 LED 装置,掌握了 Arduino 编程语言的基础知识,包括语法差异、数据类型、运算符、处理语句等。我们还了解了 Arduino 的开发周期和优化技巧,以及如何使用中断处理和传感器进行数据采集。最后,我们通过一个智能环境监测系统的项目示例,将所学知识应用到实际项目中。

6.2 未来应用

Arduino 的应用场景非常广泛,除了环境监测,还可以用于机器人控制、智能家居、工业自动化等领域。随着物联网技术的发展,Arduino 作为一个开源的硬件平台,将在更多的领域发挥重要作用。

6.3 学习建议

对于想要深入学习 Arduino 的读者,建议多做项目实践,通过实际操作来加深对知识的理解。同时,可以参考官方文档和社区论坛,获取更多的学习资源和经验分享。

以下是一个表格,总结了 Arduino 编程中的一些关键知识点:
| 知识点 | 描述 |
| ---- | ---- |
| 数据类型 | boolean char byte int unsigned int long unsigned long float double |
| 运算符 | 算术运算符( + - * / % )、位运算符( & | ~ >> << )、逻辑运算符( && || ! )、比较运算符 |
| 处理语句 | 赋值语句、增强赋值语句、 if-else if-else 语句、 switch 语句、循环语句 |
| 存储类型 | 静态存储( static )、自动存储 |
| 中断处理 | 使用 attachInterrupt() 函数设置中断 |

希望本文能帮助你快速入门 Arduino 编程,开启你的物联网之旅!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值