ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Free, open-source CNC simulator to learn and test G-code without a machine: lathes and machining centers, Fanuc, Mitsubishi and Haas controls, Macro B parametric programs, the control's alarms and collision checks in 3D. Windows, macOS, Linux.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Português (Brasil) · English
Free, open-source CNC simulator to learn and test G-code, with no machine needed: lathes and machining centers, Fanuc, Mitsubishi, Haas and Siemens 840D controls, Macro B parametric programs, the control's own alarms and collision checks. For Windows, macOS and Linux.
Website: ismael-figueiredo.github.io/cnc-simulator · G-code reference
It reads G-code, takes the machine and the control from JSON files (a post-processor in reverse) and shows the toolpath and the machined part in 3D.
Installers for every version are on the Releases page:
| System | File | Notes |
|---|---|---|
| Windows 10/11 | cnc-simulator-<version>-setup.exe | Windows may warn about an unknown publisher (the app is not signed): More info → Run anyway. Updates install themselves. |
| macOS (Apple Silicon) | cnc-simulator-<version>-arm64.dmg | Drag to Applications. First launch: right-click the app → Open (not signed). |
| macOS (Intel) | cnc-simulator-<version>-x64.dmg | Same as above. |
| Linux | cnc-simulator-<version>-x86_64.AppImage or cnc-simulator_<version>_amd64.deb | The AppImage updates itself; the .deb is updated by installing the new one. |
PS0010 IMPROPER G-CODE)..nc).Start with the exercises on the start screen (E01 to E04, with Check), then open the examples, in this order:
| Example | Machine | What it teaches |
|---|---|---|
| O1001 stepped shaft | Romi GL 300 lathe | Facing, roughing passes by hand, finishing with automatic ,C chamfers and ,R radii, grooving |
| O1002 threaded shaft | Romi GL 300 lathe | The same part with canned cycles: G71 roughing, G70 finishing, G76 thread |
| O2001 plate | Romi D600 machining center | Face milling, contour with G41, pocket, drilling and tapping cycles G81/G83/G84, engraving |
| O2002 two vises | Romi D600 machining center | G54 and G55 work offsets, M98/M99 subprograms, machine coordinates |
| O3001 two fixtures | Haas VF-2 | The same job on Haas: G154 work offsets and M97 local subprograms |
| O1500 sprocket | Romi E280 lathe | A full Macro B parametric program with live tooling and G12.1 |
| SIE1001 threaded shaft | Lathe, Siemens 840D | CYCLE95 roughing and finishing along a contour between labels, RND/CHF corners, a G33 thread in passes with R parameters and GOTOB |
| SIE2001 plate | Machining center, Siemens 840D | T/D tool selection, G41 contour with RND/CHF, a pocket in passes with R parameters, holes with MCALL CYCLE81/CYCLE83 |
| Check | Where it shows |
|---|---|
| Program errors (wrong code, missing word, bad arc) | Red alarm with the control's number, at the block |
| Travel limits | Warning with the axis and the block, from the machine's travels |
| Holder into the stock, tool into the chuck jaws | Collision list; the holder or jaws turn red in 3D |
| Wrong H or D, missing tool offset | OFFSET table and warnings; a wrong H moves the tip as on the machine |
| Cycle time | Shown under the position, following the feed and rapid overrides |
Every bundled control (Fanuc 0i-TF, 0i-MF, Romi D line, Mitsubishi M80 lathe and machining center, Haas NGC mill) has the macro option, so these run in the simulator as on the machine:
#1–#33, commons #100–#199 and #500–#999, and system variables such as #5001–#5003 (absolute position) and #5021–#5023 (machine position).+ - * /, SIN COS TAN ASIN ACOS ATAN SQRT ABS ROUND FIX FUP, brackets.IF [...] GOTO n, IF [...] THEN, WHILE [...] DOn … ENDn, with EQ NE GT LT GE LE AND OR.G65 P… A… B… with arguments, M98/M99 subprograms in the same file.#3000 = n (message) stops the run with the control's alarm number.File → New program asks for plain G-code or parametric. Both start with a header written in the selected control's own codes (units, plane, safe cancels, first tool, spindle, coolant, program end, and ; at the end of blocks when the control needs it). The parametric one adds parameters to change (#100…) and a WHILE loop that makes the passes down to the depth.
The O1500 example is a full parametric program (an ANSI 40 sprocket computed from the number of teeth); O2001 and O2002 are plain G-code with canned cycles (G81, G83, G84) and subprograms; O3001 is the Haas version, with G154 work offsets and M97 local subprograms.
Tool offsets (right panel) is the control's OFFSET screen, saved in the project and filled from the tools at first (gauge length = holder + tool, radius, nose radius).
G43 H reads the length, G41/G42 D the radius; wear adds to geometry. If H is not the real length of the tool in the spindle, the tip is drawn where it really goes (a shorter H plunges deeper) and a warning gives the difference. Cutting without G43 is warned too.T0101 → 01). X/Z wear moves the tip, R and T (tip direction) drive nose radius compensation G41/G42, geometry goes into the machine position.G10 P n (wear) and P 10000+n (geometry) on lathes.Help → Report a problem explains how to post, saves a screenshot of the window to Downloads (and copies it), and opens a GitHub issue with the version and system already filled in. Help → Known problems opens the issue list.
It grew out of Simulador_Fanuc.html (docs/legacy), a single-file simulator that already handled Fanuc Macro B, G12.1 and G41/G42 cutter compensation on a Romi GL lathe with live tooling. This project rewrites it in TypeScript, split into core, UI and desktop app, and is no longer tied to one control.
npm install # dependencies
node node_modules/electron/install.js # Electron binary (since Electron 45 it is not fetched by npm install)
npm run dev # desktop app with hot reload
npm run check # types + lint + tests: run before every commit
npm test # tests only (Vitest)
npm run typecheck # types only
npm run lint # lint only (ESLint, zero warnings allowed); lint:fix fixes what it can
npm run build # check, then build to out/ (build:only skips the check)
npm run server # browser mode at http://localhost:5174 (run npm run build first)
npm run dist # installer for the current OS in dist/
npm run dist:win # Windows installer (NSIS)
npm run dist:mac # macOS dmg, arm64 and x64 (run on a Mac; unsigned)
npm run dist:linux # Linux AppImage and .deb
npm run icons # redraw build/icon.png, the favicon, installer artwork and docs/social.png after editing build/icon.svg
npm run demo # record docs/demo.gif (start screen + the example running) for the README
After a visible UI change, run npm run demo and commit the new docs/demo.gif with it, so the README shows the current app.
npm run dev fails with Cannot read properties of undefined (reading 'handle') and "Node.js" in the trace: the environment has ELECTRON_RUN_AS_NODE=1, which some VS Code extensions set. Electron then runs as plain Node. Clear it first:
Remove-Item Env:ELECTRON_RUN_AS_NODEunset ELECTRON_RUN_AS_NODEmain and every pull request runs npm run check.git tag -a vX.Y.Z --cleanup=verbatim -F notes.md, so the ### headings are kept); the Release workflow puts it on the release page.v* tag (git tag v0.1.0 && git push origin v0.1.0) builds the Windows, macOS and Linux installers and publishes them on the GitHub Releases page. Running the workflow by hand from the Actions tab only keeps them as run artifacts.build/ (sidebar and header BMPs); the macOS disk image shows a background with the drag-to-Applications arrow. npm run icons renders all of them from build/icon.svg.main, folder /docs) is generated: npm run screens takes the app's screenshots (docs/img, in English and Portuguese) and npm run site writes the English and Portuguese home pages, the G and M code reference (made from the control files and the learning help) and sitemap.xml, with canonical and hreflang links, Open Graph and schema.org data (SoftwareApplication, FAQPage). Run both after a release with visible changes. docs/social.png is the image for Settings → Social preview.The installed app checks the latest GitHub release on start, and from Help → Check for updates.
latest*.yml files the Release workflow publishes)..deb belongs to the system package manager..github/ISSUE_TEMPLATE/bug.yml asks for version, system, machine and control, what happened and the program blocks; Help → Report a problem prefills the first two.
npm run check must pass with no errors and no warnings. npm run build (and therefore every dist script) runs it first and stops on any failure.
tsc in strict mode with noUncheckedIndexedAccess.
typescript-eslint strict type-checked rules, React hooks rules (React Compiler aware) and eqeqeq.
onSeek: (t: number) => void)..cncsim files..vscode/ recommends the ESLint extension and fixes on save.The code base, config files and docs are in English. The UI is translated, with Portuguese (Brazil) as the default, plus English and Spanish.
src/i18n/locales/ holds one catalog per language. en.ts is the source; the compiler rejects any other catalog that misses or adds a key, and a test checks that every {placeholder} is kept.pt-BR.ts.LANGUAGES in src/i18n/index.ts.name, description) can be a plain string or one string per language:
"name": { "en": "Live tool", "pt-BR": "Ferramenta acionada", "es": "Herramienta motorizada" }
Missing languages fall back to English.code plus params, never a sentence, so each language words them its own way.| Part | Technology | Why |
|---|---|---|
Core (src/core) | Plain TypeScript | Runs the same in the app, the server and the tests |
i18n (src/i18n) | Plain TypeScript, typed catalogs | Shared by UI, main process and server; no dependency |
UI (src/renderer) | React + TSX, three.js via @react-three/fiber and drei | Declarative 3D view in TSX |
Desktop (src/main, src/preload) | Electron + electron-vite | One code base for Windows, Linux and macOS |
| Configs | JSON validated with zod | Readable errors; TS types come from the schemas |
| HTTP (optional) | Fastify | Browser mode and simulation API |
| Installer | electron-builder | NSIS (Windows, multi-language), AppImage, dmg |
| Tests | Vitest |
src/
core/ no DOM: types, schemas, the interpreter, material removal, collisions, part features
config/ schema.ts (zod), project.ts (.cncsim), load.ts (validation, issues as data), kinds.ts
interp/ simulate.ts (machine state) and its pure parts: words, variables, arcs, corner,
dataSetting, loadChecks, flow, alarms; cutterComp.ts, latheCycles.ts, diagnostics.ts
i18n/ languages, translate(), localize(); locales/en.ts is the source
main/ Electron main process: window, menus, files
preload/ safe typed bridge between window and system (api.ts)
renderer/ React UI: App.tsx, Workspace.tsx (one document), hooks (usePlayback, useCodePanel,
useDisplayOptions), components/, geometry/ (3D meshes, paths, measuring),
platform/ (desktop or browser: files, recent list, storage)
server/ Fastify server (browser mode)
configs/
machines/ one machine per file: axes, spindles, turret, stock
controls/ one control per file: dialect, G and M codes, rules
tools/ tool libraries and holders (tapers)
examples/ sample programs (O1500, ANSI 40 sprocket)
tests/ Vitest: *.test.ts in node, components/*.test.tsx in jsdom (npm run test:coverage)
scripts/ icons.mjs (icon and installer art), demo.mjs (README GIF)
build/ icon source and installer artwork
docs/legacy/ original HTML simulator, reference for the port
| Machine | Control file | Source |
|---|---|---|
| Romi GL 250 M (C axis, live tool) | fanuc-0i-tf-system-b | Romi manual GL 250/300/350/450 T/M/Y |
| Romi GL 300 (no C axis) | fanuc-0i-tf-system-b | same manual, version T; G12.1, C words and S2= raise PS0010/PS0009 |
| Romi E280 (2006, C axis, live tool) | fanuc-21i-tb-system-b | EMCO WinNC Fanuc 21 TB description (EN 1902, 2003); sizes from machine listings, the rest in its notes |
| Romi D600 | fanuc-0i-mf-romi-d | Romi manual PA09403B (Fanuc 0i-MF Plus) |
| Romi D1000, D1250 | fanuc-0i-mf-romi-d | Romi manual U57998C (D800/D1000/D1250, Fanuc 0i-MF) |
| Mitsubishi M80 lathe (generic) | mitsubishi-m80-lathe-list3 or -list2 | Mitsubishi programming manual IB-1501370 (lathe system) |
| Mitsubishi M80 machining center (generic) | mitsubishi-m80-mc | Mitsubishi programming manual IB-1501372 (machining center system) |
| Haas VF-2, VF-5/40 | haas-ngc-mill | Haas NGC mill operator's manual; travels and speeds from the catalog |
| Generic 3-axis machining center | fanuc-0i-mf | — |
| Lathe and machining center, Siemens 840D (generic) | siemens-840d-lathe, siemens-840d-mill | SINUMERIK 840D/810D short programming guide 6FC5298-6AB30-0KP0 (edition 10.00) |
notes for anything the manuals do not give, such as travels, maximum speed and magazine size. The app shows these notes in the machine panel.docs/manuals/, by maker. The PDFs belong to their makers and are not in the repository.#1037 cmdtyp.
#1078 Decpt2 = 0), so X1 is 0.001 mm.integerAddressDecimal: "ignore" option; Fanuc raises PS0007.G154 P1–P99 and G110–G129 (G154 P1–P20) are the same offsets as G54.1 P n, so a project table works for Haas and Fanuc programs alike. In G10 L20 G154 P n the G154 only names the offset being written.M97 P n calls a local subprogram that starts at block N n of the same program and ends with M99; L repeats it.P/S 010); the live tool, C axis and brake codes follow the Romi convention (S2=, M19, M85) and are marked to check on the machine.; comments, R parameters with expressions (X=R1+2), CR= arcs, RND/CHR/CHF corners, AC()/IC(), T with D (on machining centers D applies length and radius), labels with GOTOF/GOTOB/, subprograms written after M30 and ended with , , the drilling cycles – and stock removal (outside turning and facing). Other cycles, frames (, , …) and are reported as not simulated.Three separate files you can mix: the same machine with another control, or one tool library on several machines. Schemas live in src/core/config/schema.ts.
Machine: inspired by the LinuxCNC INI.
{
"id": "romi-gl250-m", "name": "Romi GL 250 M", "type": "mill-turn", "kinematics": "lathe-xzc",
"axes": [
{ "name": "X", "type": "linear", "min": -2, "max": 400, "rapid": 30000, "diameter": true },
{ "name": "C", "type": "rotary", "min": -99999, "max": 99999, "rapid": 18000 }
],
"spindles": [{ "id": "S2", "name": { "en": "Live tool", "pt-BR": "Ferramenta acionada" }, "type": "live", "maxRpm": 4500 }],
"toolChangePosition": { "X": 300, "Z": 200 },
"defaultControl": "fanuc-0i-tf-system-b",
"chuck": { "diameter": 210, "length": 95, "jaws": 3, "jawHeight": 50, "jawWidth": 26, "jawLength": 25, "bore": 66 }
}
chuck (lathes): body diameter and depth, number of jaws, jaw radial length, width and gripped length, spindle bore. It is drawn and used for the chuck collision check.tailstock (lathes): { "quillDiameter": 100, "retract": 80 }, the quill diameter and how far the center backs off when retracted.table (machining centers): { "length": 840, "width": 500, "slots": 5, "slotWidth": 18, "slotPitch": 80, "top": -560, "center": { "X": 300, "Y": 265 } }. top and center are the machine Z of the table face and the machine X/Y over its middle, in the frame of the work offsets. Without them, the table goes under the stock; without table, it is sized from the travels.Control: the "post-processor". Inspired by FreeCAD posts and Fusion .cps files. Every G or M code maps to a function the interpreter knows (rapid, polar-on, cutter-comp-left, c-axis-on, brake-on…), so a new control is just a new JSON file.
{
"id": "fanuc-0i-tf-system-b", "family": "fanuc", "machineType": "lathe",
"dialect": { "gCodeSystem": "B", "decimalPoint": "calculator", "xDiameter": true, "macro": "fanuc-b",
"comment": "parentheses", "liveToolSpeedAddress": "S2=" },
"gCodes": { "G12.1": { "function": "polar-on" }, "G94": { "function": "feed-per-minute" } },
"mCodes": { "M19": { "function": "c-axis-on" }, "M85": { "function": "brake-on" } },
"rules": ["no-g0-in-polar", "no-brake-in-polar"]
}
Control alarms: each control family has its own alarm catalog in configs/alarms/, and the control names it with "alarms".
map from simulator checks to those numbers. For Fanuc 0i, these are the P/S program errors from the maintenance manual.PS0010 IMPROPER G-CODE) and stop the program at that block, like the machine.PS0001 invalid character, PS0003 too many digits, PS0004/PS0005 address, PS0006 sign, PS0007 decimal point, PS0009 axis not on the machine, PS0010 undefined G code.PS0011 no feed, PS0020–PS0023 arcs, PS0030 offset number.PS0033/PS0034/PS0037/PS0041 G41/G42 (start on an arc, plane change, blocks without movement, interference).PS0045 G83 without Q, PS0061/PS0063 G70–G73.PS0074–PS0078.PS0110–PS0129 and PS0199 (division by zero, variables, brackets, DO/END, GOTO, G65), plus #3000 → PS3000+n.,C ,R): PS0051 no move after, PS0052 next block not G01/G02/G03, PS0053 both in one block, PS0054 taper after a corner without comma, PS0055 corner larger than a move. These five numbers are from the 0i alarm list and still to be confirmed in the maintenance manual.PS0061 P/Q missing, PS0062 depth or passes missing, PS0063 sequence number not found, PS0064 shape not monotonic in Z (G71 type I), PS0065 no G00/G01 in the first shape block. PS0062, PS0064 and PS0065 are still to be confirmed in the maintenance manual.File format and limits are part of the control, like its parameters:
"fileFormat": { "startPercent": true, "endPercent": true, "eob": "semicolon", "missingEob": "alarm",
"programNumber": "required", "requireDecimalPoint": false },
"limits": { "maxDigits": 8, "maxValue": 99999.999, "subprogramNesting": 4, "bracketNesting": 5,
"loopIds": 3, "maxProgramNumber": 9999, "compNoMoveBlocks": 1, "arcTolerance": 0.02, "toolOffsets": 64 }
% at the start and end, the ; end of block, and the program number are checked when the file is loaded. They are reported, and the program still runs.% without M30/M02/M99 raises the end-of-record alarm.Tools and holders: inspired by the CAMotics tool table. Holders (BT40, HSK63A, VDI, BMT…) carry a revolution profile [radius, length] for the 3D drawing.
src/core.
.cncsim projects, installers, updates, bug reports. Next: auto-reload when the .nc changes, file associations./api/simulate API and use from a browser on the shop network..cps; tool and holder collision with part, chuck and turret.Copyright (C) 2026 Ismael Figueiredo
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE.
The control and machine manuals cited here belong to their makers and are not covered by this license.
,C and ,R at any angle, with the tangent arc followed by cutter compensation, and the control's alarms when they cannot be made. Lathes can also take C/R without comma (control option cornerWithoutComma)..cncsim): keep the program with its machine, control, tools, stock and work offsets, to reopen or send the whole job.tailstock in the machine file show a live center, quill and casting opposite the chuck. On the Romi GL, M27 brings it against the part and M26/M31 back it off (manual, section 11.3.4); facing to the axis or backing off along it while the center is there is listed as a collision. Hiding it is only visual: it still moves and its collisions are still listed.IFL n P mM17MCALLCYCLE81CYCLE83CYCLE95TRANSROTMIRRORCIPPS0145/PS0146 G12.1.PS5010 end of record, PS5073 decimal point.P32–P39 format, P62 feed, P70/P113 arcs, P112/P151–P157 cutter compensation, P170 offset number, P230–P232 subprograms, P241/P243 variables, P481/P485 polar interpolation.
P36, P277 (#3000 message) and the macro family P280–P294 come from Mitsubishi's standard list and should be confirmed in the alarm manual.