基于ESP32的图形科学计算器

Hacker News Top 工具

摘要

NumOS 是一个开源操作系统,适用于基于ESP32-S3微控制器的图形科学计算器,搭载了由Giac驱动的CAS引擎和LVGL 9.x界面。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/18 12:55

El-EnderJ/NeoCalculator 源代码:https://github.com/El-EnderJ/NeoCalculator # 🔢 NumOS ### 开源科学绘图计算器操作系统 ESP32-S3 N16R8 · ILI9341 IPS 320×240 · LVGL 9.x · CAS 引擎 · 自然显示 V.P.A.M. PlatformIO (https://platformio.org/) LVGL (https://lvgl.io/) ESP32-S3 (https://www.espressif.com/en/products/socs/esp32-s3) 网站 (https://neocalculator.tech) 框架 (https://www.arduino.cc/) 语言 (https://en.cppreference.com/) 许可证 (https://www.gnu.org/licenses/gpl-3.0) 状态 RAM Flash GitHub Star (https://github.com/El-EnderJ/NeoCalculator) GitHub Fork (https://github.com/El-EnderJ/NeoCalculator) 通过 Ko-fi 支持 (https://ko-fi.com/enderdesigns) > [!IMPORTANT]

技术状态:主要架构重构
我们正在将核心数学引擎迁移到 Giac,并实现 STIX Two Math 以提供 LaTeX 级渲染。如果你从 main 分支编译,可能会遇到 UI 问题。如需稳定版本,请查看 Releases (https://github.com/El-EnderJ/NeoCalculator/releases) 部分。

什么是 NumOS?

NumOS 是一个开源的科学与图形计算器操作系统,基于 ESP32-S3 N16R8 微控制器(16 MB Flash QIO + 8 MB PSRAM OPI)。该项目旨在成为全球最佳开源计算器,与 Casio fx-991EX ClassWiz、NumWorks、TI-84 Plus CE 和 HP Prime G2 相抗衡。

NumOS 提供:

  • 基于 Giac 的 CAS 引擎 — 符号数学现在通过 src/math/giac/GiacBridge.cpp 运行 Giac C++(大切换)。遗留的 CAS-S3 模块作为历史里程碑和可选的本地工具保留。
  • 自然显示 V.P.A.M. — 公式按纸面样式渲染:真正的堆叠分数、根号(√)、真实上标、二维导航及结构智能光标。
  • 现代 LVGL 9.x 界面 — 平滑过渡、动画启动画面、NumWorks 风格启动器。近期启动器重构:启动器现在使用 LVGL Flex ROW_WRAP(动态行)配合固定卡片大小,替代静态网格描述。参见 docs/UI_CHANGES.md 了解开发者迁移说明,以及 docs/fluid2d_plan.md 了解集成到新 APPS[] 架构的示例应用(Fluid2D)。
  • 自定义数值数学引擎 — 完整流水线:词法分析器 → Shunting-Yard 解析器 → RPN 求值器 + 可视化 AST,使用 C++17 从头实现。
  • 模块化应用架构 — 每个应用都是独立的模块,具有明确的生命周期(begin/end/load/handleKey),由 SystemApp 统一调度。

图片库

神经网络模拟器:图片

流体 2D 模拟器:图片

元素周期表(化学应用):图片

图形应用:图片

步骤(方程应用)(WIP,仍在开发,Alpha 版):图片 图片

微积分应用:图片

概率(高斯分布):图片

Python 应用:图片 图片

桥梁设计器:图片

电路模拟器(Circuit Core,Alpha 版):图片

粒子实验室(类似 Powder Toy):图片

光学实验室:图片

CAS 引擎

CAS(计算机代数系统)现在使用 Giac C++ 作为规范的符号后端。迁移通过 src/math/giac/GiacBridge.cpp 路由,并由 src/input/SerialBridge.cpp 中的 UART 命令路径消费。下方记录的遗留 CAS-S3 内部模块作为历史里程碑和可选的本地组件保留,但当前后端流程的符号真实性来自 Giac。

Giac 迁移里程碑

  • 大切换完成:自定义符号后端被 Giac 替换为规范 CAS。
  • 嵌入式数值稳定化完成:使用 -DDOUBLEVAL
  • 栈稳定化完成:使用 -DARDUINO_LOOP_STACK_SIZE=65536
  • Real 风格默认值完成:complex_mode(false) 并保留虚数单位行为(i^2 = -1)。
  • UART 命令路径已在硬件上验证:sumintsolvesimplify

CAS 流水线(导数)

flowchart TB  
    user["用户输入 (CalculusApp): x^3 + sin(x)"]  
    user --> me["数学引擎:Parser + Tokenizer"]  
    me --> af["ASTFlattener: MathAST → SymExpr DAG"]  
    af --> sd["SymDiff → d/dx: 3x^2 + cos(x)"]  
    sd --> ss["SymSimplify (8 遍不动点)"]  
    ss --> sea["SymExprToAST: SymExpr → MathAST (自然显示)"]  
    sea --> canvas["MathCanvas 渲染: 3x^2 + cos(x)"]  

CAS 流水线(积分)

flowchart TB  
    userInt["用户输入 (CalculusApp, ∫dx 模式): x · cos(x)"]  
    userInt --> af2["ASTFlattener → SymExpr DAG"]  
    af2 --> sint["SymIntegrate (Slagle): 表 → 线性 → u 代换 → 分部 (LIATE)"]  
    sint --> ss2["SymSimplify"]  
    ss2 --> conv["SymExprToAST::convertIntegral()"]  
    conv --> canvas2["MathCanvas 渲染: x·sin(x) + cos(x) + C"]  

CAS 组件

模块文件职责
CASIntcas/CASInt.h混合 BigInt:int64_t 快速路径 + 溢出时使用 mbedtls_mpi
CASRationalcas/CASRational.h/.cpp溢出安全精确分数(分子/分母,自动 GCD)
PSRAMAllocatorcas/PSRAMAllocator.hSTL 分配器 → ps_malloc/ps_free 用于 PSRAM
SymExpr DAGcas/SymExpr.h/.cpp不可变符号树,带哈希 (_hash) 和权重 (_weight)
ConsTablecas/ConsTable.hPSRAM 哈希一致表:去重相同节点
SymExprArenacas/SymExprArena.hPSRAM 碰撞分配器(16 块 × 64 KB) + 集成 ConsTable
ASTFlattenercas/ASTFlattener.h/.cppMathAST (VPAM) → SymExpr DAG,哈希一致
SymDiffcas/SymDiff.h/.cpp符号微分:17 条规则(链式、乘积、商、三角、指数、对数)
SymIntegratecas/SymIntegrate.h/.cppSlagle 积分:表、线性、u 代换、分部(LIATE)
SymSimplifycas/SymSimplify.h/.cpp多遍化简器(8 次迭代,不动点,三角/对数/指数)
SymPolycas/SymPoly.h/.cpp单变量符号多项式,使用 CASRational 系数
SymPolyMulticas/SymPolyMulti.h/.cpp多变量多项式 + Sylvester 结式
SingleSolvercas/SingleSolver.h/.cpp单变量方程:线性 / 二次 / Newton-Raphson
SystemSolvercas/SystemSolver.h/.cpp2×2 方程组:高斯消元 + 非线性(结式)
OmniSolvercas/OmniSolver.h/.cpp解析变量分离:逆函数、根、三角
HybridNewtoncas/HybridNewton.h/.cppNewton-Raphson 带符号 Jacobian 和 16 种子多点启动
CASStepLoggercas/CASStepLogger.h/.cppPSRAM 中的 StepVec — 详细步骤(INFO/FORMULA/RESULT/ERROR)
SymToASTcas/SymToAST.h/.cpp桥接:SolveResult → MathAST 自然显示
SymExprToASTcas/SymExprToAST.h/.cpp桥接:SymExpr → MathAST。包含 convertIntegral() (+C)

CAS 测试 — 53 个单元测试

阶段测试覆盖范围
A — 基础1–18Rational:加减乘除、化简。SymPoly:算术、求导、归一化。
B — ASTFlattener19–32AST→SymPoly 转换:简单多项式、常量、三角函数、幂。
C — SingleSolver33–44线性(单解)、二次(2 实根、重根、负判别式)、步骤。
D — SystemSolver45–532×2 确定系统、不定(无穷解)、不相容系统。
# platformio.ini — 启用测试:  
build_flags = ... -DCAS_RUN_TESTS  
build_src_filter = +<*> +<../tests/CASTest.cpp>  

快速开始

要求

  • PlatformIO IDE (https://platformio.org/install/ide?install=vscode)(VS Code 扩展)
  • ESP32-S3 的 USB 驱动(Windows 11+ 无需外部驱动)
  • Python 3.x(PlatformIO 会自动安装)

构建和烧录

git clone https://github.com/your-user/numOS.git  
cd numOS  
# 仅构建  
pio run -e esp32s3_n16r8  
# 构建并烧录到 ESP32-S3  
pio run -e esp32s3_n16r8 --target upload  
# 打开串口监视器(115200 波特率)  
pio device monitor  

串行键盘控制(SerialBridge)

打开串口监视器后,输入字符控制计算器:

动作动作
w↑ 上zENTER / 确认
s↓ 下xDEL / 删除
a← 左cAC / 清除
d→ 右hMODE / 返回菜单
09数字+-*/^.()运算符
SSHIFTr√ SQRT
tsingGRAPH
e=(方程)RSHOW STEPS

注意:小写 s = 下;大写 S = SHIFT。使用前请关闭 CapsLock。

项目结构

numOS/  
├── src/  
│   ├── main.cpp               # Arduino 入口点 (setup/loop)  
│   ├── SystemApp.cpp/.h       # 中央调度器和 LVGL 启动器  
│   ├── Config.h                # G

相似文章

从零开始在FPGA上设计科学计算器

Lobsters Hottest

一系列详细的博客文章,记录了从零开始使用FPGA设计和实现科学计算器的过程,涵盖了数值方法、CPU架构、微码和硬件原型设计。

ESP-EEG 是一款价格实惠的8通道生物传感板

Hacker News Top

Cerelog ESP-EEG 是一款价格实惠的8通道生物传感板,采用ADS1299芯片,通过闭环主动偏置提供更清晰的信号,价格低于OpenBCI。它支持开源固件和软件(如Brainflow),但存在一些限制,例如仅支持USB连接和非商业用途限制。