PCB EMI and EMC analysis on your own computer. Open a KiCad board or a zip of Gerber files and see what to fix, marked on the board, in seconds.
| Layout checks | 23 checks: return paths, plane gaps and stitching, decoupling, impedance, length matching, differential pair routing, test point stubs, copper under antennas, thin power traces, ESD protection at connectors, shield grounding, reset lines, power input and switching-regulator layout. Each finding says what to do. |
| Decoupling | Per supply rail and IC: the impedance of its capacitors against a target, where it falls short, and which change closes the gap. |
| ESD | An IEC 61000-4-2 contact discharge into each line that leaves the board, simulated in ngspice, with the clamp where it is and moved to the connector. |
| Cables | How much common-mode current each connector's cable can carry before it passes the FCC limit, from an antenna model in nec2c. |
| Part solve | One net (or a pair) cut out over its planes and solved in openEMS in minutes: where its current flows and what its ends see. No far field, no compliance estimate, no coupling into neighboring nets, and no component models (those need full-wave and the openEMS the worker image ships). See verification. |
| Versions | Upload a changed layout as a new version and see which findings were fixed and which are new. |
| Settings | Turn checks on or off and set thresholds per board in the app, or in an emi.rules.yaml next to the board. |
| Reports | One HTML file (or PDF) with the board, findings and results, to share. |
Your boards and results stay on your computer. Nothing is uploaded anywhere.
Results are for comparing versions of your own board. They are not a pre-compliance test. See known issues.
Full-wave simulation of a whole region (openEMS) and conducted emissions are built but off. See experimental features.
- What you need
- Step 1: Install Docker
- Step 2: Install EMI Analyzer
- Step 3: First launch
- Step 4: Analyze a board
- Using it from KiCad
- Running without the desktop app
- Running in the background
- Where your data is
- Updating and uninstalling
- Troubleshooting
- Experimental features
- More documentation
| Operating system | macOS 11 or newer (Apple Silicon or Intel), Windows 10 or 11 (64-bit), or 64-bit Linux on x86-64 |
| Memory | 8 GB or more |
| Disk | About 4 GB free: 1.4 GB for the worker image, the rest for Docker and your results |
| Docker | Docker Desktop on macOS and Windows; Docker Engine or Docker Desktop on Linux |
| Internet | Only to download the app and, once per version, the worker image |
EMI Analyzer has two parts. The app is a small download that shows your boards and results. The worker does the analysis. It runs inside Docker, so it behaves the same on every operating system, and the app starts and stops it for you.
Skip this step if docker ps already works in a terminal.
With Homebrew, one command:
brew install --cask docker-desktopThen continue at step 3. Without Homebrew:
-
Download Docker Desktop for Mac from https://docs.docker.com/desktop/setup/install/mac-install/. Choose Apple Silicon or Intel to match your Mac (Apple menu → About This Mac → Chip or Processor).
-
Open the downloaded
Docker.dmgand drag Docker into Applications. -
Open Docker from Applications. Accept the service agreement and, when asked, allow the helper with your password.
-
Wait until the Docker whale in the menu bar stops animating.
-
Check it in Terminal:
docker ps
A header line with nothing under it means Docker is ready.
OrbStack works too, instead of Docker Desktop.
-
Open Terminal as Administrator (right-click the Start button → Terminal (Admin)) and install the Windows Subsystem for Linux:
wsl --installRestart the computer when it finishes.
-
Download Docker Desktop for Windows from https://docs.docker.com/desktop/setup/install/windows-install/ and run the installer. Keep Use WSL 2 instead of Hyper-V selected.
-
Sign out and back in if the installer asks, then start Docker Desktop from the Start menu and accept the service agreement.
-
Wait until Docker Desktop shows Engine running.
-
Check it in a new terminal:
docker ps
A header line with nothing under it means Docker is ready.
-
Install Docker Engine by following https://docs.docker.com/engine/install/ubuntu/, or the page for your distribution. On Ubuntu, Docker's install script does it in one step:
curl -fsSL https://get.docker.com | sh -
Let your user run Docker without
sudo, which the app needs:sudo usermod -aG docker $USER -
Log out and log back in (or restart) so the change takes effect.
-
Check it:
docker ps
A header line with nothing under it means Docker is ready. Permission denied means you have not logged out and back in since step 2.
On a Mac, use Homebrew. One command installs the app and gets it past macOS's check for apps that are not code-signed:
brew install --cask embeddedci-com/tap/emi-analyzerThen open EMI Analyzer from Applications. Update it later with
brew upgrade --cask embeddedci-com/tap/emi-analyzer. No Homebrew? Install it from https://brew.sh, or use the
.dmg below.
For other computers, or a Mac without Homebrew, go to the latest release and download the file for your computer:
| Computer | Download |
|---|---|
| Mac with Apple Silicon (M1, M2, M3, …) | EMI.Analyzer_<version>_aarch64.dmg |
| Mac with an Intel processor | EMI.Analyzer_<version>_x64.dmg |
| Windows | EMI.Analyzer_<version>_x64-setup.exe (or the .msi) |
| Ubuntu / Debian | EMI.Analyzer_<version>_amd64.deb |
| Fedora / RHEL | EMI.Analyzer-<version>-1.x86_64.rpm |
| Other Linux | EMI.Analyzer_<version>_amd64.AppImage |
The installers are not code-signed yet, so your operating system warns you the first time you open the app. That is expected; here is how to get past it.
Skip this if you installed with Homebrew.
-
Open the downloaded
.dmgand drag EMI Analyzer into Applications. -
Open EMI Analyzer from Applications. macOS says it cannot verify the developer: click Done, not Move to Trash.
-
Open System Settings → Privacy & Security, scroll to the message about EMI Analyzer, click Open Anyway, and confirm with your password.
-
If macOS instead says the app "is damaged and can't be opened", that is the same check worded differently. Remove the download quarantine in Terminal and open the app again:
xattr -dr com.apple.quarantine "/Applications/EMI Analyzer.app"
- Run the downloaded
-setup.exe. - Windows SmartScreen shows "Windows protected your PC". Click More info, then Run anyway.
- Follow the installer. It installs Microsoft WebView2 if your computer does not have it yet.
- Start EMI Analyzer from the Start menu.
sudo apt install ./EMI.Analyzer_*_amd64.debStart EMI Analyzer from your applications menu.
sudo dnf install ./EMI.Analyzer-*-1.x86_64.rpmStart EMI Analyzer from your applications menu.
AppImages need FUSE. On Ubuntu 24.04 install it with sudo apt install libfuse2t64, on older
releases with sudo apt install libfuse2. Then make the file executable and run it:
chmod +x EMI.Analyzer_*_amd64.AppImage./EMI.Analyzer_*_amd64.AppImage- Make sure Docker is running (Step 1).
- Open EMI Analyzer. A window opens on the analyzer's home page.
- Watch the badge in the top-right corner. On the first launch it says
Downloading worker while Docker pulls
ghcr.io/embeddedci-com/emi-worker:<version>, about 330 MB to download and 1.4 GB on disk. That takes a few minutes and happens once per app version. - When the badge turns green and says Worker running, the app is ready.
Click the badge at any time to see the worker's log or restart it.
The worker container starts when you open the app and is removed when you close it. Nothing keeps running in the background.
-
On the home page, drop a board file on the upload area, or click Choose a file, and pick one of:
- a
.kicad_pcbfile; - a zipped KiCad project;
- a zip of Gerber files including the drill file and an IPC-D-356 netlist — Gerbers carry no net names on their own.
No board to hand? Click Try the sample board.
- a
-
The board appears within a few seconds, with each finding marked and numbered on it and the Findings tab on the right. Click a marker to open its finding, or a finding to zoom to it.
-
Look at the other tabs:
- ESD — simulate a discharge into a connector's lines, and compare the voltage at the IC pin with the clamp where it is against the clamp moved to the connector.
- Cables — the board's connectors, each with a suggested cable. Click Get budgets to see each cable's common-mode budget.
- Board — stackup, nets and layer settings.
-
Opening the same file again takes you to the existing project instead of creating a new one.
-
Changed the layout? In the ⋯ menu, click Upload a new version and pick the changed file. It becomes version 2 of the same board, and a version picker appears in the header.
-
Click Compare in the header to see two versions side by side: which findings were fixed and which are new, which nets changed length or via count, and, when both versions have run them, the cable budgets and the ESD peak at each pin. A version without a cable or ESD run offers to run it with the other version's settings.
-
The header also has Runs, which lists what has been analysed and lets you retry anything that failed, and the ⋯ menu can rename the board, delete one version, or delete the board with every version. Deleting removes the files and results from this computer.
-
To share results, see Sharing results.
Click Export report in the board header. Pick the sections (all that are available are on) and the format, check the preview, and download.
- HTML report: one file with everything inline, for your team or a test lab. It has a title page (board, version, date, app and worker versions, file hash, stackup, the rules file and settings used, which experimental features were on), the board with numbered finding markers, the findings by severity and rule, the analysis notes, and, when they have been run, the cable budgets and ESD results with their charts and a "changes since version N" section. It loads nothing from the network. To get a PDF, open it in a browser and print it, or click Print or save as PDF in the dialog.
- JSON data: the same content, for scripts and CI.
A cable or ESD run that has not been done on this version is listed in the dialog with a Run now button, and named in the report as not included. Every report says, on its first page and on each printed page, that it compares versions of your own board and is not a pre-compliance test.
There is a KiCad plugin that puts all of this beside the PCB Editor: it hands the app the board you have open, unsaved edits and all, and clicking a finding selects that net on the board.
Install the app first (the plugin is only a front end for it), then in KiCad open Plugin and Content Manager → Manage repositories and add
https://raw.githubusercontent.com/embeddedci-com/kicad-plugins/main/repository.json
then install EMI Analyzer from it. Details and troubleshooting: kicad-plugin/README.md.
The app does not have to be on screen. Press Minimize to menu bar in its header (Minimize to tray on Windows and Linux), or close its window, and it carries on serving the plugin with your boards, results and worker untouched. Open it again, or quit it, from that icon's menu. The plugin also starts the app by itself when it is not running.
The desktop app is a window around one program, emi-local, which also runs on its own and opens
the analyzer in your browser. Use it on a Linux machine without a desktop, or if you prefer a
browser tab. You still need Docker (Step 1).
-
Download
emi-local-<version>-<os>-<arch>from the latest release. -
On macOS and Linux, make it executable:
chmod +x emi-local-*On macOS, also remove the download quarantine, for the same reason as the app:
xattr -d com.apple.quarantine emi-local-* -
Run it (the file name depends on what you downloaded):
./emi-local-0.1.0-linux-amd64
It prints its address and opens it in your browser:
http://127.0.0.1:7465, or the next free port if that one is taken. Stop it with Ctrl+C, which also removes the worker container.
It only listens on this computer. To use it from another machine, forward the port over SSH instead of exposing it, because the app has no sign-in:
ssh -L 7465:127.0.0.1:7465 your-server| Flag | Default | |
|---|---|---|
-data-dir |
see below | where boards, results and the database are kept |
-open=false |
opens | do not open a browser tab |
-addr |
127.0.0.1:7465 |
listen address; loopback addresses only |
-worker none |
docker |
do not start a worker; run your own |
-worker-image |
ghcr.io/embeddedci-com/emi-worker:<version> |
run a different worker image (:dev for a build from source) |
-worker-concurrency |
1 |
how many runs the worker takes at once |
-experimental |
none | enable experimental features |
-endpoint-file |
in your config folder | where it says it is listening, so the KiCad plugin can find it; empty writes none |
-issue-key |
print a key for a worker you run yourself, and exit | |
-version |
print the version and exit |
emi-local serves the KiCad plugin as well as the app does. Leave
emi-local -open=false running and the plugin finds it.
EMI Analyzer keeps working with its window put away: closing the window does not quit it, and neither does Minimize to menu bar in the header, which reads Minimize to tray on Windows and Linux. The server, your boards and the Docker worker all stay up, which is what the KiCad plugin needs when the PCB Editor is the front end.
Its icon stays in the menu bar on macOS, the notification area on Windows and the system tray on Linux. That menu has Open EMI Analyzer and Quit. Quit is the only thing that stops the worker container.
| Desktop app | emi-local on its own |
|
|---|---|---|
| macOS | ~/Library/Application Support/com.embeddedci.emi-analyzer |
~/Library/Application Support/emi-analyzer |
| Windows | %APPDATA%\com.embeddedci.emi-analyzer |
%APPDATA%\emi-analyzer |
| Linux | ~/.local/share/com.embeddedci.emi-analyzer |
~/.config/emi-analyzer |
The folder holds emi.db (projects, runs and components, in SQLite), blobs/ (your board files
and results) and secret.key (signs this installation's download links and worker keys). Back up
the folder to keep your projects; delete it to start over. To remove one board and its results,
use ⋯ → Delete this board in the app.
Update: download and install the newer release over the old one. Your data folder is kept. The new version downloads its own worker image on first launch. To reclaim disk, list the old images and remove the ones you no longer need:
docker image ls ghcr.io/embeddedci-com/emi-workerdocker image rm ghcr.io/embeddedci-com/emi-worker:<old-version>Uninstall:
-
Remove the app:
brew uninstall --cask embeddedci-com/tap/emi-analyzeror drag it from Applications to the Bin (macOS), use Settings → Apps (Windows), runsudo apt remove emi-analyzer(.deb), or delete the AppImage. -
Delete the data folder listed above.
-
Remove the worker images:
docker image rm $(docker image ls -q ghcr.io/embeddedci-com/emi-worker)
| What you see | What to do |
|---|---|
| Docker not installed, but it is | The app looks on your PATH and in the usual install locations. Start the app from a terminal where docker ps works, or use emi-local. |
| Docker not running | Start Docker Desktop, or run sudo systemctl start docker on Linux. The worker starts by itself a few seconds later. |
| Downloading worker never finishes | Check your connection and free disk space, then click the badge → Restart worker. Behind a proxy, set it in Docker Desktop → Settings → Resources → Proxies. |
| Worker stopped | Click the badge and read the log. On Linux, check that docker ps works without sudo (Step 1). |
| Worker running, but a board never finishes processing | The worker cannot reach the app. With an unusual Docker setup, run emi-local -worker-url http://<address>:7465, where the address is how containers reach your computer. |
| "Interrupted: the app was closed" on a run | Runs do not survive closing the app. Retry the run. |
| macOS: "EMI Analyzer is damaged" | See Step 2 → macOS → item 4. |
| The Linux AppImage does nothing | Install FUSE (Step 2), or use the .deb. |
Found a bug? Open an issue at https://github.com/embeddedci-com/emi-analyzer/issues and include the worker log from the badge.
Some features are built but not yet reliable, and are switched off. Off means the app refuses to run them, not just that the buttons are hidden.
| Name | What it enables | Why it is off |
|---|---|---|
full-wave |
openEMS full-wave simulation of a board region, hotspot maps, the far field, cable emissions and the compliance estimate — the Solve, Drivers, Components, Results and Compliance tabs | It runs, and a test board solves end to end. What has not been done is verifying any of it on a real board, or at the record length a radiated result needs. Treat anything it produces as unchecked. See known issues. |
conducted |
A conducted-emissions scan of the power input with ngspice, on the Conducted tab: two LISNs, the input filter as laid out and each buck regulator as a current source, against FCC 15.107. Differential mode only | The LISN, a buck's input ripple and an LC filter match closed forms, but no board has been compared with a measurement, and regulator settings are assumed until you enter them. See verification. |
To try one anyway, set EMI_EXPERIMENTAL to its name where the app is started (a
comma-separated list for more than one). For full-wave:
-
emi-local:./emi-local -experimental full-wave
-
Desktop app on macOS:
EMI_EXPERIMENTAL=full-wave "/Applications/EMI Analyzer.app/Contents/MacOS/emi-analyzer" -
Desktop app on Windows: add a user environment variable
EMI_EXPERIMENTALwith the valuefull-wave(Start → Edit environment variables for your account), then start the app. -
Desktop app on Linux:
EMI_EXPERIMENTAL=full-wave emi-analyzer.
Full-wave simulation needs a lot of memory and CPU. On macOS and Windows, give Docker as much memory as you can spare under Docker Desktop → Settings → Resources.
| docs/known-issues.md | What is verified, what is experimental, what is not built yet |
| docs/running-a-worker.md | Running the worker yourself: on another machine, or from source |
| docs/rules-file.md | Tuning the checks for a board with a rules file |
| docs/emi-driver-format.md | The driver file format |
| docs/ | Everything else: how the model works, and design notes |
| kicad-plugin/README.md | The KiCad plugin: installing it, using it, and how it works |
| CONTRIBUTING.md | Building from source, tests, and releasing |
The app has no sign-in, so it protects itself by where it listens and who may call it. It binds
only to loopback addresses; answers only requests addressed to localhost or 127.0.0.1, which
stops web pages reaching it through DNS rebinding; refuses changes requested by any other origin,
including other ports on this computer, and changes not sent as JSON; cannot be framed by other
sites; serves files only on links signed with a per-installation secret that expire after 15
minutes; and gives the worker a key that is revoked when the app stops. To report a vulnerability, see SECURITY.md.
Apache License 2.0. The worker image also contains third-party programs under their own licences, notably openEMS (GPL-3.0), nec2c (GPL-2.0) and ngspice (BSD), which it runs as separate programs. worker/NOTICE lists them and says where their source code is.