Arduino+数码管 = 量电压 | A+B problem | alphabet

news/2025/10/4 10:51:46/文章来源:https://www.cnblogs.com/XuYueming/p/19117544

材料

Arduino UNO R3、8041AS 七位数码管、若干导线、电阻、电位器、按钮、面包板。

量电压

A0 读入电压值,然后显示到数码管上即可。

voltage-display.ino
// https://www.lanpade.com/7-segment-led-dot-matrix/8041as.html// === Pin Definitions ===
// Segments (a,b,c,d,e,f,g,dp) -> Arduino digital pins
const int segPins[8] = {3, 7, 11, 9, 8, 4, 12, 10};
// Digits (D1–D4, common cathode) -> Arduino pins
const int digitPins[4] = {2, 5, 6, 13};// Segment map for numbers 0–9 (abcdefg, dp separate)
const byte numbers[10] = {B11111100, // 0B01100000, // 1B11011010, // 2B11110010, // 3B01100110, // 4B10110110, // 5B10111110, // 6B11100000, // 7B11111110, // 8B11110110  // 9
};float voltage = 0.0; // measured voltage// === Functions ===
void displayVoltage(float val) {// Scale value: 0.000–5.000 -> up to 5000 (int)int scaled = (int)(val * 1000);int digits[4];for (int i = 3; i >= 0; i--) {digits[i] = scaled % 10;scaled /= 10;}// Multiplex displayfor (int d = 0; d < 4; d++) {digitalWrite(digitPins[d], LOW); // enable digit// set segmentsfor (int s = 0; s < 8; s++) {bool on = bitRead(numbers[digits[d]], 7 - s);digitalWrite(segPins[s], on ? HIGH : LOW);}// Add decimal point after first digit (x.xxx)if (d == 0) digitalWrite(segPins[7], HIGH); // dp ON for digit 1else digitalWrite(segPins[7], LOW);delay(3);digitalWrite(digitPins[d], HIGH); // disable digit}
}void setup() {for (int i = 0; i < 8; i++) pinMode(segPins[i], OUTPUT);for (int i = 0; i < 4; i++) {pinMode(digitPins[i], OUTPUT);digitalWrite(digitPins[i], HIGH); // all off initially}
}void loop() {// Read analog input (0–5V → 0–1023)int adcValue = analogRead(A0);voltage = (adcValue * 5.0) / 1023.0;// Refresh display continuouslydisplayVoltage(voltage);
}

可以进一步地,输出到 Serial,并取最近 \(10\) 次结果取平均值,以稳定测量结果。

voltage-display.ino
// https://www.lanpade.com/7-segment-led-dot-matrix/8041as.html// === Pin Definitions ===
// Segments (a,b,c,d,e,f,g,dp) -> Arduino digital pins
const int segPins[8] = {3, 7, 11, 9, 8, 4, 12, 10};
// Digits (D1–D4, common cathode) -> Arduino pins
const int digitPins[4] = {2, 5, 6, 13};// Segment map for numbers 0–9 (abcdefg, dp separate)
const byte numbers[10] = {B11111100, // 0B01100000, // 1B11011010, // 2B11110010, // 3B01100110, // 4B10110110, // 5B10111110, // 6B11100000, // 7B11111110, // 8B11110110  // 9
};// === Functions ===
void displayVoltage(float val)
{// Scale value: 0.000–5.000 -> up to 5000 (int)int scaled = (int)(val * 1000);int digits[4];for (int i = 3; i >= 0; i--){digits[i] = scaled % 10;scaled /= 10;}// Multiplex displayfor (int d = 0; d < 4; d++){digitalWrite(digitPins[d], LOW); // enable digit// set segmentsfor (int s = 0; s < 8; s++){bool on = bitRead(numbers[digits[d]], 7 - s);digitalWrite(segPins[s], on ? HIGH : LOW);}// Add decimal point after first digit (x.xxx)if (d == 0)digitalWrite(segPins[7], HIGH); // dp ON for digit 1elsedigitalWrite(segPins[7], LOW);delay(3);digitalWrite(digitPins[d], HIGH); // disable digit}
}const int NUM_SAMPLES = 10;
int samples[NUM_SAMPLES];
int sampleIndex = 0;
bool bufferFilled = false;void setup()
{for (int i = 0; i < 8; i++)pinMode(segPins[i], OUTPUT);for (int i = 0; i < 4; i++){pinMode(digitPins[i], OUTPUT);digitalWrite(digitPins[i], HIGH); // all off initially}pinMode(A0, INPUT);Serial.begin(115200);for (int i = 0; i < NUM_SAMPLES; i++){samples[i] = 0;}
}void loop()
{// Read analog input (0–5V → 0–1023)int adcValue = analogRead(A0);samples[sampleIndex] = adcValue;sampleIndex++;if (sampleIndex >= NUM_SAMPLES){sampleIndex = 0;bufferFilled = true;}float result = 0.0;int total = bufferFilled ? NUM_SAMPLES : sampleIndex;for (int i = 0; i < total; i++){result += samples[i];}result *= 5. / 1023.;result /= total;Serial.print("Sensor reading: ");Serial.print(adcValue);Serial.print(" Voltage: ");Serial.print((float)adcValue * 5. / 1023., 3);Serial.print(" Average: ");Serial.println(result, 3);// Refresh display continuouslydisplayVoltage(result);
}

voltage-display

A+B problem

让我们先把操作数码管的代码简单封装一下,可以得到以下并不标准的 segment.cpp

segment.cpp
#ifndef SEGMENT_H_
#define SEGMENT_H_// https://www.lanpade.com/7-segment-led-dot-matrix/8041as.html// === Pin Definitions ===
// Segments (a,b,c,d,e,f,g,dp) -> Arduino digital pins
const int segPins[8] = { 3, 7, 11, 9, 8, 4, 12, 10 };
// Digits (D1–D4, common cathode) -> Arduino pins
const int digitPins[4] = { 2, 5, 6, 13 };// Segment map for numbers 0–9 (abcdefg, dp separate)
const byte numbers[10] = {B11111100,  // 0B01100000,  // 1B11011010,  // 2B11110010,  // 3B01100110,  // 4B10110110,  // 5B10111110,  // 6B11100000,  // 7B11111110,  // 8B11110110   // 9
};
// Segment map for alphas a-z
const unsigned char alphas[26] = {0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e, 0xbc, 0x6e, 0xf0, 0x70,0xae, 0x1c, 0xec, 0x2a, 0x3a, 0xce, 0xe6, 0x8c, 0x92, 0x1e,0x7c, 0x38, 0x7e, 0x26, 0x76, 0x5a
};const unsigned long stayMillis = 3;
const unsigned long BATCHMILLIS = 500;  // time for show four characters
const int strBufSize = 256;const int shockShowMillis = 200;
const int shockHideMillis = 200;byte getPattern(char c, bool dp) {byte pattern = 0;if (c >= '0' && c <= '9') {pattern = numbers[c - '0'];} else if (c >= 'A' && c <= 'Z') {pattern = alphas[c - 'A'];} else if (c >= 'a' && c <= 'z') {pattern = alphas[c - 'a'];}if (dp) {pattern |= B00000001;}return pattern;
}void showSingle(byte pattern, int digit) {if (!pattern) {delay(stayMillis);return;}digitalWrite(digitPins[digit], LOW);for (int i = 0; i < 8; i++) {digitalWrite(segPins[i], bitRead(pattern, 7 - i));}delay(stayMillis);digitalWrite(digitPins[digit], HIGH);
}int initStrDP(const char *str, const bool *DP, char *strBuf, bool *dpBuf) {int bufLen = 0, strLen = strlen(str);for (int i = 0; i < strLen; i++) {if (str[i] == '.') {if (bufLen > 0 && !dpBuf[bufLen - 1]) {dpBuf[bufLen - 1] = true;} else {strBuf[bufLen] = ' ';dpBuf[bufLen] = true;bufLen++;}} else {strBuf[bufLen] = str[i];dpBuf[bufLen] = DP != NULL ? DP[i] : false;bufLen++;}}strBuf[bufLen] = '\0';return bufLen;
}struct displayLoopStateNode {char strBuf[strBufSize];bool dpBuf[strBufSize];int bufLen;unsigned long totalMillis;unsigned long batchMillis;unsigned long start;unsigned long startBatch;int currentRound;int totalRounds;bool active;
} _displayLoopState;void displayLoopTaskInit(const char *str, const bool *DP = NULL, unsigned long totalMillis = 1000, unsigned long batchMillis = BATCHMILLIS) {int strLen = strlen(str);if (str == NULL || strLen == 0) return;_displayLoopState.bufLen = initStrDP(str, DP, _displayLoopState.strBuf, _displayLoopState.dpBuf);_displayLoopState.totalRounds = _displayLoopState.bufLen + 4;_displayLoopState.batchMillis = batchMillis;_displayLoopState.totalMillis = totalMillis;unsigned long requiredTotal = _displayLoopState.totalRounds * batchMillis;if (requiredTotal > totalMillis) {_displayLoopState.batchMillis = totalMillis / _displayLoopState.totalRounds;}_displayLoopState.start = millis();_displayLoopState.startBatch = _displayLoopState.start;_displayLoopState.currentRound = 0;_displayLoopState.active = true;
}// return a bool, false for task ended
bool displayLoopTaskUpdate() {if (!_displayLoopState.active) {return false;}if (millis() - _displayLoopState.start >= _displayLoopState.totalMillis) {_displayLoopState.active = false;return false;}for (int digit = 0; digit < 4; digit++) {int charPos = _displayLoopState.currentRound - 3 + digit;char displayChar = ' ';bool displayDP = false;if (0 <= charPos && charPos < _displayLoopState.bufLen) {displayChar = _displayLoopState.strBuf[charPos];displayDP = _displayLoopState.dpBuf[charPos];}byte pattern = getPattern(displayChar, displayDP);showSingle(pattern, digit);}unsigned long currentTime = millis();while (currentTime - _displayLoopState.startBatch >= (_displayLoopState.currentRound + 1) * _displayLoopState.batchMillis) {_displayLoopState.currentRound++;if (_displayLoopState.currentRound >= _displayLoopState.totalRounds) {_displayLoopState.currentRound = 0;_displayLoopState.startBatch = currentTime;}}return true;
}/*** 在四位数码管上滚动显示字符串* @param str 要显示的字符串* @param DP 小数点控制数组,与 str 等长* @param totalMillis 总显示时间(毫秒)* @param batchMillis 每四个字符的显示时间(毫秒)*/
void displayLoop(const char *str, const bool *DP = NULL, unsigned long totalMillis = 1000, unsigned long batchMillis = BATCHMILLIS) {displayLoopTaskInit(str, DP, totalMillis, batchMillis);while (!displayLoopTaskUpdate())continue;
}void display(int value, unsigned int DP = B0000) {int digits[4];for (int i = 3; i >= 0; i--) {digits[i] = value % 10;value /= 10;}// Multiplex displayfor (int d = 0; d < 4; d++) {byte pattern = getPattern('0' + digits[d], DP & B1 << d ? true : false);showSingle(pattern, d);}
}void display(const char* str, unsigned DP = B0000) {for (int d = 0; d < 4; d++) {byte pattern = getPattern(str[d], DP & B1 << d ? true : false);showSingle(pattern, d);}
}#define __define_displayForMillis(TYPE) \void displayForMillis(TYPE value, unsigned int DP = B0000, unsigned long millisCount = 1000) { \unsigned long start = millis(); \while (millis() - start < millisCount) { \display(value, DP); \} \}
__define_displayForMillis(int)
__define_displayForMillis(const char*)
#undef __define_displayForMillis#define __define_displayShock(TYPE) \void displayShock(TYPE value, unsigned int DP = B0000, unsigned long millisCount = 1000) { \unsigned long start = millis(); \while (millis() - start < millisCount) { \displayForMillis(value, DP, min(millisCount - (millis() - start), shockShowMillis)); \delay(shockHideMillis); \} \}
__define_displayShock(int)
__define_displayShock(const char*)
#undef __define_displayShockvoid segmentInit() {for (int i = 0; i < 8; i++)pinMode(segPins[i], OUTPUT);for (int i = 0; i < 4; i++) {pinMode(digitPins[i], OUTPUT);digitalWrite(digitPins[i], HIGH);  // all off initially}
}#endif

于是可以方便地写出如下程序:

aplusb.ino
#include "include/segment.cpp"const int inputScale = 5;
const int inputPin = A0;
const int buttonPin = A1;int readInt() {while (true) {int raw = analogRead(inputPin);int value = raw / inputScale;display(value);if (digitalRead(buttonPin) == HIGH) {displayForMillis(value, 0, 20);while (digitalRead(buttonPin) == HIGH) {display(value);}displayShock(value);return value;}}
}void setup() {segmentInit();pinMode(inputPin, INPUT);pinMode(buttonPin, INPUT);Serial.begin(115200);
}void SerialPrintf(const char *fmt, ...) {char buf[128];va_list args;va_start(args, fmt);vsnprintf(buf, sizeof(buf), fmt, args);va_end(args);Serial.print(buf);
}void loop() {int a = readInt();SerialPrintf("Read a = %d\n", a);int b = readInt();SerialPrintf("Read b = %d\n", b);int sum = a + b;SerialPrintf("%d + %d = %d\n", a, b, sum);displayForMillis(sum, B0111, 5000);
}

aplusb

alphabet

我们已经封装好了,直接用就行了。

alphabet.ino
#include "include/segment.cpp"void setup() {segmentInit();displayLoop(".0123456789.A...BCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, 5000);displayLoop("520", NULL, 5000);displayLoop("520 1314", NULL, 8000);displayLoop("i love you", NULL, 8000);displayForMillis(" ADD", 0, 1000);displayShock("F  K", 0, 3000);displayLoopTaskInit("F  K YOU", NULL, 5000);
}void loop() {if (digitalRead(A1) == HIGH) {while (digitalRead(A1) == HIGH)continue;displayShock("F  K", 0, 3000);}if (!displayLoopTaskUpdate()) {displayLoopTaskInit("F  K ME. PLEASE", NULL, 5000);}
}

接线同 aplusb。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站热力图用ps怎么做网站建设 绵阳

目录 一、网络配置命令 1.ifconfig——IP地址 1.1ifconfig的基础用法 1.1.1ifconfig命令详解 1.2常用格式 1.3修改网卡名称 1.3.1临时修改 1.3.2永久修改 1.4临时修改网卡 1.4.1设置虚拟网卡 1.4.2延伸——ethtool 1.5永久修改网卡 1.6实验 —— 双网卡配置 1.…

做网站的财务需求设计新颖的兰州h5制作

(注&#xff1a;在看到大家如此关注JS里头的这几个对象&#xff0c;我试着把原文再修改一下&#xff0c;力求能再详细的阐明个中意义 2007-05-21&#xff09;在提到上述的概念之前&#xff0c;首先想说说javascript中函数的隐含参数&#xff1a;arguments Arguments 该对象代表…

详细介绍:【数据库知识】TxSQL 主从数据库同步底层原理深度解析

详细介绍:【数据库知识】TxSQL 主从数据库同步底层原理深度解析pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

做简历哪个网站比较好制作图片的软件哪个好

文章目录 797. 差分题目描述差分 797. 差分 题目描述 输入一个长度为 n nn 的整数序列。 接下来输入 m mm 个操作&#xff0c;每个操作包含三个整数 l,r,c, 表示将序列中 [l,r] 之间的每个数加上 c 。 请你输出进行完所有操作后的序列。 输入格式 第一行包含两个整数 n 和…

详细介绍:TensorFlow(1)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

建设网站方案网页休闲游戏网站

关于单点登录 单点登录的基本实现思想&#xff1a; 当客户端提交登录请求时&#xff0c;服务器端在验证登录成功后&#xff0c;将生成此用户对应的JWT数据&#xff0c;并响应到客户端 客户端在后续的访问中&#xff0c;将自行携带JWT数据发起请求&#xff0c;通常&#xff0c…

电子政务门户网站建设教训综合性电商网站建设

if 语句后可以跟可选的 elsif ... else 语句&#xff0c;这对于使用单个if ... elsif语句测试各种条件非常有用。 if...elsif...else - 语法 Perl编程语言中的 if ... elsif...else语句的语法是- if(boolean_expression 1) {# Executes when the boolean expression 1 is tr…

南昌网站建设渠道全国被执行人名单查询

在 Vue 的组件通信中&#xff0c;slot&#xff08;插槽&#xff09;的编译优化是一个重要的性能提升点。以下是 Vue2 和 Vue3 在 slot 处理上的差异及优化原理&#xff0c;用更直观的方式解释&#xff1a; Vue2 的 Slot 更新机制 想象一个父子组件场景&#xff1a; 父组件&am…

2025.10.3 NOIP 模拟赛

前言 这回一改上次颓势。 T1一眼,T3思考2h+后场切。 但 T2 只有接近正解的 50 pts,T4 常数大挂了 20pts。 A 给定 \(n,k\),对 \([1,n]\) 建线段树后,求线段树上所有节点长度的 \(k\) 次方之和。 Solution 发现线段…

(最新原创毕设)基于SpringBoot的分布式存储平台/10.3(白嫖源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案 - 指南

(最新原创毕设)基于SpringBoot的分布式存储平台/10.3(白嫖源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案 - 指南pre { white-space: pre !important; word-wrap: nor…

Python 之操作excel

一、常用方法 Workbook():创建新的工作簿create_sheet():创建工作表 append():加入一行数据详细:https://openpyxl.readthedocs.io/en/stable/api/openpyxl.html 二、示例代码import openpyxl from openpyxl.style…

大语言模型中的“推理”:基本原理与构建机制解析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网站模板商城网站如何换空间

PFA洗气瓶是一种常用于净化和干燥各种气体的实验室器皿&#xff0c;以去除其中的水分、油脂、颗粒物等杂质&#xff0c;从而使需要用到的气体满足实验要求。 PFA气体吸收瓶 PFA洗气瓶的工作原理&#xff1a; 主要是通过液体吸收、溶解或发生化学反应来去除气体中的杂质。在洗气…

找产品做代理都有哪个网站国际军事新闻视频

今天跟大家谈一谈越来越火爆的店群模式&#xff0c;现在大部分做跨境电商的卖家都会建立自己的店群&#xff0c;其中很多做 Shopee的卖家时常会听到一个名词“ Shopee 店群模式”&#xff0c;但很多人都不知道怎么去做&#xff0c;或者在犹豫要不要做&#xff0c;所以东哥我会从…

国家生物信息数据下载

001、ascp -P33001 -i /home/data/t200558/NPCdata/HRA003340/aspera01.openssh -QT -l100m -k1 -d aspera01@download.cncb.ac.cn:gsa-human/HRA003340 ./

隆昌网站建设小程序哪家公司代理

一. 背景 在刚接触开发的头几年里&#xff0c;说实话&#xff0c;根本不考虑多线程的这个问题&#xff0c;貌似那时候脑子里也有没有多线程的这个概念&#xff0c;所有的业务都是一个线程来处理&#xff0c;不考虑性能问题&#xff0c;当然也没有考虑多线程操作一条记录存在的并…

装修网站怎么做的好网站后端开发语言

题目&#xff1a; Bessie听说有场史无前例的流星雨即将来临&#xff1b;有谶言&#xff1a;陨星将落&#xff0c;徒留灰烬。为保生机&#xff0c;她誓将找寻安全之所&#xff08;永避星坠之地&#xff09;。目前她正在平面坐标系的原点放牧&#xff0c;打算在群星断其生路前转…

站长查询工具网站建设功能定位

很多时候需要用到连续的id进行数据对比&#xff0c;如判断是否连续等问题。那么&#xff0c;生成连续整数的方式有多种&#xff0c;首先容易想到的是逐步循环&#xff0c;如果想生成1kw条记录&#xff0c;则需要循环1kw次进行插入&#xff0c;那么有没有其他方式呢&#xff0c;…

linux jenkins服务启动异常等,排查是否日志磁盘空间满 du df命令

linux jenkins服务启动异常等,排查是否日志磁盘空间满 du df命令linux jenkins服务启动异常等,排查是否日志磁盘空间满 du df命令 日志路径问题PM2默认日志路径为/root/.pm2/logs/,若该目录权限不足或磁盘空间已满会…