首页 / 资讯中心 / 文章详情

基于Arduino的计算器:LCD与矩阵键盘的完整实现指南

基于Arduino的计算器:LCD与矩阵键盘的完整实现指南 ★ FEATURED ARTICLE
1. 从零搭建 Arduino 计算器LCD1602 与 4x4 矩阵键盘怎么接线如果你手上有一块 Arduino Uno、一块 LCD1602 液晶屏、一个 4x4 薄膜矩阵键盘那么这篇文章就是为你准备的。我们要做的事情很具体把这三样东西连起来写一段能跑的四则运算代码最后在屏幕上按出3.14 * 2 6.28。整套流程不需要额外的扩展板也不需要焊接面包板加杜邦线就能完成。适合刚接触嵌入式交互、想做一个“看得见摸得着”的小项目的开发者。先明确一下这个计算器能做什么支持加、减、乘、除四种运算支持小数点和负数输入结果实时显示在 LCD1602 的两行屏幕上。它不适合做科学计算也不适合替代手机计算器但它是理解“输入设备 处理逻辑 输出设备”这条链路的最佳练手项目。矩阵键盘负责把物理按键变成字符Arduino 负责解析字符并维护运算状态LCD 负责把状态反馈给你。三者缺一不可。在动手之前你需要准备这些材料Arduino Uno 或 Nano 一块、LCD1602带 I2C 转接板也可以但本文按并行接口讲因为并行接口更能看清引脚对应关系、4x4 矩阵键盘一个、10kΩ 电位器一个调 LCD 对比度、面包板一块、杜邦线若干。软件方面Arduino IDE 1.8.x 或 2.x 都可以需要安装两个库LiquidCrystalIDE 自带和Keypad需要在库管理器里搜索安装。接线是整个项目里最容易出错的一步我把它拆成两张表来看。LCD1602 采用 4 位数据模式只需要 6 根信号线加电源和对比度调节。矩阵键盘 4 行 4 列共 8 根线行接数字引脚列接模拟引脚当作普通数字引脚用。具体对应关系如下LCD1602 引脚功能Arduino 引脚RS寄存器选择12E使能11D4数据位410D5数据位59D6数据位68D7数据位77VSS地GNDVDD电源5VV0对比度电位器中间脚A背光正5V串220ΩK背光负GND矩阵键盘功能Arduino 引脚R1第1行5R2第2行4R3第3行3R4第4行2C1第1列A3C2第2列A2C3第3列A1C4第4列A0这里有一个细节值得注意列引脚接在 A0–A3 上并不是因为要用模拟输入功能而是因为 Uno 的数字引脚不够用了。在Keypad库里模拟引脚可以直接当数字引脚使用写A3和写17是等价的。电位器的另外两个脚分别接 5V 和 GND中间脚接 LCD 的 V0这样旋转电位器就能调节字符对比度。如果上电后屏幕只亮背光但不显示字符九成是对比度没调好。接线完成后先不要急着写完整计算器代码。我建议你分两步验证第一步只让 LCD 显示一行字确认接线和对比度没问题第二步只让键盘通过串口打印按键值确认行列映射正确。这两步都通过了再合并成计算器。很多新手一上来就把所有代码烧进去结果屏幕不亮、按键没反应根本不知道是哪一段出了问题。分步验证能帮你快速定位故障点。2. TaoToken 前置准备给计算器项目加一个模型对话入口你可能会问一个 Arduino 计算器项目为什么需要 TaoToken答案很简单当你的代码编译报错、按键映射对不上、或者你想让模型帮你解释Keypad库的扫描原理时有一个稳定的模型对话入口会省很多时间。TaoToken 在这里扮演的角色是“开发过程中的辅助工具”而不是计算器本身的组成部分。计算器跑在 Arduino 上TaoToken 跑在你的浏览器或终端里两者互不干扰。TaoToken 是一个大模型 API 聚合平台你可以把它理解成一个统一的接口层它把不同模型的调用方式统一成 OpenAI 兼容格式你只需要一个 Base URL 和一个 API Key就能在代码里调用模型。对于嵌入式开发者来说最实用的场景有三个一是让模型帮你审查 Arduino 代码里的逻辑漏洞二是让模型解释报错信息三是让模型根据你的接线表生成按键映射数组。这些都不需要你本地跑模型有网络和 Key 就行。前置准备分三步。第一步打开官网注册账号地址是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。注册完成后进入控制台地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite。在控制台里你可以看到自己的账户状态和额度信息。第二步创建 API Key入口在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。创建时建议给 Key 起一个容易识别的名字比如arduino-calc-debug方便以后区分用途。Key 只显示一次复制后先存到安全的地方。第三步确认你要调用的模型 ID。TaoToken 支持多种模型具体可用列表可以在文档里查文档地址是https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。对于代码审查和报错解释这类任务选一个擅长代码的模型即可。如果你只是偶尔问几个问题用模型对话页面就够了地址是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite。如果你打算长期在编辑器里用模型辅助写代码可以了解 Coding Plan地址是https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。这里要强调一点TaoToken 的 API 地址是https://taotoken.net/api这个地址不加任何 UTM 参数直接用于代码里的 Base URL。很多人在配置时把带 UTM 的官网地址填进代码结果请求失败就是因为 Base URL 和推广链接是两回事。记住这个区分浏览器里点推广链接用带 UTM 的代码里写 Base URL 用https://taotoken.net/api。配置好 Key 之后你可以先用一个最简单的 curl 请求验证连通性。在终端里执行下面这段命令把YOUR_API_KEY替换成你刚创建的 Key把MODEL_ID替换成你要用的模型 IDcurl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_API_KEY \ -d { model: MODEL_ID, messages: [ {role: user, content: 用一句话解释Arduino Keypad库的扫描原理} ] }如果返回的 JSON 里有choices字段和模型回复内容说明 Key 和网络都没问题。如果返回 401说明 Key 不对或没带上如果返回 404检查 Base URL 是不是写成了带路径的完整地址。这一步验证通过后你就可以在后续开发中随时用模型来辅助排查问题了。3. 可复制配置LCD1602 与矩阵键盘的完整代码与参数这一节是整篇文章的核心我会把完整的 Arduino 代码、库配置和按键映射表都给你你可以直接复制到 IDE 里编译上传。代码基于LiquidCrystal和Keypad两个库不需要额外安装其他依赖。先看库的引入和对象初始化部分#include LiquidCrystal.h #include Keypad.h // LCD1602 并行接口RS12, E11, D410, D59, D68, D77 LiquidCrystal lcd(12, 11, 10, 9, 8, 7); // 4x4 矩阵键盘行接 5/4/3/2列接 A3/A2/A1/A0 const byte KEYPAD_ROWS 4; const byte KEYPAD_COLS 4; byte rowPins[KEYPAD_ROWS] {5, 4, 3, 2}; byte colPins[KEYPAD_COLS] {A3, A2, A1, A0}; char keys[KEYPAD_ROWS][KEYPAD_COLS] { {1, 2, 3, }, {4, 5, 6, -}, {7, 8, 9, *}, {., 0, , /} }; Keypad keypad Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);按键映射表是矩阵键盘的灵魂。keys二维数组的第 0 行对应物理键盘最上面一行第 0 列对应最左边一列。如果你发现按1出来的是4说明行列接反了把rowPins和colPins的顺序对调即可。如果你发现按1出来的是2说明列顺序反了把colPins数组倒过来写。这个映射关系没有标准答案取决于你键盘的物理排线以实际按键为准。接下来是状态变量和计算函数。计算器需要记住三个东西第一个操作数、当前运算符、当前正在输入的数字。我用String来存操作数因为String拼接小数点比较方便计算时再转成doublechar operation 0; String memory ; String current ; bool decimalPoint false; double calculate(char op, double left, double right) { switch (op) { case : return left right; case -: return left - right; case *: return left * right; case /: return right ! 0 ? left / right : 0; } return 0; }注意除法这里我加了一个判断如果除数是 0直接返回 0避免出现inf或nan显示在屏幕上。原版代码没有处理这个边界实际使用中按5 / 0 会得到奇怪的结果。这是一个很小的改动但能避免很多困惑。输入处理函数processInput是逻辑最密集的地方。它要区分四种情况数字和小数点、运算符、等号、以及负号开头。下面这段代码可以直接用void processInput(char key) { if (key - current ) { current -; lcd.print(-); return; } if (key || key - || key * || key /) { if (operation 0) { memory current; current ; } operation key; lcd.setCursor(0, 1); lcd.print(key); lcd.setCursor(current.length() 1, 1); return; } if (key ) { double leftNum memory.toDouble(); double rightNum current.toDouble(); double result calculate(operation, leftNum, rightNum); memory String(result, 4); current ; operation 0; lcd.clear(); lcd.setCursor(0, 0); lcd.print(memory); return; } if (key . current.indexOf(.) 0) { return; } if (key ! . current 0) { current String(key); } else { current String(key); } lcd.print(key); }这里有几个细节值得展开。第一负号判断放在最前面因为-既是减号又是负号当current为空时按-应该当作负号处理而不是运算符。第二运算符按下时如果operation还是 0说明这是第一次按运算符把当前输入存进memory如果operation已经有值说明用户想连续运算但原版逻辑不支持这里保持简单不覆盖memory。第三等号按下后用String(result, 4)保留 4 位小数避免6.280000这种冗长显示。setup()和loop()保持简洁void setup() { Serial.begin(115200); lcd.begin(16, 2); lcd.print(Arduino Calc); lcd.setCursor(0, 1); lcd.print(Ready); delay(1000); lcd.clear(); lcd.cursor(); lcd.setCursor(0, 0); } void loop() { char key keypad.getKey(); if (key) { Serial.print(Key: ); Serial.println(key); processInput(key); } }串口打印按键值是一个很实用的调试手段。当你怀疑某个键没反应时打开串口监视器波特率设为 115200按一下键看有没有输出。如果有输出但屏幕没变化问题在 LCD 显示逻辑如果没输出问题在键盘接线或映射表。这个分界点能帮你省很多时间。4. 验证请求与成功结果串口监视器 LCD 实测步骤代码上传之后怎么确认它真的在工作我建议按下面这个顺序验证每一步都有明确的预期结果。第一步上电后观察 LCD。正常情况应该先显示Arduino Calc和Ready一秒后清屏光标在左上角闪烁。如果屏幕只有背光没有字符调电位器如果连背光都没有检查 A/K 引脚和 5V/GND。如果显示的是乱码方块检查 D4–D7 四根数据线有没有接错顺序。第二步打开串口监视器波特率选 115200。依次按下键盘上的1、2、3、、4、串口应该依次输出Key: 1 Key: 2 Key: 3 Key: Key: 4 Key: 同时 LCD 第一行应该显示1234按下等号后第一行变成127.0000。如果串口有输出但 LCD 没显示重点检查lcd.print的调用位置如果串口输出的是错误的字符比如按1输出4回到上一节调整行列映射。第三步测试小数和负数。按3、.、1、4、*、2、预期结果是6.2800。按-、5、、3、预期结果是-2.0000。注意负号必须在current为空时按下才生效如果你先按了数字再按负号它会被当作减号处理。第四步测试边界情况。按5、/、0、由于我在calculate里加了判断结果会显示0.0000而不是inf。按1、.、2、.、3第二个小数点会被忽略屏幕只显示1.23。这些行为不一定符合所有人的预期但至少是可预测的不会让程序崩溃。如果你在验证过程中想快速查某个库函数的用法比如Keypad::getKey()的返回值类型或者LiquidCrystal::setCursor()的参数含义可以直接在模型对话里问。把报错信息或代码片段贴进去让它帮你定位。模型对话入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite不需要额外配置打开就能用。对于这种“查一个函数签名”的小问题比翻文档快很多。实测下来最容易出问题的环节是键盘的行列识别。薄膜键盘的排线顺序和市面上常见的原理图不一定一致有的键盘第一行是 R1有的把 R1 放在最右边。遇到按键错位时不要急着改代码先用串口把每个键的实际输出打出来画一张真实的映射表再反过来填keys数组。这个方法比反复试错快得多。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth 报错这一节集中处理两类问题一类是 Arduino 代码本身的报错另一类是你在用 TaoToken 辅助开发时可能遇到的 API 报错。两类问题分开看定位思路不一样。先看 Arduino 侧。最常见的编译错误是Keypad.h: No such file or directory这说明Keypad库没装。在 IDE 里点“工具 → 管理库”搜索Keypad安装 Arduino 官方版本即可。另一个常见错误是LiquidCrystal相关如果你用的是 I2C 转接板却引入了LiquidCrystal而不是LiquidCrystal_I2C会编译失败。本文按并行接口写所以用LiquidCrystal是对的。运行时的典型问题是 LCD 只显示第一行或显示不全。这通常是lcd.begin(16, 2)的参数写错或者setCursor的列号超出 0–15 范围。还有一个隐蔽的问题在processInput里频繁调用lcd.clear()会导致屏幕闪烁因为清屏会重写整个显示缓冲区。我的做法是只在等号计算后清屏一次其他时候用空格覆盖旧字符。再看 API 侧。如果你在 curl 或代码里调用 TaoToken 时遇到401 Unauthorized按这个顺序检查第一Authorization头是不是Bearer YOUR_API_KEY格式Bearer和 Key 之间有一个空格第二Key 是不是复制完整了有没有多余的空格或换行第三Key 是不是已经被删除或过期。401 几乎都是 Key 的问题和模型 ID 无关。如果遇到local proxy failed或类似的连接错误说明请求根本没发出去。检查你的 Base URL 是不是写成了https://taotoken.net/api注意结尾没有斜杠也没有/v1之外的路径。如果你在代码里用了环境变量确认环境变量真的被读取到了。这个报错和 Key 无关纯粹是网络层或地址层的问题。reading choices这类报错通常出现在你解析响应时。比如你用 JavaScript 写response.choices[0].message.content但实际返回的 JSON 里没有choices字段就会报Cannot read properties of undefined (reading choices)。这说明请求本身失败了返回的是一个错误对象。正确的做法是先判断response.error是否存在再取choices。在 Arduino 项目里你不太会直接解析这个但如果你用 Python 脚本批量测试按键映射就会遇到。OAuth 相关报错一般出现在你尝试用某些客户端的登录流程时。如果你只是用 API Key 调用不会触发 OAuth。遇到 OAuth 报错时确认你用的是 API Key 模式而不是账号登录模式。TaoToken 的 API 调用只需要 Key不需要走 OAuth 授权流程。还有一个容易混淆的点Claude Code 或 Cline 这类工具在配置时需要同时填 Base URL、API Key 和 Model ID 三件套。缺任何一个都会报错。Base URL 填https://taotoken.net/apiKey 填你创建的 KeyModel ID 填文档里列出的可用模型。如果你只填了 Key 没填 Base URL工具会默认请求官方地址自然失败。这三件套在settings.json或auth.json里的字段名可能不同但含义是一样的。排查问题的通用思路是先确认请求有没有发出去看网络层报错再确认身份有没有通过看 401最后确认返回内容能不能解析看 choices。按这个顺序走大部分问题都能在三分钟内定位。6. 语义一致 CTA把计算器代码和模型辅助串起来到这里你的 Arduino 计算器应该已经能跑起来了。回顾一下我们做了什么接好了 LCD1602 的 6 根信号线和矩阵键盘的 8 根行列线写好了按键映射表和四则运算逻辑用串口监视器验证了每个按键的输出还处理了除零和小数点重复的边界情况。这套代码可以直接复用到其他需要“键盘输入 屏幕输出”的项目里比如密码锁、菜单选择器、简易游戏机。如果你在调试过程中遇到了本文没覆盖的报错或者想让模型帮你把计算器扩展成支持连续运算比如123直接出6可以用模型对话把当前代码贴进去让它给出修改建议。入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite打开就能用不需要额外配置。如果你打算长期在 Arduino 或其他嵌入式项目里用模型辅助写代码、查报错、生成配置可以了解一下 Coding Plan地址是https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。它适合那种“每天都要问几个代码问题”的开发节奏比每次单独调用更省事。需要再强调一次 Base URL 的写法代码里统一用https://taotoken.net/api不要带 UTM 参数。API Key 在控制台创建地址是https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。模型 ID 和详细参数以文档为准文档地址是https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。最后分享一个我在这个项目里踩过的坑矩阵键盘的排线如果太长或者和 LCD 的数据线捆在一起按键会出现“幽灵触发”就是没按任何键但串口偶尔输出字符。解决办法是把键盘排线和 LCD 排线分开走或者在keypad.getKey()外面加一个简单的去抖判断连续两次读到同一个键才认为是有效输入。这个改动很小但能显著提升稳定性。
阅读完成 · 觉得有帮助?
咨询建站