基于Arduino的简易密码锁实验(含C语言循环函数拓展)
文章目录
一、 实验效果展示
在深入代码之前,我们先看看这个“按键计数密码锁”是如何工作的。
功能描述:
- 系统设定了一个密码(例如按 12 次)。
- 用户通过按键输入次数。
- 如果次数正确,LED慢闪2次表示验证成功。
- 如果次数超过限制(例如超过10次),LED快闪5次表示报警/锁定。

二、 硬件准备与接线
1. 实验材料
- Arduino Uno 开发板 x 1
- 按键开关 (微动开关) x 1
- LED发光二极管 x 1
- 220Ω 电阻 x 1 (用于LED限流)
- 杜邦线 若干
2. 接线原理
根据代码 pinMode(KEY_PIN, INPUT_PULLUP); 分析,我们使用的是内部上拉模式。
- LED:正极接 Pin 9,负极串联电阻接 GND。
- 按键:一脚接 Pin 4,另一脚直接接 GND。(注意:虽然代码使用的是内部上拉,但如果你参考的图片中使用了外部下拉电阻接法,请确保代码逻辑与接线电平匹配。本代码逻辑是:按下=LOW)。
3. 接线示意图

三、 实验代码实现
以下是本实验的核心代码。该程序通过计算按键按下的次数来与预设密码进行比对。
#define INPUT_MAX_TIME 10 // 最大输入次数限制
const int PASSWORD = 12; // 设置的密码值(按键按下12次)
const int LED_PIN = 9; // LED指示灯引脚
const int KEY_PIN = 4; // 按键输入引脚
int current_password = 0; // 当前输入的密码值(按键累计次数)
int press_count = 0; // 按键按下次数计数器(用于判断最大输入次数)
// 函数声明
void led_flash(int times, int interval); // LED闪烁函数
void reset_system(); // 系统重置函数
void setup() {
pinMode(LED_PIN, OUTPUT); // 设置LED引脚为输出模式
pinMode(KEY_PIN, INPUT_PULLUP); // 按键使用内部上拉电阻(按下时为LOW)
digitalWrite(LED_PIN, LOW); // 初始状态:关闭LED
Serial.begin(9600); // 初始化串口通信
Serial.println("密码验证系统就绪");
Serial.print("设定密码:");
Serial.println(PASSWORD);
Serial.println("请按按键输入密码(累计按下次数=密码值)");
}
void loop() {
// 检测按键是否被按下(内部上拉电阻,按下时为LOW)
if (digitalRead(KEY_PIN) == LOW) {
delay(20); // 延时消抖
// 等待按键松开(死循环等待,直到松手)
while (digitalRead(KEY_PIN) == LOW);
// 按键有效,计数增加
current_password++;
press_count++;
// 串口打印当前状态
Serial.print("当前输入密码(按键次数):");
Serial.println(current_password);
Serial.print("剩余输入次数:");
Serial.println(INPUT_MAX_TIME - press_count);
// --- 逻辑判断区域 ---
// 1. 密码正确判断
if (current_password == PASSWORD) {
Serial.println("=== 密码正确! ===");
led_flash(2, 500); // 成功:慢闪2次
reset_system(); // 重置
}
// 2. 超过最大输入次数判断
else if (press_count >= INPUT_MAX_TIME) {
Serial.println("=== 错误:输入次数已达上限! ===");
led_flash(5, 500); // 失败:快闪5次
reset_system(); // 重置
}
}
}
/**
* LED闪烁工具函数
*/
void led_flash(int times, int interval) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH);
delay(interval);
digitalWrite(LED_PIN, LOW);
delay(interval);
}
}
/**
* 系统重置函数
*/
void reset_system() {
current_password = 0;
press_count = 0;
Serial.println("系统已重置,请重新输入密码");
Serial.println("------------------------");
}
四、 拓展一:代码逻辑缺陷与优化
仔细观察上面的代码,细心的同学可能会发现一个致命的逻辑冲突。
1. 存在的问题
- 设定密码:
const int PASSWORD = 12; - 最大限制:
#define INPUT_MAX_TIME 10 - 冲突点:用户想要输入密码12,必须按12次。但是,当用户按到第10次时,代码会触发
else if (press_count >= INPUT_MAX_TIME),直接报错重置系统。 - 后果:这个密码永远无法解开! 这是一个典型的逻辑设计漏洞。
2. 优化方案
我们需要修改最大输入次数,使其大于密码值,或者修改密码值使其小于最大次数。同时,我们可以增加一个“超时重置”或者“确认键”的功能,让交互更人性化。
修改建议:
// 修正逻辑错误
#define INPUT_MAX_TIME 15 // 将最大次数改为15,大于密码12
const int PASSWORD = 12;
五、 拓展二:C语言 if-else 配对原则详解
在代码编写中,if-else 的嵌套使用非常频繁,初学者很容易搞混配对关系。
1. 配对原则(就近原则)
C语言规定:else 总是与它上面最近的、未配对的 if 进行配对。
这与代码的缩进无关!缩进只是为了给人看,编译器只认逻辑。
2. 经典错误示例
int a = 1, b = 2;
if (a == 0)
if (b == 2)
printf("b is 2");
else
printf("a is not 0"); // 你的意图可能是这个else对应第一个if
实际运行结果:什么都不输出。
原因:
- 因为
a=1,第一个if不成立。 - 根据就近原则,那个
else其实是属于第二个if (b==2)的。 - 既然第一个
if都没进去,里面的if-else整体都不会执行。
3. 如何避免?
永远使用大括号 {}! 即使只有一行代码。
if (a == 0) {
if (b == 2) {
printf("b is 2");
}
} else {
printf("a is not 0"); // 现在逻辑正确了
}
六、 拓展三:折纸挑战(While 与 For 循环实战)
问题描述:
有一张厚度为 0.1毫米 的纸。假设纸张足够大,可以无限次折叠。问:需要折叠多少次,其厚度才能超过 珠穆朗玛峰 的高度(8848.86米)?
单位换算:
- 纸张厚度:0.1 mm
- 珠峰高度:8848.86 m = 8848860 mm
1. 使用 while 循环实现
while 循环适用于**“不知道要循环多少次,只知道停止条件”**的场景。
#include <stdio.h>
int main() {
double paper = 0.1; // 纸张初始厚度 (mm)
double everest = 8848860.0; // 珠峰高度 (mm)
int count = 0; // 折叠次数
// 当 纸张厚度 < 珠峰高度 时,继续循环
while (paper < everest) {
paper = paper * 2; // 每次折叠,厚度翻倍
count++; // 次数加1
}
printf("使用while循环计算:需要折叠 %d 次\n", count);
printf("最终厚度为:%.2f mm\n", paper);
return 0;
}
2. 使用 for 循环实现
for 循环通常用于已知次数,但也可以通过省略条件或配合 break 来实现未知次数的循环。
#include <stdio.h>
int main() {
double paper = 0.1;
double everest = 8848860.0;
int count;
// for(初始化; 条件; 迭代)
// 这里我们将厚度计算放在循环体内,条件放在中间
for (count = 0; paper < everest; count++) {
paper *= 2; // 厚度翻倍
}
printf("使用for循环计算:需要折叠 %d 次\n", count);
return 0;
}
计算结果剧透:
如果你运行上述代码,答案应该是 27次。这告诉我们指数增长的恐怖力量!
结语
通过这个实验,我们不仅实现了一个简单的密码锁,还发现了代码中隐藏的逻辑陷阱,并复习了C语言中重要的控制结构。编程不仅仅是写代码,更是逻辑思维的锻炼。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)